Commit 16843e23 authored by mvstanton's avatar mvstanton Committed by Commit bot

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}
parent 1de7dff2
...@@ -6200,7 +6200,7 @@ class Internals { ...@@ -6200,7 +6200,7 @@ class Internals {
static const int kNullValueRootIndex = 7; static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8; static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9; 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 // The external allocation limit should be below 256 MB on all architectures
// to avoid that resource-constrained embedders run low on memory. // to avoid that resource-constrained embedders run low on memory.
......
...@@ -3058,6 +3058,19 @@ void Heap::CreateInitialObjects() { ...@@ -3058,6 +3058,19 @@ void Heap::CreateInitialObjects() {
// Number of queued microtasks stored in Isolate::pending_microtask_count(). // Number of queued microtasks stored in Isolate::pending_microtask_count().
set_microtask_queue(empty_fixed_array()); 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 = Handle<SeededNumberDictionary> slow_element_dictionary =
SeededNumberDictionary::New(isolate(), 0, TENURED); SeededNumberDictionary::New(isolate(), 0, TENURED);
slow_element_dictionary->set_requires_slow_elements(); slow_element_dictionary->set_requires_slow_elements();
......
...@@ -182,7 +182,8 @@ namespace internal { ...@@ -182,7 +182,8 @@ namespace internal {
EmptySlowElementDictionary) \ EmptySlowElementDictionary) \
V(FixedArray, materialized_objects, MaterializedObjects) \ V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad) \ 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. // Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V) \ #define SMI_ROOT_LIST(V) \
......
...@@ -527,10 +527,25 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -527,10 +527,25 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
__ cmp(r4, ip); __ cmp(r4, ip);
__ b(eq, &probe_dictionary); __ 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::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC)); Code::ComputeHandlerFlags(Code::LOAD_IC));
masm->isolate()->stub_cache()->GenerateProbe( 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. // Cache miss.
GenerateMiss(masm); GenerateMiss(masm);
......
...@@ -533,9 +533,23 @@ static void GenerateKeyedLoadWithNameKey(MacroAssembler* masm, Register key, ...@@ -533,9 +533,23 @@ static void GenerateKeyedLoadWithNameKey(MacroAssembler* masm, Register key,
__ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset)); __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset));
__ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary); __ 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::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC)); 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, false, receiver, key, scratch1,
scratch2, scratch3, scratch4); scratch2, scratch3, scratch4);
// Cache miss. // Cache miss.
...@@ -578,7 +592,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -578,7 +592,7 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
__ Bind(&check_name); __ Bind(&check_name);
GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow); 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); __ Bind(&index_name);
__ IndexFromHash(x3, key); __ IndexFromHash(x3, key);
......
...@@ -399,10 +399,27 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -399,10 +399,27 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
Immediate(isolate->factory()->hash_table_map())); Immediate(isolate->factory()->hash_table_map()));
__ j(equal, &probe_dictionary); __ 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::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC)); Code::ComputeHandlerFlags(Code::LOAD_IC));
masm->isolate()->stub_cache()->GenerateProbe( masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags,
masm, Code::LOAD_IC, flags, false, receiver, key, ebx, no_reg); false, receiver, key, ebx, edi);
if (FLAG_vector_ics) {
__ pop(VectorLoadICDescriptor::VectorRegister());
__ pop(VectorLoadICDescriptor::SlotRegister());
}
// Cache miss. // Cache miss.
GenerateMiss(masm); GenerateMiss(masm);
......
...@@ -536,10 +536,24 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -536,10 +536,24 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
__ LoadRoot(at, Heap::kHashTableMapRootIndex); __ LoadRoot(at, Heap::kHashTableMapRootIndex);
__ Branch(&probe_dictionary, eq, t0, Operand(at)); __ 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::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC)); Code::ComputeHandlerFlags(Code::LOAD_IC));
masm->isolate()->stub_cache()->GenerateProbe( 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. // Cache miss.
GenerateMiss(masm); GenerateMiss(masm);
......
...@@ -332,10 +332,26 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -332,10 +332,26 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
Heap::kHashTableMapRootIndex); Heap::kHashTableMapRootIndex);
__ j(equal, &probe_dictionary); __ 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::Flags flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC)); Code::ComputeHandlerFlags(Code::LOAD_IC));
masm->isolate()->stub_cache()->GenerateProbe( masm->isolate()->stub_cache()->GenerateProbe(masm, Code::KEYED_LOAD_IC, flags,
masm, Code::LOAD_IC, flags, false, receiver, key, rbx, no_reg); false, receiver, key,
megamorphic_scratch, no_reg);
// Cache miss. // Cache miss.
GenerateMiss(masm); GenerateMiss(masm);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment