Revision: 9741
Author:   u...@chromium.org
Date:     Fri Oct 21 04:42:54 2011
Log:      Handlify KeyedIC::ComputeStub.

BUG=
TEST=

Review URL: http://codereview.chromium.org/8356041
http://code.google.com/p/v8/source/detail?r=9741

Modified:
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/ic.h
 /branches/bleeding_edge/src/list-inl.h
 /branches/bleeding_edge/src/list.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/stub-cache.cc
 /branches/bleeding_edge/src/stub-cache.h

=======================================
--- /branches/bleeding_edge/src/ic.cc   Thu Oct 20 10:08:53 2011
+++ /branches/bleeding_edge/src/ic.cc   Fri Oct 21 04:42:54 2011
@@ -971,36 +971,30 @@
 }


-MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
+Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck(
     bool is_js_array,
     ElementsKind elements_kind) {
-  return KeyedLoadElementStub(elements_kind).TryGetCode();
+  return KeyedLoadElementStub(elements_kind).GetCode();
 }


-MaybeObject* KeyedLoadIC::ComputePolymorphicStub(
-    MapList* receiver_maps,
+Handle<Code> KeyedLoadIC::ComputePolymorphicStub(
+    MapHandleList* receiver_maps,
     StrictModeFlag strict_mode) {
-  CodeList handler_ics(receiver_maps->length());
+  CodeHandleList handler_ics(receiver_maps->length());
   for (int i = 0; i < receiver_maps->length(); ++i) {
-    Map* receiver_map(receiver_maps->at(i));
-    MaybeObject* maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
+    Handle<Map> receiver_map = receiver_maps->at(i);
+    Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck(
         receiver_map, strict_mode);
-    Code* cached_stub;
-    if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
     handler_ics.Add(cached_stub);
   }
-  Object* object;
-  HandleScope scope(isolate());
   KeyedLoadStubCompiler compiler(isolate());
-  MaybeObject* maybe_code = compiler.CompileLoadPolymorphic(receiver_maps,
-                                                            &handler_ics);
-  if (!maybe_code->ToObject(&object)) return maybe_code;
+  Handle<Code> code = compiler.CompileLoadPolymorphic(
+      receiver_maps, &handler_ics);
   isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
-  PROFILE(isolate(), CodeCreateEvent(
-      Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG,
-      Code::cast(object), 0));
-  return object;
+  PROFILE(isolate(),
+ CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0));
+  return code;
 }


@@ -1034,8 +1028,7 @@
           name->Equals(isolate()->heap()->length_symbol())) {
         Handle<String> string = Handle<String>::cast(object);
         Handle<Code> code =
-            isolate()->stub_cache()->ComputeKeyedLoadStringLength(name,
-                                                                  string);
+ isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string);
         ASSERT(!code.is_null());
         set_target(*code);
         TRACE_IC("KeyedLoadIC", name, state, target());
@@ -1420,10 +1413,12 @@
 }


-static bool AddOneReceiverMapIfMissing(MapList* receiver_maps,
-                                       Map* new_receiver_map) {
+static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
+                                       Handle<Map> new_receiver_map) {
+  ASSERT(!new_receiver_map.is_null());
   for (int current = 0; current < receiver_maps->length(); ++current) {
-    if (receiver_maps->at(current) == new_receiver_map) {
+    if (!receiver_maps->at(current).is_null() &&
+        receiver_maps->at(current).is_identical_to(new_receiver_map)) {
       return false;
     }
   }
@@ -1432,22 +1427,23 @@
 }


-void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) {
+void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
+                                     MapHandleList* result) {
   ASSERT(stub->is_inline_cache_stub());
-  if (!string_stub().is_null() && stub == *string_stub()) {
-    return result->Add(isolate()->heap()->string_map());
+  if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
+    return result->Add(isolate()->factory()->string_map());
   } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
     if (stub->ic_state() == MONOMORPHIC) {
-      result->Add(Map::cast(stub->FindFirstMap()));
+      result->Add(Handle<Map>(stub->FindFirstMap()));
     } else {
       ASSERT(stub->ic_state() == MEGAMORPHIC);
       AssertNoAllocation no_allocation;
       int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
-      for (RelocIterator it(stub, mask); !it.done(); it.next()) {
+      for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
         RelocInfo* info = it.rinfo();
-        Object* object = info->target_object();
+        Handle<Object> object(info->target_object());
         ASSERT(object->IsMap());
-        AddOneReceiverMapIfMissing(result, Map::cast(object));
+        AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
       }
     }
   }
