Megamorphic KeyedLoadIC needs special handling for vector ics.
authormvstanton <mvstanton@chromium.org>
Mon, 2 Feb 2015 13:55:00 +0000 (05:55 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 2 Feb 2015 13:55:21 +0000 (13:55 +0000)
When --vector-ics is true, we still tail-call to the hand-written
megamorphic KeyedLoadIC (formerly "generic"). Now that this code uses
the megamorphic cache, it needs to deal properly with the vector and
slot registers. Achieve this with a sentinel vectors/slot combo.

R=dcarney@chromium.org
BUG=

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

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

include/v8.h
src/heap/heap.cc
src/heap/heap.h
src/ic/arm/ic-arm.cc
src/ic/arm64/ic-arm64.cc
src/ic/ia32/ic-ia32.cc
src/ic/mips/ic-mips.cc
src/ic/x64/ic-x64.cc

index bd4cb4e..e8ca3df 100644 (file)
@@ -6200,7 +6200,7 @@ class Internals {
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 154;
+  static const int kEmptyStringRootIndex = 155;
 
   // The external allocation limit should be below 256 MB on all architectures
   // to avoid that resource-constrained embedders run low on memory.
index cec8714..52bd70a 100644 (file)
@@ -3058,6 +3058,19 @@ void Heap::CreateInitialObjects() {
   // Number of queued microtasks stored in Isolate::pending_microtask_count().
   set_microtask_queue(empty_fixed_array());
 
+  if (FLAG_vector_ics) {
+    FeedbackVectorSpec spec(0, 1);
+    spec.SetKind(0, Code::KEYED_LOAD_IC);
+    Handle<TypeFeedbackVector> dummy_vector =
+        factory->NewTypeFeedbackVector(spec);
+    dummy_vector->Set(FeedbackVectorICSlot(0),
+                      *TypeFeedbackVector::MegamorphicSentinel(isolate()),
+                      SKIP_WRITE_BARRIER);
+    set_keyed_load_dummy_vector(*dummy_vector);
+  } else {
+    set_keyed_load_dummy_vector(empty_fixed_array());
+  }
+
   Handle<SeededNumberDictionary> slow_element_dictionary =
       SeededNumberDictionary::New(isolate(), 0, TENURED);
   slow_element_dictionary->set_requires_slow_elements();
index ceae148..9d7341a 100644 (file)
@@ -182,7 +182,8 @@ namespace internal {
     EmptySlowElementDictionary)                                                \
   V(FixedArray, materialized_objects, MaterializedObjects)                     \
   V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad)        \
-  V(FixedArray, microtask_queue, MicrotaskQueue)
+  V(FixedArray, microtask_queue, MicrotaskQueue)                               \
+  V(FixedArray, keyed_load_dummy_vector, KeyedLoadDummyVector)
 
 // Entries in this list are limited to Smis and are not visited during GC.
 #define SMI_ROOT_LIST(V)                                                   \
index 29ec47f..0c9e1c3 100644 (file)
@@ -527,10 +527,25 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   __ cmp(r4, ip);
   __ b(eq, &probe_dictionary);
 
+
+  if (FLAG_vector_ics) {
+    // When vector ics are in use, the handlers in the stub cache expect a
+    // vector and slot. Since we won't change the IC from any downstream
+    // misses, a dummy vector can be used.
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, r4, r5, r6, r9));
+    Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
+        masm->isolate()->factory()->keyed_load_dummy_vector());
+    int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+    __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+    __ mov(slot, Operand(Smi::FromInt(int_slot)));
+  }
+
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
-      masm, Code::LOAD_IC, flags, false, receiver, key, r3, r4, r5, r6);
+      masm, Code::KEYED_LOAD_IC, flags, false, receiver, key, r4, r5, r6, r9);
   // Cache miss.
   GenerateMiss(masm);
 
index 7c51938..93245c3 100644 (file)
@@ -533,9 +533,23 @@ static void GenerateKeyedLoadWithNameKey(MacroAssembler* masm, Register key,
   __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset));
   __ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary);
 
