From 16843e239d95f5e8eaaa06d2a0a6e371298fe11f Mon Sep 17 00:00:00 2001 From: mvstanton Date: Mon, 2 Feb 2015 05:55:00 -0800 Subject: [PATCH] Megamorphic KeyedLoadIC needs special handling for vector ics. 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 | 2 +- src/heap/heap.cc | 13 +++++++++++++ src/heap/heap.h | 3 ++- src/ic/arm/ic-arm.cc | 17 ++++++++++++++++- src/ic/arm64/ic-arm64.cc | 18 ++++++++++++++++-- src/ic/ia32/ic-ia32.cc | 21 +++++++++++++++++++-- src/ic/mips/ic-mips.cc | 16 +++++++++++++++- src/ic/x64/ic-x64.cc | 20 ++++++++++++++++++-- 8 files changed, 100 insertions(+), 10 deletions(-) diff --git a/include/v8.h b/include/v8.h index bd4cb4e..e8ca3df 100644 --- a/include/v8.h +++ b/include/v8.h @@ -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. diff --git a/src/heap/heap.cc b/src/heap/heap.cc index cec8714..52bd70a 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -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 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 slow_element_dictionary = SeededNumberDictionary::New(isolate(), 0, TENURED); slow_element_dictionary->set_requires_slow_elements(); diff --git a/src/heap/heap.h b/src/heap/heap.h index ceae148..9d7341a 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -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) \ diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc index 29ec47f..0c9e1c3 100644 --- a/src/ic/arm/ic-arm.cc +++ b/src/ic/arm/ic-arm.cc @@ -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 dummy_vector = Handle::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); diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc index 7c51938..93245c3 100644 --- a/src/ic/arm64/ic-arm64.cc +++ b/src/ic/arm64/ic-arm64.cc @@ -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 dummy_vector = Handle::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); diff --git a/src/ic/ia32/ic-ia32.cc b/src/ic/ia32/ic-ia32.cc index c302e85..c8e7215 100644 --- a/src/ic/ia32/ic-ia32.cc +++ b/src/ic/ia32/ic-ia32.cc @@ -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 dummy_vector = Handle::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); diff --git a/src/ic/mips/ic-mips.cc b/src/ic/mips/ic-mips.cc index ea32f4e..42c7ad1 100644 --- a/src/ic/mips/ic-mips.cc +++ b/src/ic/mips/ic-mips.cc @@ -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 dummy_vector = Handle::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); diff --git a/src/ic/x64/ic-x64.cc b/src/ic/x64/ic-x64.cc index 0aba18e..174275b 100644 --- a/src/ic/x64/ic-x64.cc +++ b/src/ic/x64/ic-x64.cc @@ -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 dummy_vector = Handle::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); -- 2.7.4