@@ -1458,33 +1454,13 @@
                                   StubKind stub_kind,
                                   StrictModeFlag strict_mode,
                                   Handle<Code> generic_stub) {
-  CALL_HEAP_FUNCTION(isolate(),
-                     ComputeStub(*receiver,
-                                 stub_kind,
-                                 strict_mode,
-                                 *generic_stub),
-                     Code);
-}
-
-
-
-MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
-                                  StubKind stub_kind,
-                                  StrictModeFlag strict_mode,
-                                  Code* generic_stub) {
   State ic_state = target()->ic_state();
   if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) &&
       !IsTransitionStubKind(stub_kind)) {
-    Code* monomorphic_stub;
-    MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver,
-                                                     stub_kind,
-                                                     strict_mode,
-                                                     generic_stub);
-    if (!maybe_stub->To(&monomorphic_stub)) return maybe_stub;
-
-    return monomorphic_stub;
-  }
-  ASSERT(target() != generic_stub);
+    return ComputeMonomorphicStub(
+        receiver, stub_kind, strict_mode, generic_stub);
+  }
+  ASSERT(target() != *generic_stub);

// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS // via megamorphic stubs, since they don't have a map in their relocation info
@@ -1495,18 +1471,17 @@

   // Determine the list of receiver maps that this call site has seen,
   // adding the map that was just encountered.
-  MapList target_receiver_maps;
+  MapHandleList target_receiver_maps;
+  Handle<Map> receiver_map(receiver->map());
   if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
-    target_receiver_maps.Add(receiver->map());
+    target_receiver_maps.Add(receiver_map);
   } else {
-    GetReceiverMapsForStub(target(), &target_receiver_maps);
+    GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
   }
   bool map_added =
-      AddOneReceiverMapIfMissing(&target_receiver_maps, receiver->map());
+      AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
   if (IsTransitionStubKind(stub_kind)) {
-    MaybeObject* maybe_map = ComputeTransitionedMap(receiver, stub_kind);
-    Map* new_map = NULL;
-    if (!maybe_map->To(&new_map)) return maybe_map;
+    Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
   }
   if (!map_added) {
@@ -1521,32 +1496,25 @@
     return generic_stub;
   }

- PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
-  Code::Flags flags = Code::ComputeFlags(this->kind(),
-                                         MEGAMORPHIC,
-                                         strict_mode);
-  Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
-  // If there is a cached stub, use it.
-  if (!maybe_cached_stub->IsUndefined()) {
-    ASSERT(maybe_cached_stub->IsCode());
-    return Code::cast(maybe_cached_stub);
-  }
-  MaybeObject* maybe_stub =
+  Handle<PolymorphicCodeCache> cache =
+      isolate()->factory()->polymorphic_code_cache();
+  Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode);
+  Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
+  if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+  Handle<Code> stub =
       ComputePolymorphicStub(&target_receiver_maps, strict_mode);
-  Code* stub;
-  if (!maybe_stub->To(&stub)) return maybe_stub;
- MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub);
-  if (maybe_update->IsFailure()) return maybe_update;
+  PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub);
   return stub;
 }


-MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
-    Map* receiver_map,
+Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
+    Handle<Map> receiver_map,
     StrictModeFlag strict_mode) {
   if ((receiver_map->instance_type() & kNotStringTag) == 0) {
     ASSERT(!string_stub().is_null());
-    return *string_stub();
+    return string_stub();
   } else {
     ASSERT(receiver_map->has_dictionary_elements() ||
            receiver_map->has_fast_elements() ||
@@ -1560,85 +1528,78 @@
 }


-MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver,
+Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver,
                                              StubKind stub_kind,
                                              StrictModeFlag strict_mode,
-                                             Code* generic_stub) {
-  Code* result = NULL;
+                                             Handle<Code> generic_stub) {
   if (receiver->HasFastElements() ||
       receiver->HasFastSmiOnlyElements() ||
       receiver->HasExternalArrayElements() ||
       receiver->HasFastDoubleElements() ||
       receiver->HasDictionaryElements()) {
-    MaybeObject* maybe_stub =
-        isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
-            receiver, stub_kind, strict_mode);
-    if (!maybe_stub->To(&result)) return maybe_stub;
+    return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
+        receiver, stub_kind, strict_mode);
   } else {
-    result = generic_stub;
-  }
-  return result;
+    return generic_stub;
+  }
 }


