UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
- LOperand* name, LOperand* slot,
- LOperand* vector) {
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
Register extra2 = r6;
Register extra3 = r9;
-#ifdef DEBUG
- Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
- Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
- DCHECK(!FLAG_vector_ics ||
- !AreAliased(slot, vector, scratch, extra, extra2, extra3));
-#endif
-
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
-
- if (!instr->hydrogen()->is_just_miss()) {
- DCHECK(!instr->hydrogen()->is_keyed_load());
-
- // The probe will tail call to a handler if found.
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, extra, extra2, extra3);
- }
+ // 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.
- if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
- LOperand* name, LOperand* slot,
- LOperand* vector) {
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
Register extra = x5;
Register extra2 = x6;
Register extra3 = x7;
- DCHECK(!FLAG_vector_ics ||
- !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()),
- scratch, extra, extra2, extra3));
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
-
- if (!instr->hydrogen()->is_just_miss()) {
- DCHECK(!instr->hydrogen()->is_keyed_load());
-
- // The probe will tail call to a handler if found.
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, extra, extra2, extra3);
- }
+ // 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.
- if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
// 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);
class HTailCallThroughMegamorphicCache FINAL : public HInstruction {
public:
- enum Flags {
- NONE = 0,
- CALLED_FROM_KEYED_LOAD = 1 << 0,
- PERFORM_MISS_ONLY = 1 << 1
- };
-
- static Flags ComputeFlags(bool called_from_keyed_load,
- bool perform_miss_only) {
- Flags flags = NONE;
- if (called_from_keyed_load) {
- flags = static_cast<Flags>(flags | CALLED_FROM_KEYED_LOAD);
- }
- if (perform_miss_only) {
- flags = static_cast<Flags>(flags | PERFORM_MISS_ONLY);
- }
- return flags;
- }
-
- DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(
- HTailCallThroughMegamorphicCache, HValue*, HValue*, HValue*, HValue*,
- HTailCallThroughMegamorphicCache::Flags);
-
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HTailCallThroughMegamorphicCache,
HValue*, HValue*);
return Representation::Tagged();
}
- virtual int OperandCount() const FINAL OVERRIDE {
- return FLAG_vector_ics ? 5 : 3;
- }
+ 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); }
- HValue* slot() const {
- DCHECK(FLAG_vector_ics);
- return OperandAt(3);
- }
- HValue* vector() const {
- DCHECK(FLAG_vector_ics);
- return OperandAt(4);
- }
Code::Flags flags() const;
- bool is_keyed_load() const { return flags_ & CALLED_FROM_KEYED_LOAD; }
- bool is_just_miss() const { return flags_ & PERFORM_MISS_ONLY; }
-
std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache)
private:
HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver,
- HValue* name, HValue* slot, HValue* vector,
- Flags flags)
- : flags_(flags) {
- DCHECK(FLAG_vector_ics);
+ HValue* name) {
SetOperandAt(0, context);
SetOperandAt(1, receiver);
SetOperandAt(2, name);
- SetOperandAt(3, slot);
- SetOperandAt(4, vector);
}
- HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver,
- HValue* name)
- : flags_(NONE) {
- SetOperandAt(0, context);
- SetOperandAt(1, receiver);
- SetOperandAt(2, name);
- }
-
- EmbeddedContainer<HValue*, 5> inputs_;
- Flags flags_;
+ EmbeddedContainer<HValue*, 3> inputs_;
};
Register name = ToRegister(instr->name());
DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
DCHECK(name.is(LoadDescriptor::NameRegister()));
- Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
- Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
-
Register scratch = ebx;
Register extra = edi;
- DCHECK(!extra.is(slot) && !extra.is(vector));
DCHECK(!scratch.is(receiver) && !scratch.is(name));
DCHECK(!extra.is(receiver) && !extra.is(name));
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
-
- if (!instr->hydrogen()->is_just_miss()) {
- if (FLAG_vector_ics) {
- __ push(slot);
- __ push(vector);
- }
+ // 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);
- // The probe will tail call to a handler if found.
- // If --vector-ics is on, then it knows to pop the two args first.
- DCHECK(!instr->hydrogen()->is_keyed_load());
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, extra);
-
- if (FLAG_vector_ics) {
- __ pop(vector);
- __ pop(slot);
- }
- }
-
- // Tail call to miss if we ended up here.
- if (must_teardown_frame) __ leave();
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
- LOperand* name, LOperand* slot,
- LOperand* vector) {
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
Register extra = t1;
Register extra2 = t2;
Register extra3 = t5;
-#ifdef DEBUG
- Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
- Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
- DCHECK(!FLAG_vector_ics ||
- !AreAliased(slot, vector, scratch, extra, extra2, extra3));
-#endif
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
-
- if (!instr->hydrogen()->is_just_miss()) {
- DCHECK(!instr->hydrogen()->is_keyed_load());
-
- // The probe will tail call to a handler if found.
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, extra, extra2, extra3);
- }
+ // 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.
- if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
- LOperand* name, LOperand* slot,
- LOperand* vector) {
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
Register extra = a5;
Register extra2 = a6;
Register extra3 = t1;
-#ifdef DEBUG
- Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
- Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
- DCHECK(!FLAG_vector_ics ||
- !AreAliased(slot, vector, scratch, extra, extra2, extra3));
-#endif
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
-
- if (!instr->hydrogen()->is_just_miss()) {
- DCHECK(!instr->hydrogen()->is_keyed_load());
-
- // The probe will tail call to a handler if found.
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, extra, extra2, extra3);
- }
+ // 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.
- if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
- LOperand* name, LOperand* slot,
- LOperand* vector) {
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")
DCHECK(name.is(LoadDescriptor::NameRegister()));
Register scratch = rdi;
DCHECK(!scratch.is(receiver) && !scratch.is(name));
- DCHECK(!FLAG_vector_ics ||
- !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()),
- scratch));
- // Important for the tail-call.
- bool must_teardown_frame = NeedsEagerFrame();
+ // 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);
- if (!instr->hydrogen()->is_just_miss()) {
- // The probe will tail call to a handler if found.
- DCHECK(!instr->hydrogen()->is_keyed_load());
- isolate()->stub_cache()->GenerateProbe(
- masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
- receiver, name, scratch, no_reg);
- }
-
- // Tail call to miss if we ended up here.
- if (must_teardown_frame) __ leave();
- if (instr->hydrogen()->is_keyed_load()) {
- KeyedLoadIC::GenerateMiss(masm());
- } else {
- LoadIC::GenerateMiss(masm());
- }
+ LoadIC::GenerateMiss(masm());
}
UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
LOperand* name_register =
UseFixed(instr->name(), LoadDescriptor::NameRegister());
- LOperand* slot = NULL;
- LOperand* vector = NULL;
- if (FLAG_vector_ics) {
- slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
- vector =
- UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
- }
// Not marked as call. It can't deoptimize, and it never returns.
return new (zone()) LTailCallThroughMegamorphicCache(
- context, receiver_register, name_register, slot, vector);
+ context, receiver_register, name_register);
}
class LTailCallThroughMegamorphicCache FINAL
- : public LTemplateInstruction<0, 5, 0> {
+ : public LTemplateInstruction<0, 3, 0> {
public:
explicit LTailCallThroughMegamorphicCache(LOperand* context,
- LOperand* receiver, LOperand* name,
- LOperand* slot, LOperand* vector) {
+ LOperand* receiver,
+ LOperand* name) {
inputs_[0] = context;
inputs_[1] = receiver;
inputs_[2] = name;
- inputs_[3] = slot;
- inputs_[4] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* receiver() { return inputs_[1]; }
LOperand* name() { return inputs_[2]; }
- LOperand* slot() { return inputs_[3]; }
- LOperand* vector() { return inputs_[4]; }
DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
"tail-call-through-megamorphic-cache")