Now that vector ics are established for load, keyed load and call ics, let's remove dead code behind the flag.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#28422}
This commit is contained in:
mvstanton 2015-05-15 06:25:25 -07:00 committed by Commit bot
parent de3a1ca02e
commit 323ced9e27
73 changed files with 482 additions and 1613 deletions

View File

@ -1489,8 +1489,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
// Ensure that the vector and slot registers won't be clobbered before
// calling the miss handler.
DCHECK(!FLAG_vector_ics ||
!AreAliased(r4, r5, VectorLoadICDescriptor::VectorRegister(),
DCHECK(!AreAliased(r4, r5, VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister()));
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r4,
@ -1510,9 +1509,8 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
Register scratch = r5;
Register result = r0;
DCHECK(!scratch.is(receiver) && !scratch.is(index));
DCHECK(!FLAG_vector_ics ||
(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister())));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister()));
// StringCharAtGenerator doesn't use the result register until it's passed
// the different miss possibilities. If it did, we would have a conflict
@ -2953,7 +2951,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
index_not_number_,
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Push(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_, index_);
} else {
@ -2970,7 +2968,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
__ Move(index_, r0);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Pop(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_);
} else {

View File

@ -144,10 +144,8 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.bit() | name.bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
}
RegList regs = receiver.bit() | name.bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}

View File

@ -1333,13 +1333,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ Move(LoadDescriptor::NameRegister(), home_object_symbol);
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
__ cmp(r0, Operand(isolate()->factory()->undefined_value()));
Label done;
@ -1412,10 +1408,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
__ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
@ -1502,10 +1496,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "[ Global variable");
__ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
CallGlobalLoadIC(var->name());
context()->Plug(r0);
break;
@ -2200,10 +2192,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_call);
__ ldr(load_receiver, MemOperand(sp, kPointerSize));
__ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(r1, r0);
@ -2220,10 +2210,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
@ -2233,10 +2221,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result.value
__ pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
context()->DropAndPlug(2, r0); // drop iter and g
break;
@ -2388,13 +2374,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2413,13 +2395,9 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
}
@ -4631,13 +4609,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -5070,10 +5044,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "[ Global variable");
__ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);

View File

@ -1105,20 +1105,6 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), r1);

View File

@ -154,7 +154,6 @@ class LCodeGen;
V(SubI) \
V(RSubI) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -475,26 +474,6 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -2987,7 +2987,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -3010,9 +3009,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(r0));
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3109,9 +3106,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in r2.
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
@ -3962,29 +3957,6 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
DCHECK(receiver.is(r1));
DCHECK(name.is(r2));
Register scratch = r4;
Register extra = r5;
Register extra2 = r6;
Register extra3 = r9;
// The probe will tail call to a handler if found.
isolate()->stub_cache()->GenerateProbe(
masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name,
scratch, extra, extra2, extra3);
// Tail call to miss if we ended up here.
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(ToRegister(instr->result()).is(r0));

View File

@ -1449,8 +1449,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
// Ensure that the vector and slot registers won't be clobbered before
// calling the miss handler.
DCHECK(!FLAG_vector_ics ||
!AreAliased(x10, x11, VectorLoadICDescriptor::VectorRegister(),
DCHECK(!AreAliased(x10, x11, VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister()));
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10,
@ -1471,9 +1470,8 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
Register result = x0;
Register scratch = x10;
DCHECK(!scratch.is(receiver) && !scratch.is(index));
DCHECK(!FLAG_vector_ics ||
(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister())));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister()));
// StringCharAtGenerator doesn't use the result register until it's passed
// the different miss possibilities. If it did, we would have a conflict
@ -3354,7 +3352,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// If index is a heap number, try converting it to an integer.
__ JumpIfNotHeapNumber(index_, index_not_number_);
call_helper.BeforeCall(masm);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Push(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_, index_);
} else {
@ -3371,7 +3369,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
__ Mov(index_, x0);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Pop(object_, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister());
} else {

View File

@ -207,10 +207,8 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.Bit() | name.Bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().Bit();
}
RegList regs = receiver.Bit() | name.Bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().Bit();
Generate_DebugBreakCallHelper(masm, regs, 0, x10);
}

View File

@ -1318,13 +1318,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ Mov(LoadDescriptor::NameRegister(), Operand(home_object_symbol));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
__ Mov(x10, Operand(isolate()->factory()->undefined_value()));
__ cmp(x0, x10);
@ -1392,10 +1388,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
__ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand());
__ Mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL
: CONTEXTUAL;
@ -1478,10 +1472,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "Global variable");
__ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand());
__ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
CallGlobalLoadIC(var->name());
context()->Plug(x0);
break;
@ -2054,13 +2046,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2080,13 +2068,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in x0 and x1.
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
}
@ -4312,13 +4296,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
Handle<String> name = expr->name();
__ Mov(LoadDescriptor::NameRegister(), Operand(name));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -4746,10 +4726,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "Global variable");
__ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand());
__ Mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);
@ -5103,10 +5081,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Bind(&l_call);
__ Peek(load_receiver, 1 * kPointerSize);
__ Peek(load_name, 2 * kPointerSize);
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ Mov(x1, x0);
@ -5123,10 +5099,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL); // x0=result.done
// The ToBooleanStub argument (result.done) is in x0.
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@ -5136,10 +5110,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result.value
__ Pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
}
__ Mov(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL); // x0=result.value
context()->DropAndPlug(2, x0); // drop iter and g
break;

View File

@ -1588,20 +1588,6 @@ LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
// The function is required (by MacroAssembler::InvokeFunction) to be in x1.

View File

@ -165,7 +165,6 @@ class LCodeGen;
V(SubI) \
V(SubS) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -319,26 +318,6 @@ class LTemplateInstruction : public LTemplateResultInstruction<R> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -2022,29 +2022,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
DCHECK(receiver.is(x1));
DCHECK(name.is(x2));
Register scratch = x4;
Register extra = x5;
Register extra2 = x6;
Register extra3 = x7;
// The probe will tail call to a handler if found.
isolate()->stub_cache()->GenerateProbe(
masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name,
scratch, extra, extra2, extra3);
// Tail call to miss if we ended up here.
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(instr->IsMarkedAsCall());
DCHECK(ToRegister(instr->result()).Is(x0));
@ -3363,7 +3340,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -3385,9 +3361,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
.is(LoadDescriptor::ReceiverRegister()));
DCHECK(ToRegister(instr->result()).Is(x0));
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3714,9 +3688,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// LoadIC expects name and receiver in registers.
DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,

View File