-MaybeObject* KeyedIC::ComputeTransitionedMap(JSObject* receiver,
-                                             StubKind stub_kind) {
+Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
+                                            StubKind stub_kind) {
   switch (stub_kind) {
     case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT:
     case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT:
-      return receiver->GetElementsTransitionMap(FAST_ELEMENTS);
+      return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
+      break;
     case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE:
-      return receiver->GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
+ return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
+      break;
     default:
       UNREACHABLE();
-      return NULL;
+      return Handle<Map>::null();
   }
 }


-MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck(
+Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck(
     bool is_js_array,
     ElementsKind elements_kind) {
-  return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
+  return KeyedStoreElementStub(is_js_array, elements_kind).GetCode();
 }


-MaybeObject* KeyedStoreIC::ComputePolymorphicStub(
-    MapList* receiver_maps,
-    StrictModeFlag strict_mode) {
+Handle<Code> KeyedStoreIC::ComputePolymorphicStub(MapHandleList* receiver_maps, + StrictModeFlag strict_mode) {
   // Collect MONOMORPHIC stubs for all target_receiver_maps.
-  CodeList handler_ics(receiver_maps->length());
-  MapList transitioned_maps(receiver_maps->length());
+  CodeHandleList handler_ics(receiver_maps->length());
+  MapHandleList transitioned_maps(receiver_maps->length());
   for (int i = 0; i < receiver_maps->length(); ++i) {
-    Map* receiver_map(receiver_maps->at(i));
-    MaybeObject* maybe_cached_stub = NULL;
- Map* transitioned_map = receiver_map->FindTransitionedMap(receiver_maps);
-    if (transitioned_map != NULL) {
-      maybe_cached_stub = ElementsTransitionAndStoreStub(
+    Handle<Map> receiver_map(receiver_maps->at(i));
+    Handle<Code> cached_stub;
+    Handle<Map> transitioned_map =
+        receiver_map->FindTransitionedMap(receiver_maps);
+    if (!transitioned_map.is_null()) {
+      cached_stub = ElementsTransitionAndStoreStub(
           receiver_map->elements_kind(),  // original elements_kind
           transitioned_map->elements_kind(),
           receiver_map->instance_type() == JS_ARRAY_TYPE,  // is_js_array
-          strict_mode).TryGetCode();
+          strict_mode).GetCode();
     } else {
-      maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
-          receiver_map, strict_mode);
-    }
-    Code* cached_stub;
-    if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
+      cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map,
+                                                          strict_mode);
+    }
+    ASSERT(!cached_stub.is_null());
     handler_ics.Add(cached_stub);
     transitioned_maps.Add(transitioned_map);
   }
-  Object* object;
-  HandleScope scope(isolate());
   KeyedStoreStubCompiler compiler(isolate(), strict_mode);
-  MaybeObject* maybe_code = compiler.CompileStorePolymorphic(
+  Handle<Code> code = compiler.CompileStorePolymorphic(
       receiver_maps, &handler_ics, &transitioned_maps);
-  if (!maybe_code->ToObject(&object)) return maybe_code;
   isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
-  PROFILE(isolate(), CodeCreateEvent(
-      Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG,
-      Code::cast(object), 0));
-  return object;
+  PROFILE(isolate(),
+ CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
+  return code;
 }


=======================================
--- /branches/bleeding_edge/src/ic.h    Fri Oct 21 03:19:16 2011
+++ /branches/bleeding_edge/src/ic.h    Fri Oct 21 04:42:54 2011
@@ -365,7 +365,7 @@
   explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
   virtual ~KeyedIC() {}

-  virtual MaybeObject* GetElementStubWithoutMapCheck(
+  virtual Handle<Code> GetElementStubWithoutMapCheck(
       bool is_js_array,
       ElementsKind elements_kind) = 0;

@@ -381,27 +381,23 @@
                            StrictModeFlag strict_mode,
                            Handle<Code> default_stub);

-  MaybeObject* ComputeStub(JSObject* receiver,
-                           StubKind stub_kind,
-                           StrictModeFlag strict_mode,
-                           Code* default_stub);
-
-  virtual MaybeObject* ComputePolymorphicStub(MapList* receiver_maps,
+  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
StrictModeFlag strict_mode) = 0;

-  MaybeObject* ComputeMonomorphicStubWithoutMapCheck(
-      Map* receiver_map,
+  Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
+      Handle<Map> receiver_map,
       StrictModeFlag strict_mode);

  private:
-  void GetReceiverMapsForStub(Code* stub, MapList* result);
-
-  MaybeObject* ComputeMonomorphicStub(JSObject* receiver,
+  void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
+
+  Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver,
                                       StubKind stub_kind,
                                       StrictModeFlag strict_mode,
-                                      Code* default_stub);
-
- MaybeObject* ComputeTransitionedMap(JSObject* receiver, StubKind stub_kind);
+                                      Handle<Code> default_stub);
+
+  Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
+                                     StubKind stub_kind);

   static bool IsTransitionStubKind(StubKind stub_kind) {
     return stub_kind > STORE_NO_TRANSITION;
@@ -441,16 +437,15 @@
   static const int kSlowCaseBitFieldMask =
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);