+  if (FLAG_vector_ics) {
+    // When vector ics are in use, the handlers in the stub cache expect a
+    // vector and slot. Since we won't change the IC from any downstream
+    // misses, a dummy vector can be used.
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch1, scratch2, scratch3, scratch4));
+    Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
+        masm->isolate()->factory()->keyed_load_dummy_vector());
+    int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+    __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+    __ Mov(slot, Operand(Smi::FromInt(int_slot)));
+  }
+
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, flags,
+  masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags,
                                                false, receiver, key, scratch1,
                                                scratch2, scratch3, scratch4);
   // Cache miss.
@@ -578,7 +592,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   __ Bind(&check_name);
   GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow);
 
-  GenerateKeyedLoadWithNameKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow);
+  GenerateKeyedLoadWithNameKey(masm, key, receiver, x4, x5, x6, x7, x3, &slow);
 
   __ Bind(&index_name);
   __ IndexFromHash(x3, key);
index c302e85..c8e7215 100644 (file)
@@ -399,10 +399,27 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
          Immediate(isolate->factory()->hash_table_map()));
   __ j(equal, &probe_dictionary);
 
+  if (FLAG_vector_ics) {
+    // When vector ics are in use, the handlers in the stub cache expect a
+    // vector and slot. Since we won't change the IC from any downstream
+    // misses, a dummy vector can be used.
+    Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
+        isolate->factory()->keyed_load_dummy_vector());
+    int slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+    __ push(Immediate(Smi::FromInt(slot)));
+    __ push(Immediate(dummy_vector));
+  }
+
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, Code::LOAD_IC, flags, false, receiver, key, ebx, no_reg);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags,
+                                               false, receiver, key, ebx, edi);
+
+  if (FLAG_vector_ics) {
+    __ pop(VectorLoadICDescriptor::VectorRegister());
+    __ pop(VectorLoadICDescriptor::SlotRegister());
+  }
+
   // Cache miss.
   GenerateMiss(masm);
 
index ea32f4e..42c7ad1 100644 (file)
@@ -536,10 +536,24 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   __ LoadRoot(at, Heap::kHashTableMapRootIndex);
   __ Branch(&probe_dictionary, eq, t0, Operand(at));
 
+  if (FLAG_vector_ics) {
+    // When vector ics are in use, the handlers in the stub cache expect a
+    // vector and slot. Since we won't change the IC from any downstream
+    // misses, a dummy vector can be used.
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, t0, t1, t2, t5));
+    Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
+        masm->isolate()->factory()->keyed_load_dummy_vector());
+    int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+    __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
+    __ li(slot, Operand(Smi::FromInt(int_slot)));
+  }
+
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
-      masm, Code::LOAD_IC, flags, false, receiver, key, a3, t0, t1, t2);
+      masm, Code::LOAD_IC, flags, false, receiver, key, t0, t1, t2, t5);
   // Cache miss.
   GenerateMiss(masm);
 
index 0aba18e..174275b 100644 (file)
@@ -332,10 +332,26 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
                  Heap::kHashTableMapRootIndex);
   __ j(equal, &probe_dictionary);
 
+  Register megamorphic_scratch = rdi;
+  if (FLAG_vector_ics) {
+    // When vector ics are in use, the handlers in the stub cache expect a
+    // vector and slot. Since we won't change the IC from any downstream
+    // misses, a dummy vector can be used.
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(megamorphic_scratch, vector, slot));
+    Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
+        masm->isolate()->factory()->keyed_load_dummy_vector());
+    int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
+    __ Move(vector, dummy_vector);
+    __ Move(slot, Smi::FromInt(int_slot));
+  }
+
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::LOAD_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(
-      masm, Code::LOAD_IC, flags, false, receiver, key, rbx, no_reg);
+  masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags,
+                                               false, receiver, key,
+                                               megamorphic_scratch, no_reg);
   // Cache miss.
   GenerateMiss(masm);