@ -18,7 +18,7 @@ class AstNumberingVisitor final : public AstVisitor {
: AstVisitor(),
next_id_(BailoutId::FirstUsable().ToInt()),
properties_(zone),
ic_slot_cache_(FLAG_vector_ics ? 4 : 0),
ic_slot_cache_(4),
dont_optimize_reason_(kNoReason) {
InitializeAstVisitor(isolate, zone);
}
@ -71,10 +71,8 @@ class AstNumberingVisitor final : public AstVisitor {
node->SetFirstFeedbackICSlot(FeedbackVectorICSlot(ic_slots),
&ic_slot_cache_);
properties_.increase_ic_slots(reqs.ic_slots());
if (FLAG_vector_ics) {
for (int i = 0; i < reqs.ic_slots(); i++) {
properties_.SetKind(ic_slots + i, node->FeedbackICSlotKind(i));
}
for (int i = 0; i < reqs.ic_slots(); i++) {
properties_.SetKind(ic_slots + i, node->FeedbackICSlotKind(i));
}
}
}
@ -83,8 +81,7 @@ class AstNumberingVisitor final : public AstVisitor {
int next_id_;
AstProperties properties_;
// The slot cache allows us to reuse certain vector IC slots. It's only used
// if FLAG_vector_ics is true.
// The slot cache allows us to reuse certain vector IC slots.
ICSlotCache ic_slot_cache_;
BailoutReason dont_optimize_reason_;

View File

@ -1592,7 +1592,7 @@ class VariableProxy final : public Expression {
void BindTo(Variable* var);
bool UsesVariableFeedbackSlot() const {
return FLAG_vector_ics && (var()->IsUnallocated() || var()->IsLookupSlot());
return var()->IsUnallocated() || var()->IsLookupSlot();
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
@ -1691,7 +1691,7 @@ class Property final : public Expression {
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
Isolate* isolate, const ICSlotCache* cache) override {
return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
return FeedbackVectorRequirements(0, 1);
}
void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
ICSlotCache* cache) override {
@ -1702,7 +1702,7 @@ class Property final : public Expression {
}
FeedbackVectorICSlot PropertyFeedbackSlot() const {
DCHECK(!FLAG_vector_ics || !property_feedback_slot_.IsInvalid());
DCHECK(!property_feedback_slot_.IsInvalid());
return property_feedback_slot_;
}
@ -1939,9 +1939,7 @@ class CallRuntime final : public Expression {
bool is_jsruntime() const { return function_ == NULL; }
// Type feedback information.
bool HasCallRuntimeFeedbackSlot() const {
return FLAG_vector_ics && is_jsruntime();
}
bool HasCallRuntimeFeedbackSlot() const { return is_jsruntime(); }
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
Isolate* isolate, const ICSlotCache* cache) override {
return FeedbackVectorRequirements(0, HasCallRuntimeFeedbackSlot() ? 1 : 0);
@ -2331,9 +2329,7 @@ class Yield final : public Expression {
}
// Type feedback information.
bool HasFeedbackSlots() const {
return FLAG_vector_ics && (yield_kind() == kDelegating);
}
bool HasFeedbackSlots() const { return yield_kind() == kDelegating; }
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
Isolate* isolate, const ICSlotCache* cache) override {
return FeedbackVectorRequirements(0, HasFeedbackSlots() ? 3 : 0);
@ -2691,7 +2687,7 @@ class SuperReference final : public Expression {
// Type feedback information.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
Isolate* isolate, const ICSlotCache* cache) override {
return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
return FeedbackVectorRequirements(0, 1);
}
void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
ICSlotCache* cache) override {
@ -2700,7 +2696,7 @@ class SuperReference final : public Expression {
Code::Kind FeedbackICSlotKind(int index) override { return Code::LOAD_IC; }
FeedbackVectorICSlot HomeObjectFeedbackSlot() {
DCHECK(!FLAG_vector_ics || !homeobject_feedback_slot_.IsInvalid());
DCHECK(!homeobject_feedback_slot_.IsInvalid());
return homeobject_feedback_slot_;
}

View File

@ -1309,11 +1309,6 @@ static void Generate_KeyedLoadIC_Megamorphic(MacroAssembler* masm) {
}
static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
KeyedLoadIC::GeneratePreMonomorphic(masm);
}
static void Generate_StoreIC_Miss(MacroAssembler* masm) {
StoreIC::GenerateMiss(masm);
}

View File

@ -87,8 +87,6 @@ enum BuiltinExtraArguments {
V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, kNoExtraICState) \
V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, kNoExtraICState) \
V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC, \
kNoExtraICState) \
V(KeyedLoadIC_Megamorphic, KEYED_LOAD_IC, MEGAMORPHIC, kNoExtraICState) \
\
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, StoreIC::kStrictModeState) \

View File

@ -11,14 +11,6 @@
namespace v8 {
namespace internal {
// static
Callable CodeFactory::LoadGlobalIC(Isolate* isolate,
Handle<GlobalObject> global,
Handle<String> name) {
return Callable(LoadIC::load_global(isolate, global, name),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode) {
@ -34,10 +26,7 @@ Callable CodeFactory::LoadICInOptimizedCode(
InlineCacheState initialization_state) {
auto code = LoadIC::initialize_stub_in_optimized_code(
isolate, LoadICState(mode).GetExtraICState(), initialization_state);
if (FLAG_vector_ics) {
return Callable(code, VectorLoadICDescriptor(isolate));
}
return Callable(code, LoadDescriptor(isolate));
return Callable(code, VectorLoadICDescriptor(isolate));
}
@ -53,7 +42,7 @@ Callable CodeFactory::KeyedLoadICInOptimizedCode(
Isolate* isolate, InlineCacheState initialization_state) {
auto code = KeyedLoadIC::initialize_stub_in_optimized_code(
isolate, initialization_state);
if (FLAG_vector_ics && initialization_state != MEGAMORPHIC) {
if (initialization_state != MEGAMORPHIC) {
return Callable(code, VectorLoadICDescriptor(isolate));
}
return Callable(code, LoadDescriptor(isolate));

View File

@ -32,8 +32,6 @@ class Callable final BASE_EMBEDDED {
class CodeFactory final {
public:
// Initial states for ICs.
static Callable LoadGlobalIC(Isolate* isolate, Handle<GlobalObject> global,
Handle<String> name);
static Callable LoadIC(Isolate* isolate, ContextualMode mode);
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode,
InlineCacheState initialization_state);

View File

@ -2205,29 +2205,4 @@ Handle<Code> KeyedLoadGenericStub::GenerateCode() {
return DoGenerateCode(this);
}
Handle<Code> MegamorphicLoadStub::GenerateCode() {
return DoGenerateCode(this);
}
template <>
HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
HValue* name = GetParameter(LoadDescriptor::kNameIndex);
// We shouldn't generate this when FLAG_vector_ics is true because the
// megamorphic case is handled as part of the default stub.
DCHECK(!FLAG_vector_ics);
// This stub tail calls, and an erected frame presents complications we don't
// need.
info()->MarkMustNotHaveEagerFrame();
// Probe the stub cache.
Add<HTailCallThroughMegamorphicCache>(receiver, name);
// We never continue.
return graph()->GetConstant0();
}
} } // namespace v8::internal

View File

@ -618,10 +618,7 @@ void HandlerStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() {
if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
if (FLAG_vector_ics) {
return VectorLoadICDescriptor(isolate());
}
return LoadDescriptor(isolate());
return VectorLoadICDescriptor(isolate());
} else {
DCHECK_EQ(Code::STORE_IC, kind());
return StoreDescriptor(isolate());
@ -646,9 +643,6 @@ CallInterfaceDescriptor StoreTransitionStub::GetCallInterfaceDescriptor() {
}
void MegamorphicLoadStub::InitializeDescriptor(CodeStubDescriptor* d) {}
void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry);

View File

@ -76,7 +76,6 @@ namespace internal {
V(KeyedLoadGeneric) \
V(LoadScriptContextField) \
V(LoadDictionaryElement) \
V(MegamorphicLoad) \
V(NameDictionaryLookup) \
V(NumberToString) \
V(Typeof) \
@ -987,10 +986,7 @@ class FunctionPrototypeStub : public PlatformCodeStub {
// translated to a hydrogen code stub, a new CallInterfaceDescriptor
// should be created that just uses that register for more efficient code.
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
if (FLAG_vector_ics) {
return VectorLoadICDescriptor(isolate());
}
return LoadDescriptor(isolate());
return VectorLoadICDescriptor(isolate());
}
DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
@ -2081,10 +2077,7 @@ class LoadDictionaryElementStub : public HydrogenCodeStub {
: HydrogenCodeStub(isolate) {}
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
if (FLAG_vector_ics) {
return VectorLoadICDescriptor(isolate());
}
return LoadDescriptor(isolate());
return VectorLoadICDescriptor(isolate());
}
DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
@ -2178,32 +2171,6 @@ class CallIC_ArrayTrampolineStub : public CallICTrampolineStub {
};
class MegamorphicLoadStub : public HydrogenCodeStub {
public:
MegamorphicLoadStub(Isolate* isolate, const LoadICState& state)
: HydrogenCodeStub(isolate) {
set_sub_minor_key(state.GetExtraICState());
}
Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
InlineCacheState GetICState() const final { return MEGAMORPHIC; }
ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(sub_minor_key());
}
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
if (FLAG_vector_ics) {
return VectorLoadICDescriptor(isolate());
}
return LoadDescriptor(isolate());
}
DEFINE_HYDROGEN_CODE_STUB(MegamorphicLoad, HydrogenCodeStub);
};
class VectorRawLoadStub : public PlatformCodeStub {
public:
explicit VectorRawLoadStub(Isolate* isolate, const LoadICState& state)

View File

@ -343,11 +343,8 @@ void JSGenericLowering::LowerJSLoadProperty(Node* node) {
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
Callable callable =
CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
if (FLAG_vector_ics) {
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 3, jsgraph()->HeapConstant(p.feedback().vector()));
ReplaceWithStubCall(node, callable,
CallDescriptor::kPatchableCallSite | flags);
}
@ -362,11 +359,8 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
UNINITIALIZED)
: CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_ics) {
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 3, jsgraph()->HeapConstant(p.feedback().vector()));
ReplaceWithStubCall(node, callable,
CallDescriptor::kPatchableCallSite | flags);
}

View File

@ -260,7 +260,6 @@ DEFINE_BOOL(track_field_types, true, "track field types")
DEFINE_IMPLICATION(track_field_types, track_fields)
DEFINE_IMPLICATION(track_field_types, track_heap_object_fields)
DEFINE_BOOL(smi_binop, true, "support smi representation in binary operations")
DEFINE_BOOL(vector_ics, true, "support vector-based ics")
// Flags for optimization types.
DEFINE_BOOL(optimize_for_size, false,

View File

@ -445,13 +445,7 @@ void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
void FullCodeGenerator::CallGlobalLoadIC(Handle<String> name) {
if (masm()->serializer_enabled() || FLAG_vector_ics) {
// Vector-ICs don't work with LoadGlobalIC.
return CallLoadIC(CONTEXTUAL);
}
Handle<Code> ic = CodeFactory::LoadGlobalIC(
isolate(), isolate()->global_object(), name).code();
CallIC(ic, TypeFeedbackId::None());
return CallLoadIC(CONTEXTUAL);
}

View File

@ -3135,17 +3135,13 @@ 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, 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());
}
FeedbackVectorSpec spec(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);
set_detached_contexts(empty_fixed_array());
set_retained_maps(ArrayList::cast(empty_fixed_array()));

View File

@ -837,7 +837,6 @@ bool HInstruction::CanDeoptimize() {
case HValue::kStoreNamedGeneric:
case HValue::kStringCharCodeAt:
case HValue::kStringCharFromCode:
case HValue::kTailCallThroughMegamorphicCache:
case HValue::kThisFunction:
case HValue::kTypeofIsAndBranch:
case HValue::kUnknownOSRValue:
@ -1717,22 +1716,6 @@ std::ostream& HCallStub::PrintDataTo(std::ostream& os) const { // NOLINT
}
Code::Flags HTailCallThroughMegamorphicCache::flags() const {
Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
Code::ComputeHandlerFlags(Code::LOAD_IC));
return code_flags;
}
std::ostream& HTailCallThroughMegamorphicCache::PrintDataTo(
std::ostream& os) const { // NOLINT
for (int i = 0; i < OperandCount(); i++) {
os << NameOf(OperandAt(i)) << " ";
}
return os << "flags: " << flags();
}
std::ostream& HUnknownOSRValue::PrintDataTo(std::ostream& os) const { // NOLINT
const char* type = "expression";
if (environment_->is_local_index(index_)) type = "local";

View File

@ -156,7 +156,6 @@ class LChunkBuilder;
V(StringCharFromCode) \
V(StringCompareAndBranch) \
V(Sub) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -5353,44 +5352,6 @@ class HCallStub final : public HUnaryCall {
};
class HTailCallThroughMegamorphicCache final : public HInstruction {
public:
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HTailCallThroughMegamorphicCache,
HValue*, HValue*);
Representation RequiredInputRepresentation(int index) override {
return Representation::Tagged();
}
virtual int OperandCount() const final override { return 3; }
virtual HValue* OperandAt(int i) const final override { return inputs_[i]; }
HValue* context() const { return OperandAt(0); }
HValue* receiver() const { return OperandAt(1); }
HValue* name() const { return OperandAt(2); }
Code::Flags flags() const;
std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache)
protected:
virtual void InternalSetOperandAt(int i, HValue* value) final override {
inputs_[i] = value;
}
private:
HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver,
HValue* name) {
SetOperandAt(0, context);
SetOperandAt(1, receiver);
SetOperandAt(2, name);
}
EmbeddedContainer<HValue*, 3> inputs_;
};
class HUnknownOSRValue final : public HTemplateInstruction<0> {
public:
DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int);
@ -5440,10 +5401,9 @@ class HLoadGlobalGeneric final : public HTemplateInstruction<2> {
Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_;
}
bool HasVectorAndSlot() const { return FLAG_vector_ics; }
bool HasVectorAndSlot() const { return true; }
void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot) {
DCHECK(FLAG_vector_ics);
feedback_vector_ = vector;
slot_ = slot;
}
@ -6448,10 +6408,9 @@ class HLoadNamedGeneric final : public HTemplateInstruction<2> {
Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_;
}
bool HasVectorAndSlot() const { return FLAG_vector_ics; }
bool HasVectorAndSlot() const { return true; }
void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot) {
DCHECK(FLAG_vector_ics);
feedback_vector_ = vector;
slot_ = slot;
}
@ -6731,13 +6690,11 @@ class HLoadKeyedGeneric final : public HTemplateInstruction<3> {
return feedback_vector_;
}
bool HasVectorAndSlot() const {
DCHECK(!FLAG_vector_ics || initialization_state_ == MEGAMORPHIC ||
!feedback_vector_.is_null());
DCHECK(initialization_state_ == MEGAMORPHIC || !feedback_vector_.is_null());
return !feedback_vector_.is_null();
}
void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot) {
DCHECK(FLAG_vector_ics);
feedback_vector_ = vector;
slot_ = slot;
}

View File

@ -5491,10 +5491,8 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
New<HLoadGlobalGeneric>(global_object,
variable->name(),
ast_context()->is_for_typeof());
if (FLAG_vector_ics) {
instr->SetVectorAndSlot(handle(current_feedback_vector(), isolate()),
expr->VariableFeedbackSlot());
}
instr->SetVectorAndSlot(handle(current_feedback_vector(), isolate()),
expr->VariableFeedbackSlot());
return ast_context()->ReturnInstruction(instr, expr->id());
}
}
@ -7018,29 +7016,26 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
Deoptimizer::SOFT);
}
if (access_type == LOAD) {
if (FLAG_vector_ics) {
Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate());
FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate());
FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
if (!expr->AsProperty()->key()->IsPropertyName()) {
// It's possible that a keyed load of a constant string was converted
// to a named load. Here, at the last minute, we need to make sure to
// use a generic Keyed Load if we are using the type vector, because
// it has to share information with full code.
HConstant* key = Add<HConstant>(name);
HLoadKeyedGeneric* result =
New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
}
HLoadNamedGeneric* result =
New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC);
if (!expr->AsProperty()->key()->IsPropertyName()) {
// It's possible that a keyed load of a constant string was converted
// to a named load. Here, at the last minute, we need to make sure to
// use a generic Keyed Load if we are using the type vector, because
// it has to share information with full code.
HConstant* key = Add<HConstant>(name);
HLoadKeyedGeneric* result =
New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
}
return New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC);
HLoadNamedGeneric* result =
New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC);
result->SetVectorAndSlot(vector, slot);
return result;
} else {
return New<HStoreNamedGeneric>(object, name, value,
function_language_mode(), PREMONOMORPHIC);
@ -7056,14 +7051,12 @@ HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
HValue* key,
HValue* value) {
if (access_type == LOAD) {
InlineCacheState initial_state =
FLAG_vector_ics ? expr->AsProperty()->GetInlineCacheState()
: PREMONOMORPHIC;
InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState();
HLoadKeyedGeneric* result =
New<HLoadKeyedGeneric>(object, key, initial_state);
// HLoadKeyedGeneric with vector ics benefits from being encoded as
// MEGAMORPHIC because the vector/slot combo becomes unnecessary.
if (FLAG_vector_ics && initial_state != MEGAMORPHIC) {
if (initial_state != MEGAMORPHIC) {
// We need to pass vector information.
Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate());

View File

@ -653,19 +653,14 @@ void MathPowStub::Generate(MacroAssembler* masm) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver = LoadDescriptor::ReceiverRegister();
if (FLAG_vector_ics) {
// With careful management, we won't have to save slot and vector on
// the stack. Simply handle the possibly missing case first.
// TODO(mvstanton): this code can be more efficient.
__ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
Immediate(isolate()->factory()->the_hole_value()));
__ j(equal, &miss);
__ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
__ ret(0);
} else {
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
ebx, &miss);
}
// With careful management, we won't have to save slot and vector on
// the stack. Simply handle the possibly missing case first.
// TODO(mvstanton): this code can be more efficient.
__ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
Immediate(isolate()->factory()->the_hole_value()));
__ j(equal, &miss);
__ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
__ ret(0);
__ bind(&miss);
PropertyAccessCompiler::TailCallBuiltin(
@ -713,9 +708,8 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
DCHECK(!scratch.is(receiver) && !scratch.is(index));
Register result = eax;
DCHECK(!result.is(scratch));
DCHECK(!FLAG_vector_ics ||
(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister())));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister()));
// StringCharAtGenerator doesn't use the result register until it's passed
// the different miss possibilities. If it did, we would have a conflict
@ -2974,7 +2968,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
index_not_number_,
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ push(VectorLoadICDescriptor::VectorRegister());
__ push(VectorLoadICDescriptor::SlotRegister());
}
@ -2993,7 +2987,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
__ mov(index_, eax);
}
__ pop(object_);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ pop(VectorLoadICDescriptor::SlotRegister());
__ pop(VectorLoadICDescriptor::VectorRegister());
}

View File

@ -183,10 +183,8 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-ia32.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.bit() | name.bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
}
RegList regs = receiver.bit() | name.bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().bit();
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}

View File

@ -1259,13 +1259,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ mov(LoadDescriptor::NameRegister(), home_object_symbol);
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
__ cmp(eax, isolate()->factory()->undefined_value());
Label done;
@ -1340,10 +1336,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
// load IC call.
__ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
@ -1428,10 +1422,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "[ Global variable");
__ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), var->name());
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
CallGlobalLoadIC(var->name());
context()->Plug(eax);
break;
@ -2125,10 +2117,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result = receiver[f](arg);
__ bind(&l_call);
__ mov(load_receiver, Operand(esp, kPointerSize));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
@ -2145,10 +2135,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Move(load_receiver, eax); // result
__ mov(load_name,
isolate()->factory()->done_string()); // "done"
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
@ -2159,10 +2147,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ pop(load_receiver); // result
__ mov(load_name,
isolate()->factory()->value_string()); // "value"
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
context()->DropAndPlug(2, eax); // drop iter and g
break;
@ -2300,13 +2286,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2325,13 +2307,9 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
}
@ -4553,13 +4531,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
__ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -4998,10 +4972,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "[ Global variable");
__ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
if (FLAG_vector_ics) {
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ mov(VectorLoadICDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);

View File

@ -2868,7 +2868,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -2891,9 +2890,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(eax));
__ mov(LoadDescriptor::NameRegister(), instr->name());
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3010,9 +3007,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(eax));
__ mov(LoadDescriptor::NameRegister(), instr->name());
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
@ -3485,27 +3480,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
Register scratch = ebx;
Register extra = edi;
DCHECK(!scratch.is(receiver) && !scratch.is(name));
DCHECK(!extra.is(receiver) && !extra.is(name));
// The probe will tail call to a handler if found.
// If --vector-ics is on, then it knows to pop the two args first.
isolate()->stub_cache()->GenerateProbe(masm(), Code::LOAD_IC,
instr->hydrogen()->flags(), false,
receiver, name, scratch, extra);
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(ToRegister(instr->result()).is(eax));

View File

@ -1146,20 +1146,6 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), esi);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), esi);
LOperand* function = UseFixed(instr->function(), edi);

View File

@ -155,7 +155,6 @@ class LCodeGen;
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -470,26 +469,6 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -55,11 +55,9 @@ class PropertyAccessCompiler BASE_EMBEDDED {
Register receiver() const { return registers_[0]; }
Register name() const { return registers_[1]; }
Register slot() const {
DCHECK(FLAG_vector_ics);
return VectorLoadICDescriptor::SlotRegister();
}
Register vector() const {
DCHECK(FLAG_vector_ics);
return VectorLoadICDescriptor::VectorRegister();
}
Register scratch1() const { return registers_[2]; }

View File

@ -289,14 +289,10 @@ static const Register LoadIC_TempRegister() { return r3; }
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
if (FLAG_vector_ics) {
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
__ Push(receiver, name, slot, vector);
} else {
__ Push(receiver, name);
}
__ Push(receiver, name, slot, vector);
}
@ -304,8 +300,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in lr.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->load_miss(), 1, r4, r5);
@ -313,7 +308,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -441,8 +436,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in lr.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5);
@ -451,7 +445,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -527,20 +521,16 @@ 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)));
}
// 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));

View File

@ -368,22 +368,17 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
Isolate* isolate = masm->isolate();
ASM_LOCATION("LoadIC::GenerateMiss");
DCHECK(!FLAG_vector_ics ||
!AreAliased(x4, x5, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(x4, x5, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->load_miss(), 1, x4, x5);
// Perform tail call to the entry.
if (FLAG_vector_ics) {
__ Push(VectorLoadICDescriptor::ReceiverRegister(),
VectorLoadICDescriptor::NameRegister(),
VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister());
} else {
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
}
__ Push(VectorLoadICDescriptor::ReceiverRegister(),
VectorLoadICDescriptor::NameRegister(),
VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister());
ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -445,24 +440,19 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in lr.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(x10, x11, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(x10, x11, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11);
if (FLAG_vector_ics) {
__ Push(VectorLoadICDescriptor::ReceiverRegister(),
VectorLoadICDescriptor::NameRegister(),
VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister());
} else {
__ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
}
__ Push(VectorLoadICDescriptor::ReceiverRegister(),
VectorLoadICDescriptor::NameRegister(),
VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister());
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -533,19 +523,16 @@ 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)));
}
// 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));

View File

@ -130,10 +130,9 @@ void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
MacroAssembler* masm, Register receiver, Register scratch1,
Register scratch2, Label* miss_label) {
DCHECK(!FLAG_vector_ics);
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
__ mov(eax, scratch1);
__ ret(0);
// TODO(mvstanton): This isn't used on ia32. Move all the other
// platform implementations into a code stub so this method can be removed.
UNREACHABLE();
}

View File

@ -399,26 +399,21 @@ 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));
}
// 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::KEYED_LOAD_IC, flags,
false, receiver, key, ebx, edi);
if (FLAG_vector_ics) {
__ pop(VectorLoadICDescriptor::VectorRegister());
__ pop(VectorLoadICDescriptor::SlotRegister());
}
__ pop(VectorLoadICDescriptor::VectorRegister());
__ pop(VectorLoadICDescriptor::SlotRegister());
// Cache miss.
GenerateMiss(masm);
@ -733,26 +728,18 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
if (FLAG_vector_ics) {
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
DCHECK(!edi.is(receiver) && !edi.is(name) && !edi.is(slot) &&
!edi.is(vector));
__ pop(edi);
__ push(receiver);
__ push(name);
__ push(slot);
__ push(vector);
__ push(edi);
} else {
DCHECK(!ebx.is(receiver) && !ebx.is(name));
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
DCHECK(!edi.is(receiver) && !edi.is(name) && !edi.is(slot) &&
!edi.is(vector));
__ pop(ebx);
__ push(receiver);
__ push(name);
__ push(ebx);
}
__ pop(edi);
__ push(receiver);
__ push(name);
__ push(slot);
__ push(vector);
__ push(edi);
}
@ -764,7 +751,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -794,7 +781,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}

View File