-  virtual MaybeObject* GetElementStubWithoutMapCheck(
+  virtual Handle<Code> GetElementStubWithoutMapCheck(
       bool is_js_array,
       ElementsKind elements_kind);

  protected:
   virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }

-  virtual MaybeObject* ComputePolymorphicStub(
-      MapList* receiver_maps,
-      StrictModeFlag strict_mode);
+  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
+                                              StrictModeFlag strict_mode);

   virtual Handle<Code> string_stub() {
     return isolate()->builtins()->KeyedLoadIC_String();
@@ -585,16 +580,15 @@
   static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);

-  virtual MaybeObject* GetElementStubWithoutMapCheck(
+  virtual Handle<Code> GetElementStubWithoutMapCheck(
       bool is_js_array,
       ElementsKind elements_kind);

  protected:
   virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }

-  virtual MaybeObject* ComputePolymorphicStub(
-      MapList* receiver_maps,
-      StrictModeFlag strict_mode);
+  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
+                                              StrictModeFlag strict_mode);

   private:
   // Update the inline cache.
=======================================
--- /branches/bleeding_edge/src/list-inl.h      Tue Oct 18 06:40:33 2011
+++ /branches/bleeding_edge/src/list-inl.h      Fri Oct 21 04:42:54 2011
@@ -235,6 +235,19 @@
 int SortedListBSearch(const List<T>& list, T elem) {
   return SortedListBSearch<T>(list, elem, PointerValueCompare<T>);
 }
+
+
+template <class T>
+List<T*>* UnwrapHandleList(List<T*>* destination, List<Handle<T> >* source) {
+  ASSERT(destination->is_empty());
+  int length = source->length();
+  for (int i = 0; i < length; ++i) {
+    Handle<T> handle = source->at(i);
+    destination->Add(handle.is_null() ? NULL : *handle);
+  }
+  return destination;
+}
+

 } }  // namespace v8::internal

=======================================
--- /branches/bleeding_edge/src/list.h  Tue Sep 13 01:31:21 2011
+++ /branches/bleeding_edge/src/list.h  Fri Oct 21 04:42:54 2011
@@ -165,8 +165,11 @@

 class Map;
 class Code;
+template<typename T> class Handle;
 typedef List<Map*> MapList;
 typedef List<Code*> CodeList;
+typedef List<Handle<Map> > MapHandleList;
+typedef List<Handle<Code> > CodeHandleList;

 // Perform binary search for an element in an already sorted
 // list. Returns the index of the element of -1 if it was not found.
@@ -176,6 +179,15 @@
 template <typename T>
 int SortedListBSearch(const List<T>& list, T elem);

+// Unwraps each handle in the source list to a pointer at
+// the corresponding position in the destination list.
+// Returns the destination list.
+// Both list must have the same length.
+
+template <class T>
+List<T*>* UnwrapHandleList(List<T*>* destination, List<Handle<T> >* source);
+
+
 } }  // namespace v8::internal


=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Oct 21 03:37:56 2011
+++ /branches/bleeding_edge/src/objects.cc      Fri Oct 21 04:42:54 2011
@@ -2188,6 +2188,14 @@
   }
   return false;
 }
+
+
+Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
+  MapList raw_candidates(candidates->length());
+  Map* result = FindTransitionedMap(UnwrapHandleList(&raw_candidates,
+                                                     candidates));
+  return (result == NULL) ? Handle<Map>::null() : Handle<Map>(result);
+}


 Map* Map::FindTransitionedMap(MapList* candidates) {
@@ -2395,6 +2403,15 @@
   set_instance_descriptors(DescriptorArray::cast(new_descriptors));
   return this;
 }
