Vector ICs: Adapting store ic classes for vectors.
authormvstanton <mvstanton@chromium.org>
Tue, 1 Sep 2015 14:09:07 +0000 (07:09 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 1 Sep 2015 14:09:24 +0000 (14:09 +0000)
BUG=

Review URL: https://codereview.chromium.org/1326483002

Cr-Commit-Position: refs/heads/master@{#30512}

src/ic/access-compiler.cc
src/ic/access-compiler.h
src/ic/handler-compiler.cc
src/ic/handler-compiler.h
src/ic/ic-compiler.cc
src/ic/ic-compiler.h
src/ic/ic.cc
src/ic/ic.h
src/type-feedback-vector.h

index 0dc9ab6e8dd9337c22c83bc2a0bedef844417610..951966e7debe521a2c0901e59a962d48514c7134 100644 (file)
@@ -49,5 +49,25 @@ Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
   DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
   return store_calling_convention();
 }
+
+
+Register PropertyAccessCompiler::slot() const {
+  if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
+    return LoadDescriptor::SlotRegister();
+  }
+  DCHECK(FLAG_vector_stores &&
+         (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC));
+  return VectorStoreICDescriptor::SlotRegister();
+}
+
+
+Register PropertyAccessCompiler::vector() const {
+  if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
+    return LoadWithVectorDescriptor::VectorRegister();
+  }
+  DCHECK(FLAG_vector_stores &&
+         (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC));
+  return VectorStoreICDescriptor::VectorRegister();
+}
 }  // namespace internal
 }  // namespace v8
index 61567a2224b14132e57a1bdd90f143a595d01f17..4eb70eff7780471fee5815ace8a263c63e8d9202 100644 (file)
@@ -54,8 +54,8 @@ class PropertyAccessCompiler BASE_EMBEDDED {
 
   Register receiver() const { return registers_[0]; }
   Register name() const { return registers_[1]; }
-  Register slot() const { return LoadDescriptor::SlotRegister(); }
-  Register vector() const { return LoadWithVectorDescriptor::VectorRegister(); }
+  Register slot() const;
+  Register vector() const;
   Register scratch1() const { return registers_[2]; }
   Register scratch2() const { return registers_[3]; }
   Register scratch3() const { return registers_[4]; }
index 7e242d3bc979c6e8ec61f18ba5facead4402d4c5..a42fc690f86e073f22f21c21da1b3432eecef508 100644 (file)
@@ -424,6 +424,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
     Handle<Map> transition, Handle<Name> name) {
   Label miss;
 
+  if (FLAG_vector_stores) PushVectorAndSlot();
+
   // Check that we are allowed to write this.
   bool is_nonexistent = holder()->map() == transition->GetBackPointer();
   if (is_nonexistent) {
@@ -454,16 +456,19 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
   DCHECK(!transition->is_access_check_needed());
 
   // Call to respective StoreTransitionStub.
-  Register transition_map_reg = StoreTransitionDescriptor::MapRegister();
-  bool push_map_on_stack = transition_map_reg.is(no_reg);
-  Register map_reg = push_map_on_stack ? scratch1() : transition_map_reg;
+  Register transition_map_reg = StoreTransitionHelper::MapRegister();
+  bool stack_args = StoreTransitionHelper::UsesStackArgs();
+  Register map_reg = stack_args ? scratch1() : transition_map_reg;
 
   if (details.type() == DATA_CONSTANT) {
     DCHECK(descriptors->GetValue(descriptor)->IsJSFunction());
     GenerateRestoreMap(transition, map_reg, scratch2(), &miss);
     GenerateConstantCheck(map_reg, descriptor, value(), scratch2(), &miss);
-    if (push_map_on_stack) {
+    if (stack_args) {
+      // Also pushes vector and slot.
       GeneratePushMap(map_reg, scratch2());
+    } else if (FLAG_vector_stores) {
+      PopVectorAndSlot();
     }
     GenerateRestoreName(name);
     StoreTransitionStub stub(isolate());
@@ -480,8 +485,11 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
             : StoreTransitionStub::StoreMapAndValue;
 
     GenerateRestoreMap(transition, map_reg, scratch2(), &miss);
-    if (push_map_on_stack) {
+    if (stack_args) {
+      // Also pushes vector and slot.
       GeneratePushMap(map_reg, scratch2());
+    } else if (FLAG_vector_stores) {
+      PopVectorAndSlot();
     }
     GenerateRestoreName(name);
     StoreTransitionStub stub(isolate(),
@@ -491,21 +499,37 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
   }
 
   GenerateRestoreName(&miss, name);
+  if (FLAG_vector_stores) PopVectorAndSlot();
   TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   return GetCode(kind(), Code::FAST, name);
 }
 
 
+bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks(
+    HeapType* field_type) const {
+  return !field_type->Classes().Done();
+}
+
+
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
   Label miss;
   DCHECK(it->representation().IsHeapObject());
 
-  GenerateFieldTypeChecks(*it->GetFieldType(), value(), &miss);
+  HeapType* field_type = *it->GetFieldType();
+  bool need_save_restore = false;
+  if (RequiresFieldTypeChecks(field_type)) {
+    need_save_restore = IC::ICUseVector(kind());
+    if (need_save_restore) PushVectorAndSlot();
+    GenerateFieldTypeChecks(field_type, value(), &miss);
+    if (need_save_restore) PopVectorAndSlot();
+  }
+
   StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation());
   GenerateTailCall(masm(), stub.GetCode());
 
   __ bind(&miss);
+  if (need_save_restore) PopVectorAndSlot();
   TailCallBuiltin(masm(), MissBuiltin(kind()));
   return GetCode(kind(), Code::FAST, it->name());
 }
index 05c973a6250da8b8d83d654f8565bf8f8e7244b9..f5dafe9038a11c6ba21b4f8d09461ebfb634a654 100644 (file)
@@ -262,6 +262,7 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
                              Register value_reg, Register scratch,
                              Label* miss_label);
 
+  bool RequiresFieldTypeChecks(HeapType* field_type) const;
   void GenerateFieldTypeChecks(HeapType* field_type, Register value_reg,
                                Label* miss_label);
 
index d42bfa77934e95dfe5b2a375291498f2cf3474f4..875d98729fc83f8e340b99809e37e917b9939f95 100644 (file)
@@ -119,6 +119,25 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
 }
 
 
+Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+    Handle<Map> receiver_map, LanguageMode language_mode,
+    KeyedAccessStoreMode store_mode) {
+  Isolate* isolate = receiver_map->GetIsolate();
+  ExtraICState extra_state =
+      KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
+
+  DCHECK(store_mode == STANDARD_STORE ||
+         store_mode == STORE_AND_GROW_NO_TRANSITION ||
+         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
+         store_mode == STORE_NO_TRANSITION_HANDLE_COW);
+
+  PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
+  Handle<Code> code =
+      compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
+  return code;
+}
+
+
 Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
     Handle<Map> receiver_map, LanguageMode language_mode,
     KeyedAccessStoreMode store_mode) {
@@ -220,31 +239,6 @@ Handle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map,
 }
 
 
-Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
-    MapHandleList* receiver_maps, LanguageMode language_mode) {
-  Isolate* isolate = receiver_maps->at(0)->GetIsolate();
-  DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
-  Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
-  Handle<PolymorphicCodeCache> cache =
-      isolate->factory()->polymorphic_code_cache();
-  Handle<Object> probe = cache->Lookup(receiver_maps, flags);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
-
-  CodeHandleList handlers(receiver_maps->length());
-  ElementHandlerCompiler compiler(isolate);
-  compiler.CompileElementHandlers(receiver_maps, &handlers, language_mode);
-  PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
-  Handle<Code> code = ic_compiler.CompilePolymorphic(
-      receiver_maps, &handlers, isolate->factory()->empty_string(),
-      Code::NORMAL, ELEMENT);
-
-  isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
-
-  PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
-  return code;
-}
-
-
 Handle<Code> PropertyICCompiler::ComputePolymorphic(
     Code::Kind kind, MapHandleList* maps, CodeHandleList* handlers,
     int valid_maps, Handle<Name> name, ExtraICState extra_ic_state) {
@@ -256,6 +250,23 @@ Handle<Code> PropertyICCompiler::ComputePolymorphic(
 }
 
 
+void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
+    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+    CodeHandleList* handlers, KeyedAccessStoreMode store_mode,
+    LanguageMode language_mode) {
+  Isolate* isolate = receiver_maps->at(0)->GetIsolate();
+  DCHECK(store_mode == STANDARD_STORE ||
+         store_mode == STORE_AND_GROW_NO_TRANSITION ||
+         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
+         store_mode == STORE_NO_TRANSITION_HANDLE_COW);
+  ExtraICState extra_state =
+      KeyedStoreIC::ComputeExtraICState(language_mode, store_mode);
+  PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
+  compiler.CompileKeyedStorePolymorphicHandlers(
+      receiver_maps, transitioned_maps, handlers, store_mode);
+}
+
+
 Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
     MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
     LanguageMode language_mode) {
@@ -338,11 +349,9 @@ Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
 }
 
 
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
-    MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
-  // Collect MONOMORPHIC stubs for all |receiver_maps|.
-  CodeHandleList handlers(receiver_maps->length());
-  MapHandleList transitioned_maps(receiver_maps->length());
+void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
+    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+    CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
   for (int i = 0; i < receiver_maps->length(); ++i) {
     Handle<Map> receiver_map(receiver_maps->at(i));
     Handle<Code> cached_stub;
@@ -379,9 +388,19 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
       }
     }
     DCHECK(!cached_stub.is_null());
-    handlers.Add(cached_stub);
-    transitioned_maps.Add(transitioned_map);
+    handlers->Add(cached_stub);
+    transitioned_maps->Add(transitioned_map);
   }
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
+    MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
+  // Collect MONOMORPHIC stubs for all |receiver_maps|.
+  CodeHandleList handlers(receiver_maps->length());
+  MapHandleList transitioned_maps(receiver_maps->length());
+  CompileKeyedStorePolymorphicHandlers(receiver_maps, &transitioned_maps,
+                                       &handlers, store_mode);
 
   Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers,
                                                    &transitioned_maps);
@@ -394,7 +413,7 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
     Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
   ElementsKind elements_kind = receiver_map->elements_kind();
   bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
@@ -408,6 +427,14 @@ Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
   } else {
     stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
   }
+  return stub;
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
+    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
+  Handle<Code> stub =
+      CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
 
   Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
 
index b5226e9a6eb451f7e69f3e5bccd9036245623e0a..ee6597d59d04b32a99407ec21844f29cace20244 100644 (file)
@@ -34,11 +34,16 @@ class PropertyICCompiler : public PropertyAccessCompiler {
   static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
       Handle<Map> receiver_map, ExtraICState extra_ic_state);
 
+  static Handle<Code> ComputeKeyedStoreMonomorphicHandler(
+      Handle<Map> receiver_map, LanguageMode language_mode,
+      KeyedAccessStoreMode store_mode);
   static Handle<Code> ComputeKeyedStoreMonomorphic(
       Handle<Map> receiver_map, LanguageMode language_mode,
       KeyedAccessStoreMode store_mode);
-  static Handle<Code> ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps,
-                                                  LanguageMode language_mode);
+  static void ComputeKeyedStorePolymorphicHandlers(
+      MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
+      CodeHandleList* handlers, KeyedAccessStoreMode store_mode,
+      LanguageMode language_mode);
   static Handle<Code> ComputeKeyedStorePolymorphic(
       MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
       LanguageMode language_mode);
@@ -78,10 +83,16 @@ class PropertyICCompiler : public PropertyAccessCompiler {
                                   Handle<Name> name, Code::StubType type,
                                   IcCheckType check);
 
+  Handle<Code> CompileKeyedStoreMonomorphicHandler(
+      Handle<Map> receiver_map, KeyedAccessStoreMode store_mode);
   Handle<Code> CompileKeyedStoreMonomorphic(Handle<Map> receiver_map,
                                             KeyedAccessStoreMode store_mode);
   Handle<Code> CompileKeyedStorePolymorphic(MapHandleList* receiver_maps,
                                             KeyedAccessStoreMode store_mode);
+  void CompileKeyedStorePolymorphicHandlers(MapHandleList* receiver_maps,
+                                            MapHandleList* transitioned_maps,
+                                            CodeHandleList* handlers,
+                                            KeyedAccessStoreMode store_mode);
   Handle<Code> CompileKeyedStorePolymorphic(MapHandleList* receiver_maps,
                                             CodeHandleList* handler_stubs,
                                             MapHandleList* transitioned_maps);
index 644df525d24492562c9a5cd017040df55a812806..85e3f3c889e0e0a617760eb3d3e1e49b05f2a8f4 100644 (file)
@@ -123,8 +123,11 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
     ExtraICState extra_state = new_target->extra_ic_state();
     const char* modifier = "";
     if (new_target->kind() == Code::KEYED_STORE_IC) {
-      modifier = GetTransitionMarkModifier(
-          KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
+      KeyedAccessStoreMode mode =
+          FLAG_vector_stores
+              ? casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode()
+              : KeyedStoreIC::GetKeyedAccessStoreMode(extra_state);
+      modifier = GetTransitionMarkModifier(mode);
     }
     PrintF(" (%c->%c%s) ", TransitionMarkFromState(old_state),
            TransitionMarkFromState(new_state), modifier);
@@ -666,6 +669,20 @@ void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
 }
 
 