@ -87,26 +87,6 @@ Handle<Code> PropertyICCompiler::ComputeMonomorphic(
}
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
Handle<Map> receiver_map) {
Isolate* isolate = receiver_map->GetIsolate();
DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
if (probe->IsCode()) return Handle<Code>::cast(probe);
Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map);
PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
Handle<Code> code = compiler.CompileMonomorphic(
receiver_map, stub, isolate->factory()->empty_string(), ELEMENT);
Map::UpdateCodeCache(receiver_map, name, code);
return code;
}
Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
Handle<Map> receiver_map) {
Isolate* isolate = receiver_map->GetIsolate();
@ -189,31 +169,6 @@ static void FillCache(Isolate* isolate, Handle<Code> code) {
}
Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
InlineCacheState ic_state,
ExtraICState extra_state) {
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
Handle<UnseededNumberDictionary> cache =
isolate->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
PropertyICCompiler compiler(isolate, Code::LOAD_IC);
Handle<Code> code;
if (ic_state == UNINITIALIZED) {
code = compiler.CompileLoadInitialize(flags);
} else if (ic_state == PREMONOMORPHIC) {
code = compiler.CompileLoadPreMonomorphic(flags);
} else if (ic_state == MEGAMORPHIC) {
code = compiler.CompileLoadMegamorphic(flags);
} else {
UNREACHABLE();
}
FillCache(isolate, code);
return code;
}
Handle<Code> PropertyICCompiler::ComputeStore(Isolate* isolate,
InlineCacheState ic_state,
ExtraICState extra_state) {
@ -334,23 +289,6 @@ Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) {
}
Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
LoadIC::GeneratePreMonomorphic(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
PROFILE(isolate(),
CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
return code;
}
Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state_));
auto code = stub.GetCode();
PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
return code;
}
Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
StoreIC::GenerateInitialize(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");

View File

@ -18,8 +18,6 @@ class PropertyICCompiler : public PropertyAccessCompiler {
ExtraICState extra_ic_state);
// Named
static Handle<Code> ComputeLoad(Isolate* isolate, InlineCacheState ic_state,
ExtraICState extra_state);
static Handle<Code> ComputeStore(Isolate* isolate, InlineCacheState ic_state,
ExtraICState extra_state);
@ -35,7 +33,6 @@ class PropertyICCompiler : public PropertyAccessCompiler {
// Keyed
static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
Handle<Map> receiver_map);
static Handle<Code> ComputeKeyedLoadMonomorphic(Handle<Map> receiver_map);
static Handle<Code> ComputeKeyedStoreMonomorphic(
Handle<Map> receiver_map, LanguageMode language_mode,
@ -69,8 +66,6 @@ class PropertyICCompiler : public PropertyAccessCompiler {
CacheHolderFlag cache_holder = kCacheOnReceiver);
Handle<Code> CompileLoadInitialize(Code::Flags flags);
Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags);
Handle<Code> CompileLoadMegamorphic(Code::Flags flags);
Handle<Code> CompileStoreInitialize(Code::Flags flags);
Handle<Code> CompileStorePreMonomorphic(Code::Flags flags);
Handle<Code> CompileStoreGeneric(Code::Flags flags);

View File

@ -98,7 +98,7 @@ void IC::SetTargetAtAddress(Address address, Code* target,
DCHECK(target->is_inline_cache_stub() || target->is_compare_ic_stub());
// Don't use this for load_ics when --vector-ics is turned on.
DCHECK(!(FLAG_vector_ics && target->is_inline_cache_stub()) ||
DCHECK(!target->is_inline_cache_stub() ||
(target->kind() != Code::LOAD_IC &&
target->kind() != Code::KEYED_LOAD_IC));

View File

@ -495,11 +495,8 @@ void IC::Clear(Isolate* isolate, Address address,
switch (target->kind()) {
case Code::LOAD_IC:
if (FLAG_vector_ics) return;
return LoadIC::Clear(isolate, address, target, constant_pool);
case Code::KEYED_LOAD_IC:
if (FLAG_vector_ics) return;
return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
return;
case Code::STORE_IC:
return StoreIC::Clear(isolate, address, target, constant_pool);
case Code::KEYED_STORE_IC:
@ -520,18 +517,6 @@ void IC::Clear(Isolate* isolate, Address address,
}
void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
ConstantPoolArray* constant_pool) {
DCHECK(!FLAG_vector_ics);
if (IsCleared(target)) return;
// Make sure to also clear the map used in inline fast cases. If we
// do not clear these maps, cached code can keep objects alive
// through the embedded maps.
SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool);
}
void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) {
if (IsCleared(nexus)) return;
// Make sure to also clear the map used in inline fast cases. If we
@ -556,16 +541,6 @@ void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
}
void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
ConstantPoolArray* constant_pool) {
DCHECK(!FLAG_vector_ics);
if (IsCleared(target)) return;
Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
target->extra_ic_state());
SetTargetAtAddress(address, code, constant_pool);
}
void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
if (IsCleared(nexus)) return;
State state = nexus->StateFromFeedback();
@ -941,78 +916,29 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
ExtraICState extra_state) {
if (FLAG_vector_ics) {
return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
}
return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state);
}
Handle<Code> LoadIC::load_global(Isolate* isolate, Handle<GlobalObject> global,
Handle<String> name) {
// This special IC doesn't work with vector ics.
DCHECK(!FLAG_vector_ics);
Handle<ScriptContextTable> script_contexts(
global->native_context()->script_context_table());
ScriptContextTable::LookupResult lookup_result;
if (ScriptContextTable::Lookup(script_contexts, name, &lookup_result)) {
return initialize_stub(isolate, LoadICState(CONTEXTUAL).GetExtraICState());
}
Handle<Map> global_map(global->map());
Handle<Code> handler = PropertyHandlerCompiler::Find(
name, global_map, Code::LOAD_IC, kCacheOnReceiver, Code::NORMAL);
if (handler.is_null()) {
LookupIterator it(global, name);
if (!it.IsFound() || !it.GetHolder<JSObject>().is_identical_to(global) ||
it.state() != LookupIterator::DATA) {
return initialize_stub(isolate,
LoadICState(CONTEXTUAL).GetExtraICState());
}
NamedLoadHandlerCompiler compiler(isolate, global_map, global,
kCacheOnReceiver);
Handle<PropertyCell> cell = it.GetPropertyCell();
handler = compiler.CompileLoadGlobal(cell, name, it.IsConfigurable());
Map::UpdateCodeCache(global_map, name, handler);
}
return PropertyICCompiler::ComputeMonomorphic(
Code::LOAD_IC, name, handle(global->map()), handler,
LoadICState(CONTEXTUAL).GetExtraICState());
return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
}
Handle<Code> LoadIC::initialize_stub_in_optimized_code(
Isolate* isolate, ExtraICState extra_state, State initialization_state) {
if (FLAG_vector_ics) {
return VectorRawLoadStub(isolate, LoadICState(extra_state)).GetCode();
}
return PropertyICCompiler::ComputeLoad(isolate, initialization_state,
extra_state);
return VectorRawLoadStub(isolate, LoadICState(extra_state)).GetCode();
}
Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
if (FLAG_vector_ics) {
return KeyedLoadICTrampolineStub(isolate).GetCode();
}
return isolate->builtins()->KeyedLoadIC_Initialize();
return KeyedLoadICTrampolineStub(isolate).GetCode();
}
Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
Isolate* isolate, State initialization_state) {
if (FLAG_vector_ics && initialization_state != MEGAMORPHIC) {
if (initialization_state != MEGAMORPHIC) {
return VectorRawKeyedLoadStub(isolate).GetCode();
}
switch (initialization_state) {
case UNINITIALIZED:
return isolate->builtins()->KeyedLoadIC_Initialize();
case PREMONOMORPHIC:
return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
case MEGAMORPHIC:
return isolate->builtins()->KeyedLoadIC_Megamorphic();
default:
@ -1046,35 +972,8 @@ Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate,
Handle<Code> LoadIC::megamorphic_stub() {
if (kind() == Code::LOAD_IC) {
MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state()));
return stub.GetCode();
} else {
DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
return KeyedLoadIC::ChooseMegamorphicStub(isolate());
}
}
Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
ExtraICState extra_state) {
DCHECK(!FLAG_vector_ics);
return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
}
Handle<Code> KeyedLoadIC::pre_monomorphic_stub(Isolate* isolate) {
return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
}
Handle<Code> LoadIC::pre_monomorphic_stub() const {
if (kind() == Code::LOAD_IC) {
return LoadIC::pre_monomorphic_stub(isolate(), extra_ic_state());
} else {
DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
return KeyedLoadIC::pre_monomorphic_stub(isolate());
}
DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
return KeyedLoadIC::ChooseMegamorphicStub(isolate());
}
@ -1088,11 +987,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
if (state() == UNINITIALIZED) {
// This is the first time we execute this inline cache. Set the target to
// the pre monomorphic stub to delay setting the monomorphic state.
if (UseVector()) {
ConfigureVectorState(PREMONOMORPHIC);
} else {
set_target(*pre_monomorphic_stub());
}
ConfigureVectorState(PREMONOMORPHIC);
TRACE_IC("LoadIC", lookup->name());
return;
}
@ -1360,13 +1255,10 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
if (target_receiver_maps.length() == 0) {
if (FLAG_vector_ics) {
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
// The first time a receiver is seen that is a transitioned version of the
@ -1380,13 +1272,10 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
IsMoreGeneralElementsKindTransition(
target_receiver_maps.at(0)->elements_kind(),
Handle<JSObject>::cast(receiver)->GetElementsKind())) {
if (FLAG_vector_ics) {
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
Handle<Code> handler =
PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
return null_handle;
}
DCHECK(state() != GENERIC);
@ -1407,16 +1296,11 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
return megamorphic_stub();
}
if (FLAG_vector_ics) {
CodeHandleList handlers(target_receiver_maps.length());
ElementHandlerCompiler compiler(isolate());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps,
&handlers);
return null_handle;
}
return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
CodeHandleList handlers(target_receiver_maps.length());
ElementHandlerCompiler compiler(isolate());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, &handlers);
return null_handle;
}
@ -2369,31 +2253,22 @@ RUNTIME_FUNCTION(LoadIC_Miss) {
Handle<Name> key = args.at<Name>(1);
Handle<Object> result;
if (FLAG_vector_ics) {
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
// LoadIC miss handler if the handler misses. Since the vector Nexus is
// set up outside the IC, handle that here.
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
LoadICNexus nexus(vector, vector_slot);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
ic.Load(receiver, key));
} else {
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
ic.Load(receiver, key));
}
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
// LoadIC miss handler if the handler misses. Since the vector Nexus is
// set up outside the IC, handle that here.
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
LoadICNexus nexus(vector, vector_slot);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
} else {
DCHECK(args.length() == 2);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
}
@ -2409,22 +2284,14 @@ RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> result;
if (FLAG_vector_ics) {
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
} else {
DCHECK(args.length() == 2);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
}
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
return *result;
}
@ -2436,21 +2303,14 @@ RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> result;
if (FLAG_vector_ics) {
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
} else {
DCHECK(args.length() == 2);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
}
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
return *result;
}
@ -3018,31 +2878,22 @@ RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) {
Handle<Name> key = args.at<Name>(1);
Handle<Object> result;
if (FLAG_vector_ics) {
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
// LoadIC miss handler if the handler misses. Since the vector Nexus is
// set up outside the IC, handle that here.
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
LoadICNexus nexus(vector, vector_slot);
LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
ic.Load(receiver, key));
} else {
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
ic.Load(receiver, key));
}
DCHECK(args.length() == 4);
Handle<Smi> slot = args.at<Smi>(2);
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
// LoadIC miss handler if the handler misses. Since the vector Nexus is
// set up outside the IC, handle that here.
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
LoadICNexus nexus(vector, vector_slot);
LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
} else {
DCHECK(args.length() == 2);
LoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, vector_slot);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
ic.UpdateState(receiver, key);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
}

View File

@ -114,8 +114,7 @@ class IC {
}
static bool ICUseVector(Code::Kind kind) {
return (FLAG_vector_ics &&
(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) ||
return kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
kind == Code::CALL_IC;
}
@ -362,7 +361,7 @@ class LoadIC : public IC {
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) {
DCHECK(!FLAG_vector_ics || nexus != NULL);
DCHECK(nexus != NULL);
DCHECK(IsLoadStub());
}
@ -388,9 +387,6 @@ class LoadIC : public IC {
// Code generator routines.
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GeneratePreMonomorphic(MacroAssembler* masm) {
GenerateMiss(masm);
}
static void GenerateMiss(MacroAssembler* masm);
static void GenerateNormal(MacroAssembler* masm);
static void GenerateRuntimeGetProperty(MacroAssembler* masm);
@ -399,8 +395,6 @@ class LoadIC : public IC {
ExtraICState extra_state);
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, ExtraICState extra_state, State initialization_state);
static Handle<Code> load_global(Isolate* isolate, Handle<GlobalObject> global,
Handle<String> name);
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
Handle<Name> name);
@ -430,10 +424,6 @@ class LoadIC : public IC {
CacheHolderFlag cache_holder) override;
private:
virtual Handle<Code> pre_monomorphic_stub() const;
static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
ExtraICState extra_state);
Handle<Code> SimpleFieldLoad(FieldIndex index);
static void Clear(Isolate* isolate, Address address, Code* target,
@ -461,7 +451,7 @@ class KeyedLoadIC : public LoadIC {
KeyedLoadIC(FrameDepth depth, Isolate* isolate,
KeyedLoadICNexus* nexus = NULL)
: LoadIC(depth, isolate, nexus) {
DCHECK(!FLAG_vector_ics || nexus != NULL);
DCHECK(nexus != NULL);
DCHECK(target()->is_keyed_load_stub());
}
@ -472,9 +462,6 @@ class KeyedLoadIC : public LoadIC {
static void GenerateMiss(MacroAssembler* masm);
static void GenerateRuntimeGetProperty(MacroAssembler* masm);
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GeneratePreMonomorphic(MacroAssembler* masm) {
GenerateMiss(masm);
}
static void GenerateMegamorphic(MacroAssembler* masm);
// Bit mask to be tested against bit field for the cases when
@ -488,16 +475,12 @@ class KeyedLoadIC : public LoadIC {
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, State initialization_state);
static Handle<Code> ChooseMegamorphicStub(Isolate* isolate);
static Handle<Code> pre_monomorphic_stub(Isolate* isolate);
static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);
protected:
// receiver is HeapObject because it could be a String or a JSObject
Handle<Code> LoadElementStub(Handle<HeapObject> receiver);
virtual Handle<Code> pre_monomorphic_stub() const {
return pre_monomorphic_stub(isolate());
}
private:
static void Clear(Isolate* isolate, Address address, Code* target,

View File

@ -296,14 +296,10 @@ static const Register LoadIC_TempRegister() { return a3; }
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
if (FLAG_vector_ics) {
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
__ Push(receiver, name, slot, vector);
} else {
__ Push(receiver, name);
}
__ Push(receiver, name, slot, vector);
}
@ -311,8 +307,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in ra.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->load_miss(), 1, t0, t1);
@ -320,7 +315,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -450,8 +445,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in ra.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1);
@ -461,7 +455,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -536,19 +530,16 @@ 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)));
}
// 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));

View File

@ -294,14 +294,10 @@ static const Register LoadIC_TempRegister() { return a3; }
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
if (FLAG_vector_ics) {
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
__ Push(receiver, name, slot, vector);
} else {
__ Push(receiver, name);
}
__ Push(receiver, name, slot, vector);
}
@ -309,8 +305,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is on the stack.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->load_miss(), 1, a4, a5);
@ -318,7 +313,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -448,8 +443,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// The return address is in ra.
Isolate* isolate = masm->isolate();
DCHECK(!FLAG_vector_ics ||
!AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
DCHECK(!AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
VectorLoadICDescriptor::VectorRegister()));
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a4, a5);
@ -459,7 +453,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -534,19 +528,16 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
__ LoadRoot(at, Heap::kHashTableMapRootIndex);
__ Branch(&probe_dictionary, eq, a4, 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, a4, a5, a6, t1));
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)));
}
// 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, a4, a5, a6, t1));
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));

View File

@ -333,19 +333,16 @@ void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
__ 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));
}
// 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));
@ -737,26 +734,17 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
static void LoadIC_PushArgs(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
if (FLAG_vector_ics) {
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
DCHECK(!rdi.is(receiver) && !rdi.is(name) && !rdi.is(slot) &&
!rdi.is(vector));
Register slot = VectorLoadICDescriptor::SlotRegister();
Register vector = VectorLoadICDescriptor::VectorRegister();
DCHECK(!rdi.is(receiver) && !rdi.is(name) && !rdi.is(slot) &&
!rdi.is(vector));
__ PopReturnAddressTo(rdi);
__ Push(receiver);
__ Push(name);
__ Push(slot);
__ Push(vector);
__ PushReturnAddressFrom(rdi);
} else {
DCHECK(!rbx.is(receiver) && !rbx.is(name));
__ PopReturnAddressTo(rbx);
__ Push(receiver);
__ Push(name);
__ PushReturnAddressFrom(rbx);
}
__ PopReturnAddressTo(rdi);
__ Push(receiver);
__ Push(name);
__ Push(slot);
__ Push(vector);
__ PushReturnAddressFrom(rdi);
}
@ -771,7 +759,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}
@ -802,7 +790,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// Perform tail call to the entry.
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
int arg_count = FLAG_vector_ics ? 4 : 2;
int arg_count = 4;
__ TailCallExternalReference(ref, arg_count, 1);
}

View File

@ -1386,8 +1386,7 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
Register scratch = t1;
Register result = v0;
DCHECK(!scratch.is(receiver) && !scratch.is(index));
DCHECK(!FLAG_vector_ics ||
!scratch.is(VectorLoadICDescriptor::VectorRegister()));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()));
StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
&miss, // When not a string.
@ -1611,8 +1610,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
// Ensure that the vector and slot registers won't be clobbered before
// calling the miss handler.
DCHECK(!FLAG_vector_ics ||
!AreAliased(t0, t1, VectorLoadICDescriptor::VectorRegister(),
DCHECK(!AreAliased(t0, t1, VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister()));
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, t0,
@ -3092,7 +3090,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
// Consumed by runtime conversion function:
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Push(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_, index_);
} else {
@ -3109,7 +3107,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
__ Move(index_, v0);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Pop(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_);
} else {

View File

@ -153,10 +153,8 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.bit() | name.bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
}
RegList regs = receiver.bit() | name.bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}

View File

@ -1321,13 +1321,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ li(LoadDescriptor::NameRegister(), home_object_symbol);
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
Label done;
__ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
@ -1396,10 +1392,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
__ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
@ -1486,10 +1480,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "[ Global variable");
__ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
CallGlobalLoadIC(var->name());
context()->Plug(v0);
break;
@ -2186,10 +2178,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_call);
__ lw(load_receiver, MemOperand(sp, kPointerSize));
__ lw(load_name, MemOperand(sp, 2 * kPointerSize));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
@ -2206,10 +2196,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
__ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@ -2219,10 +2207,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result.value
__ pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
context()->DropAndPlug(2, v0); // drop iter and g
break;
@ -2363,13 +2349,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2388,13 +2370,9 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
}
@ -4634,13 +4612,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -5075,10 +5049,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "[ Global variable");
__ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);

View File

@ -2907,7 +2907,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -2930,9 +2929,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(v0));
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3033,9 +3030,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
@ -3952,30 +3947,6 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
DCHECK(receiver.is(a1));
DCHECK(name.is(a2));
Register scratch = t0;
Register extra = t1;
Register extra2 = t2;
Register extra3 = t5;
// The probe will tail call to a handler if found.
isolate()->stub_cache()->GenerateProbe(
masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name,
scratch, extra, extra2, extra3);
// Tail call to miss if we ended up here.
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(ToRegister(instr->result()).is(v0));

View File

@ -1110,20 +1110,6 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), a1);

View File

