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}
This commit is contained in:
parent
1de7dff2ef
commit
16843e239d
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user