+
+
+Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
+                                               ElementsKind to_kind) {
+  Isolate* isolate = object->GetIsolate();
+  CALL_HEAP_FUNCTION(isolate,
+                     object->GetElementsTransitionMap(to_kind),
+                     Map);
+}


 MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind to_kind) {
@@ -5122,6 +5139,19 @@
   set(EntryToIndex(index) + 1, heap->null_value());
   ElementRemoved();
 }
+
+
+void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache,
+                                  MapHandleList* maps,
+                                  Code::Flags flags,
+                                  Handle<Code> code) {
+  Isolate* isolate = cache->GetIsolate();
+  List<Map*> raw_maps(maps->length());
+  CALL_HEAP_FUNCTION_VOID(
+      isolate,
+      (raw_maps.Clear(),
+       cache->Update(UnwrapHandleList(&raw_maps, maps), flags, *code)));
+}


 MaybeObject* PolymorphicCodeCache::Update(MapList* maps,
@@ -5150,6 +5180,13 @@
   set_cache(new_cache);
   return this;
 }
+
+
+Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps,
+                                            Code::Flags flags) {
+  List<Map*> raw_maps(maps->length());
+  return Handle<Object>(Lookup(UnwrapHandleList(&raw_maps, maps), flags));
+}


 Object* PolymorphicCodeCache::Lookup(MapList* maps, Code::Flags flags) {
=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Oct 21 03:32:38 2011
+++ /branches/bleeding_edge/src/objects.h       Fri Oct 21 04:42:54 2011
@@ -1800,6 +1800,8 @@

// Returns a new map with all transitions dropped from the object's current
   // map and the ElementsKind set.
+  static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
+                                              ElementsKind to_kind);
   MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
       ElementsKind elements_kind);

@@ -4355,10 +4357,12 @@
                                      Map* transitioned_map);

   // Returns the transitioned map for this map with the most generic
-  // elements_kind that's found in |candidates|, or NULL if no match is
+ // elements_kind that's found in |candidates|, or null handle if no match is
   // found at all.
+  Handle<Map> FindTransitionedMap(MapHandleList* candidates);
   Map* FindTransitionedMap(MapList* candidates);

+
   // Dispatched behavior.
 #ifdef OBJECT_PRINT
   inline void MapPrint() {
@@ -5859,9 +5863,18 @@
  public:
   DECL_ACCESSORS(cache, Object)

+  static void Update(Handle<PolymorphicCodeCache> cache,
+                     MapHandleList* maps,
+                     Code::Flags flags,
+                     Handle<Code> code);
+
   MUST_USE_RESULT MaybeObject* Update(MapList* maps,
                                       Code::Flags flags,
                                       Code* code);
+
+  // Returns an undefined value if the entry is not found.
+  Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
+
   Object* Lookup(MapList* maps, Code::Flags flags);

   static inline PolymorphicCodeCache* cast(Object* obj);
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc   Fri Oct 21 03:19:16 2011
+++ /branches/bleeding_edge/src/stub-cache.cc   Fri Oct 21 04:42:54 2011
@@ -542,8 +542,23 @@
 }


-MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement(
-    JSObject* receiver,
+Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(Handle<Map> map) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     (set_failure(NULL), CompileLoadElement(*map)),
+                     Code);
+}
+
+
+Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(Handle<Map> map) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     (set_failure(NULL),
+                      CompileStoreElement(*map)),
+                      Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadOrStoreElement(
+    Handle<JSObject> receiver,
     KeyedIC::StubKind stub_kind,
     StrictModeFlag strict_mode) {
   Code::Flags flags =
@@ -552,60 +567,90 @@
                                      : Code::KEYED_STORE_IC,
           NORMAL,
           strict_mode);
-  String* name = NULL;
+  Handle<String> name;
   switch (stub_kind) {
     case KeyedIC::LOAD:
-      name = isolate()->heap()->KeyedLoadElementMonomorphic_symbol();
+      name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
       break;
     case KeyedIC::STORE_NO_TRANSITION:
-      name = isolate()->heap()->KeyedStoreElementMonomorphic_symbol();
+      name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol();
       break;
     default:
       UNREACHABLE();
       break;
   }