@ -152,7 +152,6 @@ class LCodeGen;
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -472,26 +471,6 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -1386,8 +1386,7 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
Register scratch = a5;
Register result = v0;
DCHECK(!scratch.is(receiver) && !scratch.is(index));
DCHECK(!FLAG_vector_ics ||
!scratch.is(VectorLoadICDescriptor::VectorRegister()));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()));
StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
&miss, // When not a string.
@ -1611,8 +1610,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
// Ensure that the vector and slot registers won't be clobbered before
// calling the miss handler.
DCHECK(!FLAG_vector_ics ||
!AreAliased(a4, a5, VectorLoadICDescriptor::VectorRegister(),
DCHECK(!AreAliased(a4, a5, VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister()));
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a4,
@ -3131,7 +3129,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
// Consumed by runtime conversion function:
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Push(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_, index_);
} else {
@ -3149,7 +3147,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
// have a chance to overwrite it.
__ Move(index_, v0);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Pop(VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister(), object_);
} else {

View File

@ -156,10 +156,8 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.bit() | name.bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
}
RegList regs = receiver.bit() | name.bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}

View File

@ -1318,13 +1318,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ li(LoadDescriptor::NameRegister(), home_object_symbol);
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
Label done;
__ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
@ -1393,10 +1389,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
__ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
@ -1485,10 +1479,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// object (receiver) in a0.
__ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
CallGlobalLoadIC(var->name());
context()->Plug(v0);
break;
@ -2183,10 +2175,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_call);
__ ld(load_receiver, MemOperand(sp, kPointerSize));
__ ld(load_name, MemOperand(sp, 2 * kPointerSize));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
@ -2203,10 +2193,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
__ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@ -2216,10 +2204,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result.value
__ pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
context()->DropAndPlug(2, v0); // drop iter and g
break;
@ -2362,13 +2348,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2388,13 +2370,9 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has register arguments receiver and key.
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
CallIC(ic);
}
@ -4638,13 +4616,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -5078,10 +5052,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "[ Global variable");
__ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
if (FLAG_vector_ics) {
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
}
__ li(VectorLoadICDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);

View File

@ -2906,7 +2906,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -2929,9 +2928,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(v0));
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3047,9 +3044,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
// Name is always in a2.
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
@ -4015,30 +4010,6 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
DCHECK(receiver.is(a1));
DCHECK(name.is(a2));
Register scratch = a4;
Register extra = a5;
Register extra2 = a6;
Register extra3 = t1;
// The probe will tail call to a handler if found.
isolate()->stub_cache()->GenerateProbe(
masm(), Code::LOAD_IC, instr->hydrogen()->flags(), false, receiver, name,
scratch, extra, extra2, extra3);
// Tail call to miss if we ended up here.
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(ToRegister(instr->result()).is(v0));

View File

@ -1110,20 +1110,6 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), a1);

View File

@ -151,7 +151,6 @@ class LCodeGen;
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -471,26 +470,6 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -11,7 +11,7 @@ namespace v8 {
namespace internal {
int TypeFeedbackVector::ic_metadata_length() const {
return FLAG_vector_ics ? VectorICComputer::word_count(ICSlots()) : 0;
return VectorICComputer::word_count(ICSlots());
}

View File

@ -50,11 +50,6 @@ Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
if (!FLAG_vector_ics) {
// We only have CALL_ICs
return Code::CALL_IC;
}
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
int data = Smi::cast(get(index))->value();
VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
@ -63,11 +58,6 @@ Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
if (!FLAG_vector_ics) {
// Nothing to do if we only have CALL_ICs
return;
}
VectorICKind b = FromCodeKind(kind);
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
int data = Smi::cast(get(index))->value();
@ -88,8 +78,7 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
const Spec* spec) {
const int slot_count = spec->slots();
const int ic_slot_count = spec->ic_slots();
const int index_count =
FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
const int index_count = VectorICComputer::word_count(ic_slot_count);
const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) +
index_count + kReservedIndexCount;
if (length == kReservedIndexCount) {
@ -119,10 +108,8 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
}
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array);
if (FLAG_vector_ics) {
for (int i = 0; i < ic_slot_count; i++) {
vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i));
}
for (int i = 0; i < ic_slot_count; i++) {
vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i));
}
return vector;
}
@ -140,8 +127,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
bool TypeFeedbackVector::SpecDiffersFrom(
const ZoneFeedbackVectorSpec* other_spec) const {
if (!FLAG_vector_ics) return false;
if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) {
return true;
}
@ -312,8 +297,7 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
InlineCacheState CallICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
DCHECK(!FLAG_vector_ics ||
GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate) ||
DCHECK(GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate) ||
GetFeedbackExtra() == Smi::FromInt(kHasReturnedMinusZeroSentinel));
if (feedback == *vector()->MegamorphicSentinel(isolate)) {

View File

@ -29,7 +29,7 @@ class FeedbackVectorSpec {
int ic_slots() const { return has_ic_slot_ ? 1 : 0; }
Code::Kind GetKind(int ic_slot) const {
DCHECK(FLAG_vector_ics && has_ic_slot_ && ic_slot == 0);
DCHECK(has_ic_slot_ && ic_slot == 0);
return ic_kind_;
}
@ -46,9 +46,7 @@ class ZoneFeedbackVectorSpec {
: slots_(0), ic_slots_(0), ic_slot_kinds_(zone) {}
ZoneFeedbackVectorSpec(Zone* zone, int slots, int ic_slots)
: slots_(slots),
ic_slots_(ic_slots),
ic_slot_kinds_(FLAG_vector_ics ? ic_slots : 0, zone) {}
: slots_(slots), ic_slots_(ic_slots), ic_slot_kinds_(ic_slots, zone) {}
int slots() const { return slots_; }
void increase_slots(int count) { slots_ += count; }
@ -56,16 +54,14 @@ class ZoneFeedbackVectorSpec {
int ic_slots() const { return ic_slots_; }
void increase_ic_slots(int count) {
ic_slots_ += count;
if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots_);
ic_slot_kinds_.resize(ic_slots_);
}
void SetKind(int ic_slot, Code::Kind kind) {
DCHECK(FLAG_vector_ics);
ic_slot_kinds_[ic_slot] = kind;
}
Code::Kind GetKind(int ic_slot) const {
DCHECK(FLAG_vector_ics);
return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot));
}
@ -100,7 +96,7 @@ class TypeFeedbackVector : public FixedArray {
static const int kWithTypesIndex = 1;
static const int kGenericCountIndex = 2;
static int elements_per_ic_slot() { return FLAG_vector_ics ? 2 : 1; }
static int elements_per_ic_slot() { return 2; }
int first_ic_slot_index() const {
DCHECK(length() >= kReservedIndexCount);

View File

@ -492,35 +492,20 @@ void AstTyper::VisitThrow(Throw* expr) {
void AstTyper::VisitProperty(Property* expr) {
// Collect type feedback.
FeedbackVectorICSlot slot(FeedbackVectorICSlot::Invalid());
TypeFeedbackId id(TypeFeedbackId::None());
if (FLAG_vector_ics) {
slot = expr->PropertyFeedbackSlot();
expr->set_inline_cache_state(oracle()->LoadInlineCacheState(slot));
} else {
id = expr->PropertyFeedbackId();
expr->set_inline_cache_state(oracle()->LoadInlineCacheState(id));
}
slot = expr->PropertyFeedbackSlot();
expr->set_inline_cache_state(oracle()->LoadInlineCacheState(slot));
if (!expr->IsUninitialized()) {
if (expr->key()->IsPropertyName()) {
Literal* lit_key = expr->key()->AsLiteral();
DCHECK(lit_key != NULL && lit_key->value()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->value());
if (FLAG_vector_ics) {
oracle()->PropertyReceiverTypes(slot, name, expr->GetReceiverTypes());
} else {
oracle()->PropertyReceiverTypes(id, name, expr->GetReceiverTypes());
}
oracle()->PropertyReceiverTypes(slot, name, expr->GetReceiverTypes());
} else {
bool is_string;
IcCheckType key_type;
if (FLAG_vector_ics) {
oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
&is_string, &key_type);
} else {
oracle()->KeyedPropertyReceiverTypes(id, expr->GetReceiverTypes(),
&is_string, &key_type);
}
oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
&is_string, &key_type);
expr->set_is_string_access(is_string);
expr->set_key_type(key_type);
}

View File

@ -527,8 +527,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
// Ensure that the vector and slot registers won't be clobbered before
// calling the miss handler.
DCHECK(!FLAG_vector_ics ||
!AreAliased(r8, r9, VectorLoadICDescriptor::VectorRegister(),
DCHECK(!AreAliased(r8, r9, VectorLoadICDescriptor::VectorRegister(),
VectorLoadICDescriptor::SlotRegister()));
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8,
@ -913,9 +912,8 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
Register scratch = rdi;
Register result = rax;
DCHECK(!scratch.is(receiver) && !scratch.is(index));
DCHECK(!FLAG_vector_ics ||
(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister())));
DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
result.is(VectorLoadICDescriptor::SlotRegister()));
// StringCharAtGenerator doesn't use the result register until it's passed
// the different miss possibilities. If it did, we would have a conflict
@ -2941,7 +2939,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
index_not_number_,
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Push(VectorLoadICDescriptor::VectorRegister());
__ Push(VectorLoadICDescriptor::SlotRegister());
}
@ -2960,7 +2958,7 @@ void StringCharCodeAtGenerator::GenerateSlow(
__ movp(index_, rax);
}
__ Pop(object_);
if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) {
if (embed_mode == PART_OF_IC_HANDLER) {
__ Pop(VectorLoadICDescriptor::SlotRegister());
__ Pop(VectorLoadICDescriptor::VectorRegister());
}

View File

@ -163,10 +163,8 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-x64.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
RegList regs = receiver.bit() | name.bit();
if (FLAG_vector_ics) {
regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
}
RegList regs = receiver.bit() | name.bit() |
VectorLoadICTrampolineDescriptor::SlotRegister().bit();
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}

View File

@ -1293,14 +1293,9 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
__ Move(LoadDescriptor::NameRegister(), home_object_symbol);
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
__ Cmp(rax, isolate()->factory()->undefined_value());
Label done;
@ -1376,10 +1371,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
// load IC call.
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ Move(LoadDescriptor::NameRegister(), proxy->var()->name());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
@ -1463,10 +1456,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, "[ Global variable");
__ Move(LoadDescriptor::NameRegister(), var->name());
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
CallGlobalLoadIC(var->name());
context()->Plug(rax);
break;
@ -2158,10 +2149,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result = receiver[f](arg);
__ bind(&l_call);
__ movp(load_receiver, Operand(rsp, kPointerSize));
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic, TypeFeedbackId::None());
__ movp(rdi, rax);
@ -2177,10 +2166,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Move(load_receiver, rax);
__ Push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
@ -2190,10 +2177,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result.value
__ Pop(load_receiver); // result
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
context()->DropAndPlug(2, rax); // drop iter and g
break;
@ -2332,13 +2317,9 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
DCHECK(!prop->IsSuperAccess());
__ Move(LoadDescriptor::NameRegister(), key->value());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -2357,13 +2338,9 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
} else {
CallIC(ic, prop->PropertyFeedbackId());
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
CallIC(ic);
}
@ -4575,13 +4552,9 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Load the function from the receiver.
__ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
__ Move(LoadDescriptor::NameRegister(), expr->name());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
}
@ -5016,10 +4989,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
Comment cmnt(masm_, "[ Global variable");
__ Move(LoadDescriptor::NameRegister(), proxy->name());
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
}
__ Move(VectorLoadICDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);

