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:
mvstanton 2015-02-02 05:55:00 -08:00 committed by Commit bot
parent 1de7dff2ef
commit 16843e239d
8 changed files with 100 additions and 10 deletions

View 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.

View 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();

View 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) \

View 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);

View 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);

View 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);

View 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);

View 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);