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,
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
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 {
// 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 {
// 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);
}
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;
__ 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
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;
__ 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);
__ 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);
// 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;
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);
}
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);
}
// 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);
}
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);
}
-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);
V(SubI) \
V(RSubI) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
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()));
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();
// 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();
}
-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));
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,
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
// 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 {
// 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 {
// 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);
}
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);
__ 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;
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;
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);
}
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);
}
// 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);
}
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);
__ 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);
__ 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());
// 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;
}
-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.
V(SubI) \
V(SubS) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
}
-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));
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()));
.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();
// 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,
: 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);
}
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));
}
}
}
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_;
void BindTo(Variable* var);
bool UsesVariableFeedbackSlot() const {
- return FLAG_vector_ics && (var()->IsUnallocated() || var()->IsLookupSlot());
+ return var()->IsUnallocated() || var()->IsLookupSlot();
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
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 {
}
FeedbackVectorICSlot PropertyFeedbackSlot() const {
- DCHECK(!FLAG_vector_ics || !property_feedback_slot_.IsInvalid());
+ DCHECK(!property_feedback_slot_.IsInvalid());
return property_feedback_slot_;
}
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);
}
// 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);
// 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 {
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_;
}
}
-static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
- KeyedLoadIC::GeneratePreMonomorphic(masm);
-}
-
-
static void Generate_StoreIC_Miss(MacroAssembler* masm) {
StoreIC::GenerateMiss(masm);
}
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) \
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) {
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));
}
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));
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);
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
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());
}
-void MegamorphicLoadStub::InitializeDescriptor(CodeStubDescriptor* d) {}
-
-
void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->Initialize(
Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry);
V(KeyedLoadGeneric) \
V(LoadScriptContextField) \
V(LoadDictionaryElement) \
- V(MegamorphicLoad) \
V(NameDictionaryLookup) \
V(NumberToString) \
V(Typeof) \
// 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);
: HydrogenCodeStub(isolate) {}
CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
- if (FLAG_vector_ics) {
- return VectorLoadICDescriptor(isolate());
- }
- return LoadDescriptor(isolate());
+ return VectorLoadICDescriptor(isolate());
}
DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
};
-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)
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);
}
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);
}
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,
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);
}
// 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()));
case HValue::kStoreNamedGeneric:
case HValue::kStringCharCodeAt:
case HValue::kStringCharFromCode:
- case HValue::kTailCallThroughMegamorphicCache:
case HValue::kThisFunction:
case HValue::kTypeofIsAndBranch:
case HValue::kUnknownOSRValue:
}
-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";
V(StringCharFromCode) \
V(StringCompareAndBranch) \
V(Sub) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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);
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;
}
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;
}
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;
}
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());
}
}
Deoptimizer::SOFT);
}
if (access_type == LOAD) {
- if (FLAG_vector_ics) {
- 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);
+ 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;
}
- 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);
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());
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(
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
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());
}
__ 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());
}
// 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);
}
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;
// 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
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;
// 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);
__ 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);
__ 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;
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);
}
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);
}
// 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);
}
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);
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()));
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();
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();
}
-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));
}
-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);
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
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]; }
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);
}
// 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);
// 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);
}
// 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);
// 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);
}
__ 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));
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);
}
// 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);
}
__ 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));
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();
}
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);
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));
-
- __ pop(ebx);
- __ push(receiver);
- __ push(name);
- __ push(ebx);
- }
+
+ 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);
}
// 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);
}
// 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);
}
}
-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();
}
-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) {
}
-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");
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);
// 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,
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);
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));
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:
}
-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
}
-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();
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:
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());
}
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;
}
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
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);
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;
}
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));
}
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;
}
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;
}
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));
}
}
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;
}
LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
: IC(depth, isolate, nexus) {
- DCHECK(!FLAG_vector_ics || nexus != NULL);
+ DCHECK(nexus != NULL);
DCHECK(IsLoadStub());
}
// 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);
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);
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,
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());
}
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
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,
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);
}
// 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);
// 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);
}
// 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);
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);
}
__ 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));
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);
}
// 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);
// 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);
}
// 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);
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);
}
__ 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));
__ 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));
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));
-
- __ 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);
- }
+ 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);
}
// 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);
}
// 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);
}
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.
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,
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 {
// 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 {
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);
}
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()));
__ 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
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;
__ 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);
__ 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());
// 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;
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);
}
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);
}
// 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);
}
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);
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()));
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();
// 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();
}
-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));
}
-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);
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
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.
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,
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 {
// 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 {
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);
}
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()));
__ 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
// 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;
__ 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);
__ 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());
// 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;
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);
}
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);
}
// 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);
}
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);
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()));
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();
// 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();
}
-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));
}
-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);
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
namespace internal {
int TypeFeedbackVector::ic_metadata_length() const {
- return FLAG_vector_ics ? VectorICComputer::word_count(ICSlots()) : 0;
+ return VectorICComputer::word_count(ICSlots());
}
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());
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();
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) {
}
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;
}
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;
}
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)) {
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_;
}
: 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; }
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));
}
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);
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);
}
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,
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
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());
}
__ 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());
}
// 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);
}
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;
// 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
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;
// 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);
__ 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);
// 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;
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);
}
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);
}
// 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);
}
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);
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()));
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();
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();
}
-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));
}
-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);
V(StringCompareAndBranch) \
V(SubI) \
V(TaggedToI) \
- V(TailCallThroughMegamorphicCache) \
V(ThisFunction) \
V(ToFastProperties) \
V(TransitionElementsKind) \
};
-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; }
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());
// 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());
}
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));
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();
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());
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());
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());
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);
}
*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();
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);
}
*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);
}
*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);
}
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) {