View File

@ -2889,7 +2889,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
template <class T>
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
DCHECK(FLAG_vector_ics);
Register vector_register = ToRegister(instr->temp_vector());
Register slot_register = VectorLoadICDescriptor::SlotRegister();
DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
@ -2912,9 +2911,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(rax));
__ Move(LoadDescriptor::NameRegister(), instr->name());
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode,
PREMONOMORPHIC).code();
@ -3031,9 +3028,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
DCHECK(ToRegister(instr->result()).is(rax));
__ Move(LoadDescriptor::NameRegister(), instr->name());
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(
isolate(), NOT_CONTEXTUAL,
instr->hydrogen()->initialization_state()).code();
@ -3563,24 +3558,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
}
void LCodeGen::DoTailCallThroughMegamorphicCache(
LTailCallThroughMegamorphicCache* instr) {
Register receiver = ToRegister(instr->receiver());
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
Register scratch = rdi;
DCHECK(!scratch.is(receiver) && !scratch.is(name));
// The probe will tail call to a handler if found.
isolate()->stub_cache()->GenerateProbe(masm(), Code::LOAD_IC,
instr->hydrogen()->flags(), false,
receiver, name, scratch, no_reg);
LoadIC::GenerateMiss(masm());
}
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
DCHECK(ToRegister(instr->result()).is(rax));

View File

@ -1126,20 +1126,6 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
}
LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
HTailCallThroughMegamorphicCache* instr) {
LOperand* context = UseFixed(instr->context(), rsi);
LOperand* receiver_register =
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
context, receiver_register, name_register);
}
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), rsi);
LOperand* function = UseFixed(instr->function(), rdi);

View File

@ -151,7 +151,6 @@ class LCodeGen;
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
@ -479,27 +478,6 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> {
};
class LTailCallThroughMegamorphicCache final
: public LTemplateInstruction<0, 3, 0> {
public:
explicit LTailCallThroughMegamorphicCache(LOperand* context,
LOperand* receiver,
LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
};
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
public:
bool HasInterestingComment(LCodeGen* gen) const override { return false; }

View File

@ -15332,9 +15332,6 @@ TEST(ExternalInternalizedStringCollectedAtTearDown) {
TEST(ExternalInternalizedStringCollectedAtGC) {
// TODO(mvstanton): vector ics need weak support.
if (i::FLAG_vector_ics) return;
int destroyed = 0;
{ LocalContext env;
v8::HandleScope handle_scope(env->GetIsolate());

View File

@ -362,7 +362,7 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
// Now a feedback vector is allocated.
CHECK(f->shared()->is_compiled());
int expected_slots = 0;
int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
int expected_ic_slots = 2;
CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
}

View File

@ -46,19 +46,13 @@ TEST(VectorStructure) {
CHECK_EQ(1, vector->ICSlots());
ZoneFeedbackVectorSpec spec(zone, 3, 5);
if (FLAG_vector_ics) {
for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
}
for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
vector = factory->NewTypeFeedbackVector(&spec);
CHECK_EQ(3, vector->Slots());
CHECK_EQ(5, vector->ICSlots());
int metadata_length = vector->ic_metadata_length();
if (!FLAG_vector_ics) {
CHECK_EQ(0, metadata_length);
} else {
CHECK(metadata_length > 0);
}
CHECK(metadata_length > 0);
int index = vector->GetIndex(FeedbackVectorSlot(0));
@ -79,11 +73,6 @@ TEST(VectorStructure) {
TEST(VectorICMetadata) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
if (!FLAG_vector_ics) {
// If FLAG_vector_ics is false, we only store CALL_ICs in the vector, so
// there is no need for metadata to describe the slots.
return;
}
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Zone* zone = isolate->runtime_zone();
@ -259,7 +248,7 @@ TEST(VectorCallICStates) {
TEST(VectorLoadICStates) {
if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@ -313,7 +302,7 @@ TEST(VectorLoadICStates) {
TEST(VectorLoadICSlotSharing) {
if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@ -341,7 +330,7 @@ TEST(VectorLoadICSlotSharing) {
TEST(VectorLoadICOnSmi) {
if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());

View File

@ -3472,23 +3472,15 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
} else {
CHECK(ic_before->ic_state() == MONOMORPHIC);
}
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_after->ic_state() == DEFAULT);
} else {
CHECK(ic_after->ic_state() == MONOMORPHIC);
}
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_after->ic_state() == DEFAULT);
}
@ -3512,12 +3504,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
} else {
CHECK(ic_before->ic_state() == MONOMORPHIC);
}
CheckVectorIC(f, 0, MONOMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
@ -3525,12 +3513,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorICCleared(f, 0);
CHECK(ic_after->ic_state() == DEFAULT);
} else {
CHECK(IC::IsCleared(ic_after));
}
CheckVectorICCleared(f, 0);
CHECK(ic_after->ic_state() == DEFAULT);
}
@ -3561,24 +3545,16 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
} else {
CHECK(ic_before->ic_state() == POLYMORPHIC);
}
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_after->ic_state() == DEFAULT);
} else {
CHECK(ic_after->ic_state() == POLYMORPHIC);
}
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_after->ic_state() == DEFAULT);
}
@ -3609,25 +3585,16 @@ TEST(IncrementalMarkingClearsPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
} else {
CHECK(ic_before->ic_state() == POLYMORPHIC);
}
CheckVectorIC(f, 0, POLYMORPHIC);
CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
if (FLAG_vector_ics) {
CheckVectorICCleared(f, 0);
CHECK(ic_before->ic_state() == DEFAULT);
} else {
CHECK(IC::IsCleared(ic_after));
}
CheckVectorICCleared(f, 0);
CHECK(ic_before->ic_state() == DEFAULT);
}
@ -4730,9 +4697,8 @@ Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared,
int ic_slot, InlineCacheState state) {
if (FLAG_vector_ics &&
(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
kind == Code::CALL_IC)) {
if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
kind == Code::CALL_IC) {
TypeFeedbackVector* vector = shared->feedback_vector();
FeedbackVectorICSlot slot(ic_slot);
if (kind == Code::LOAD_IC) {