+void IC::ConfigureVectorState(MapHandleList* maps,
+                              MapHandleList* transitioned_maps,
+                              CodeHandleList* handlers) {
+  DCHECK(UseVector());
+  DCHECK(kind() == Code::KEYED_STORE_IC);
+  KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
+  nexus->ConfigurePolymorphic(maps, transitioned_maps, handlers);
+
+  vector_set_ = true;
+  OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
+                        POLYMORPHIC);
+}
+
+
 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
   // If the object is undefined or null it's illegal to try to get any
   // of its properties; throw a TypeError in that case.
@@ -967,7 +984,7 @@ static Handle<Code> KeyedStoreICInitializeStubHelper(
 Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate,
                                            LanguageMode language_mode,
                                            State initialization_state) {
-  if (FLAG_vector_stores) {
+  if (FLAG_vector_stores && initialization_state != MEGAMORPHIC) {
     VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
     return stub.GetCode();
   }
@@ -989,6 +1006,13 @@ Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code(
 }
 
 
+Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
+                                                 ExtraICState extra_state) {
+  LanguageMode mode = StoreICState::GetLanguageMode(extra_state);
+  return KeyedStoreICInitializeStubHelper(isolate, mode, MEGAMORPHIC);
+}
+
+
 Handle<Code> LoadIC::megamorphic_stub() {
   DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
   return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state());
@@ -1854,6 +1878,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
 
 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
                                             KeyedAccessStoreMode store_mode) {
+  Handle<Code> null_handle;
   // Don't handle megamorphic property accesses for INTERCEPTORS or
   // ACCESSOR_CONSTANT
   // via megamorphic stubs, since they don't have a map in their relocation info
@@ -1869,6 +1894,13 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
     Handle<Map> monomorphic_map =
         ComputeTransitionedMap(receiver_map, store_mode);
     store_mode = GetNonTransitioningStoreMode(store_mode);
+    if (FLAG_vector_stores) {
+      Handle<Code> handler =
+          PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+              monomorphic_map, language_mode(), store_mode);
+      ConfigureVectorState(Handle<Name>::null(), monomorphic_map, handler);
+      return null_handle;
+    }
     return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
         monomorphic_map, language_mode(), store_mode);
   }
@@ -1878,7 +1910,9 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
   // superset of the original IC. Handle those here if the receiver map hasn't
   // changed or it has transitioned to a more general kind.
   KeyedAccessStoreMode old_store_mode =
-      KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
+      FLAG_vector_stores
+          ? GetKeyedAccessStoreMode()
+          : KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
   Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
   if (state() == MONOMORPHIC) {
     Handle<Map> transitioned_receiver_map = receiver_map;
@@ -1894,6 +1928,14 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
       // if they at least come from the same origin for a transitioning store,
       // stay MONOMORPHIC and use the map for the most generic ElementsKind.
       store_mode = GetNonTransitioningStoreMode(store_mode);
+      if (FLAG_vector_stores) {
+        Handle<Code> handler =
+            PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+                transitioned_receiver_map, language_mode(), store_mode);
+        ConfigureVectorState(Handle<Name>::null(), transitioned_receiver_map,
+                             handler);
+        return null_handle;
+      }
       return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
           transitioned_receiver_map, language_mode(), store_mode);
     } else if (receiver_map.is_identical_to(previous_receiver_map) &&
@@ -1904,6 +1946,13 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
       // A "normal" IC that handles stores can switch to a version that can
       // grow at the end of the array, handle OOB accesses or copy COW arrays
       // and still stay MONOMORPHIC.
+      if (FLAG_vector_stores) {
+        Handle<Code> handler =
+            PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
+                receiver_map, language_mode(), store_mode);
+        ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
+        return null_handle;
+      }
       return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
           receiver_map, language_mode(), store_mode);
     }
@@ -1964,6 +2013,16 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
     }
   }
 
+  if (FLAG_vector_stores) {
+    MapHandleList transitioned_maps(target_receiver_maps.length());
+    CodeHandleList handlers(target_receiver_maps.length());
+    PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
+        &target_receiver_maps, &transitioned_maps, &handlers, store_mode,
+        language_mode());
+    ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers);
+    return null_handle;
+  }
+
   return PropertyICCompiler::ComputeKeyedStorePolymorphic(
       &target_receiver_maps, store_mode, language_mode());
 }
