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);
}
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver = LoadDescriptor::ReceiverRegister();
+ // 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);
- 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);
- }
__ bind(&miss);
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
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-x87.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; }