-  Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
-  if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
-
-  Map* receiver_map = receiver->map();
-  MaybeObject* maybe_new_code = NULL;
+  Handle<Map> receiver_map(receiver->map());
+  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags));
+  if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+  Handle<Code> code;
   switch (stub_kind) {
     case KeyedIC::LOAD: {
-      HandleScope scope(isolate_);
       KeyedLoadStubCompiler compiler(isolate_);
-      maybe_new_code = compiler.CompileLoadElement(receiver_map);
+      code = compiler.CompileLoadElement(receiver_map);
       break;
     }
     case KeyedIC::STORE_NO_TRANSITION: {
-      HandleScope scope(isolate_);
       KeyedStoreStubCompiler compiler(isolate_, strict_mode);
-      maybe_new_code = compiler.CompileStoreElement(receiver_map);
+      code = compiler.CompileStoreElement(receiver_map);
       break;
     }
     default:
       UNREACHABLE();
       break;
   }
-  Code* code = NULL;
-  if (!maybe_new_code->To(&code)) return maybe_new_code;
+
+  ASSERT(!code.is_null());

   if (stub_kind == KeyedIC::LOAD) {
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
-                            Code::cast(code), 0));
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
   } else {
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
-                            Code::cast(code), 0));
-  }
-  ASSERT(code->IsCode());
-  Object* result;
-  { MaybeObject* maybe_result =
-        receiver->UpdateMapCodeCache(name, Code::cast(code));
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
+  }
+  JSObject::UpdateMapCodeCache(receiver, name, code);
   return code;
 }
+
+
+Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
+    MapHandleList* receiver_maps,
+    CodeHandleList* handler_stubs) {
+  MapList raw_receiver_maps(receiver_maps->length());
+  CodeList raw_handler_stubs(handler_stubs->length());
+  CALL_HEAP_FUNCTION(
+      isolate(),
+      (set_failure(NULL),
+       raw_receiver_maps.Clear(),
+       raw_handler_stubs.Clear(),
+       CompileLoadPolymorphic(UnwrapHandleList(&raw_receiver_maps,
+                                               receiver_maps),
+                              UnwrapHandleList(&raw_handler_stubs,
+                                               handler_stubs))),
+      Code);
+}
+
+
+Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
+    MapHandleList* receiver_maps,
+    CodeHandleList* handler_stubs,
+    MapHandleList* transitioned_maps) {
+  MapList raw_receiver_maps(receiver_maps->length());
+  CodeList raw_handler_stubs(handler_stubs->length());
+  MapList raw_transitioned_maps(transitioned_maps->length());
+  CALL_HEAP_FUNCTION(
+      isolate(),
+      (set_failure(NULL),
+       raw_receiver_maps.Clear(),
+       raw_handler_stubs.Clear(),
+       raw_transitioned_maps.Clear(),
+       CompileStorePolymorphic(UnwrapHandleList(&raw_receiver_maps,
+                                                receiver_maps),
+                               UnwrapHandleList(&raw_handler_stubs,
+                                                handler_stubs),
+                               UnwrapHandleList(&raw_transitioned_maps,
+                                                transitioned_maps))),
+      Code);
+}


 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
=======================================
--- /branches/bleeding_edge/src/stub-cache.h    Fri Oct 21 03:19:16 2011
+++ /branches/bleeding_edge/src/stub-cache.h    Fri Oct 21 04:42:54 2011
@@ -168,10 +168,9 @@
                                       Handle<Map> transition,
                                       StrictModeFlag strict_mode);

-  MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement(
-      JSObject* receiver,
-      KeyedIC::StubKind stub_kind,
-      StrictModeFlag strict_mode);
+  Handle<Code> ComputeKeyedLoadOrStoreElement(Handle<JSObject> receiver,
+                                              KeyedIC::StubKind stub_kind,
+                                              StrictModeFlag strict_mode);

   // ---

@@ -687,8 +686,13 @@

   MUST_USE_RESULT MaybeObject* CompileLoadFunctionPrototype(String* name);

+  Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
+
   MUST_USE_RESULT MaybeObject* CompileLoadElement(Map* receiver_map);

+  Handle<Code> CompileLoadPolymorphic(MapHandleList* receiver_maps,
+                                      CodeHandleList* handler_ics);
+
   MUST_USE_RESULT MaybeObject* CompileLoadPolymorphic(
       MapList* receiver_maps,
       CodeList* handler_ics);
@@ -769,8 +773,14 @@
                                                  Map* transition,
                                                  String* name);

+  Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
+
   MUST_USE_RESULT MaybeObject* CompileStoreElement(Map* receiver_map);

+  Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps,
+                                       CodeHandleList* handler_stubs,
+                                       MapHandleList* transitioned_maps);
+
   MUST_USE_RESULT MaybeObject* CompileStorePolymorphic(
       MapList* receiver_maps,
       CodeList* handler_stubs,

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to