@@ -2200,7 +2259,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
 
           // Validate that the store_mode in the stub can also be derived
           // from peeking in the code bits of the handlers.
-          ValidateStoreMode(stub);
+          if (!FLAG_vector_stores) ValidateStoreMode(stub);
         } else {
           TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
         }
@@ -2467,7 +2526,7 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
   Handle<Object> result;
 
   if (FLAG_vector_stores) {
-    DCHECK(args.length() == 5);
+    DCHECK(args.length() == 5 || args.length() == 6);
     Handle<Smi> slot = args.at<Smi>(3);
     Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
     FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
@@ -2595,12 +2654,19 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) {
 
 RUNTIME_FUNCTION(Runtime_StoreIC_Slow) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+  DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3));
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  LanguageMode language_mode = ic.language_mode();
+  LanguageMode language_mode;
+  if (FLAG_vector_stores) {
+    StoreICNexus nexus(isolate);
+    StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
+    language_mode = ic.language_mode();
+  } else {
+    StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+    language_mode = ic.language_mode();
+  }
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
@@ -2611,12 +2677,19 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Slow) {
 
 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+  DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3));
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  LanguageMode language_mode = ic.language_mode();
+  LanguageMode language_mode;
+  if (FLAG_vector_stores) {
+    KeyedStoreICNexus nexus(isolate);
+    KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
+    language_mode = ic.language_mode();
+  } else {
+    KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+    language_mode = ic.language_mode();
+  }
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
@@ -2628,14 +2701,20 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
+  DCHECK(args.length() == (FLAG_vector_stores ? 6 : 4));
   Handle<Object> object = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
   Handle<Object> value = args.at<Object>(2);
-  Handle<Map> map = args.at<Map>(3);
-
-  LanguageMode language_mode = ic.language_mode();
+  Handle<Map> map = args.at<Map>(FLAG_vector_stores ? 5 : 3);
+  LanguageMode language_mode;
+  if (FLAG_vector_stores) {
+    KeyedStoreICNexus nexus(isolate);
+    KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
+    language_mode = ic.language_mode();
+  } else {
+    KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
+    language_mode = ic.language_mode();
+  }
   if (object->IsJSObject()) {
     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
                                      map->elements_kind());
index 9223e7dce8e6e16d396c6bf006813fe8bf7f6e41..6002d9291383819645f1b97f46549c3e5a402372 100644 (file)
@@ -122,6 +122,11 @@ class IC {
   // Configure the vector for POLYMORPHIC.
   void ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
                             CodeHandleList* handlers);
+  // Configure the vector for POLYMORPHIC with transitions (only for element
+  // keyed stores).
+  void ConfigureVectorState(MapHandleList* maps,
+                            MapHandleList* transitioned_maps,
+                            CodeHandleList* handlers);
 
   char TransitionMarkFromState(IC::State state);
   void TraceIC(const char* type, Handle<Object> name);
@@ -538,10 +543,17 @@ class KeyedStoreIC : public StoreIC {
 
   static KeyedAccessStoreMode GetKeyedAccessStoreMode(
       ExtraICState extra_state) {
+    DCHECK(!FLAG_vector_stores);
     return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
   }
 
+  KeyedAccessStoreMode GetKeyedAccessStoreMode() {
+    DCHECK(FLAG_vector_stores);
+    return casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode();
+  }
+
   static IcCheckType GetKeyType(ExtraICState extra_state) {
+    DCHECK(!FLAG_vector_stores);
     return IcCheckTypeField::decode(extra_state);
   }
 
@@ -571,6 +583,8 @@ class KeyedStoreIC : public StoreIC {
 
   static Handle<Code> initialize_stub_in_optimized_code(
       Isolate* isolate, LanguageMode language_mode, State initialization_state);
+  static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
+                                            ExtraICState extra_state);
 
   static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus);
 
index cbba89339a305d30ff050fecd57bb78732102e31..2118a088f4d18badb894d0e67941f3aa4c61c445 100644 (file)
@@ -407,6 +407,10 @@ class KeyedStoreICNexus : public FeedbackNexus {
       : FeedbackNexus(vector, slot) {
     DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);
   }
+  explicit KeyedStoreICNexus(Isolate* isolate)
+      : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
+                      TypeFeedbackVector::DummySlot(
+                          TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
   KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
       : FeedbackNexus(vector, slot) {
     DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);