Introduce FeedbackVectorSlot type - better than int.
It's good to have typing around this value. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/641373002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24528 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8f983e7672
commit
d04617b2db
@ -1102,7 +1102,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
|
||||
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Comment cmnt(masm_, "[ ForInStatement");
|
||||
int slot = stmt->ForInFeedbackSlot();
|
||||
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
|
||||
SetStatementPosition(stmt);
|
||||
|
||||
Label loop, exit;
|
||||
@ -1194,7 +1194,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
__ Move(r1, FeedbackVector());
|
||||
__ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
__ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));
|
||||
__ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot.ToInt())));
|
||||
|
||||
__ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
|
||||
__ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
|
||||
@ -1366,7 +1366,7 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
|
||||
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->HomeObjectFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
|
||||
@ -1432,7 +1432,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
|
||||
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
@ -1521,7 +1521,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(CONTEXTUAL);
|
||||
context()->Plug(r0);
|
||||
@ -2150,7 +2150,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
|
||||
}
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
@ -2170,7 +2170,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
@ -2183,7 +2183,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
|
||||
context()->DropAndPlug(2, r0); // drop iter and g
|
||||
@ -2364,7 +2364,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
|
||||
@ -2389,7 +2389,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallIC(ic);
|
||||
} else {
|
||||
CallIC(ic, prop->PropertyFeedbackId());
|
||||
@ -2896,7 +2896,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic = CallIC::initialize_stub(
|
||||
isolate(), arg_count, call_type);
|
||||
__ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
|
||||
__ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
// Don't assign a type feedback id to the IC, since type feedback is provided
|
||||
// by the vector above.
|
||||
@ -3096,12 +3096,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
if (FLAG_pretenuring_call_new) {
|
||||
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot() ==
|
||||
expr->CallNewFeedbackSlot() + 1);
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
|
||||
expr->CallNewFeedbackSlot().ToInt() + 1);
|
||||
}
|
||||
|
||||
__ Move(r2, FeedbackVector());
|
||||
__ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
|
||||
__ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
|
||||
|
||||
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
|
||||
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
||||
@ -4302,7 +4302,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
|
||||
@ -4706,7 +4706,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
|
@ -3000,7 +3000,7 @@ void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
// No need to allocate this register.
|
||||
DCHECK(VectorLoadICDescriptor::SlotRegister().is(r0));
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(instr->hydrogen()->slot())));
|
||||
Operand(Smi::FromInt(instr->hydrogen()->slot().ToInt())));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1097,7 +1097,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
ASM_LOCATION("FullCodeGenerator::VisitForInStatement");
|
||||
Comment cmnt(masm_, "[ ForInStatement");
|
||||
int slot = stmt->ForInFeedbackSlot();
|
||||
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
|
||||
// TODO(all): This visitor probably needs better comments and a revisit.
|
||||
SetStatementPosition(stmt);
|
||||
|
||||
@ -1181,7 +1181,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
__ LoadObject(x1, FeedbackVector());
|
||||
__ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
__ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));
|
||||
__ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot.ToInt())));
|
||||
|
||||
__ Mov(x1, Smi::FromInt(1)); // Smi indicates slow check.
|
||||
__ Peek(x10, 0); // Get enumerated object.
|
||||
@ -1352,7 +1352,7 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
|
||||
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->HomeObjectFeedbackSlot()));
|
||||
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
|
||||
@ -1414,7 +1414,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
|
||||
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL
|
||||
@ -1499,7 +1499,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(CONTEXTUAL);
|
||||
context()->Plug(x0);
|
||||
@ -2012,7 +2012,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(prop->PropertyFeedbackSlot()));
|
||||
SmiFromSlot(prop->PropertyFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
|
||||
@ -2038,7 +2038,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(prop->PropertyFeedbackSlot()));
|
||||
SmiFromSlot(prop->PropertyFeedbackSlot()));
|
||||
CallIC(ic);
|
||||
} else {
|
||||
CallIC(ic, prop->PropertyFeedbackId());
|
||||
@ -2557,7 +2557,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
|
||||
Handle<Code> ic = CallIC::initialize_stub(
|
||||
isolate(), arg_count, call_type);
|
||||
__ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot()));
|
||||
__ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot()));
|
||||
__ Peek(x1, (arg_count + 1) * kXRegSize);
|
||||
// Don't assign a type feedback id to the IC, since type feedback is provided
|
||||
// by the vector above.
|
||||
@ -2761,12 +2761,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
if (FLAG_pretenuring_call_new) {
|
||||
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot() ==
|
||||
expr->CallNewFeedbackSlot() + 1);
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
|
||||
expr->CallNewFeedbackSlot().ToInt() + 1);
|
||||
}
|
||||
|
||||
__ LoadObject(x2, FeedbackVector());
|
||||
__ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot()));
|
||||
__ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot()));
|
||||
|
||||
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
|
||||
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
||||
@ -3968,7 +3968,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(name));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->CallRuntimeFeedbackSlot()));
|
||||
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
|
||||
@ -4368,7 +4368,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
||||
__ Mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
@ -4724,7 +4724,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ Peek(load_name, 2 * kPointerSize);
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->KeyedLoadFeedbackSlot()));
|
||||
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
|
||||
}
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
@ -4744,7 +4744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->DoneFeedbackSlot()));
|
||||
SmiFromSlot(expr->DoneFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // x0=result.done
|
||||
// The ToBooleanStub argument (result.done) is in x0.
|
||||
@ -4757,7 +4757,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
if (FLAG_vector_ics) {
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->ValueFeedbackSlot()));
|
||||
SmiFromSlot(expr->ValueFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // x0=result.value
|
||||
context()->DropAndPlug(2, x0); // drop iter and g
|
||||
|
@ -3377,7 +3377,7 @@ void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
// No need to allocate this register.
|
||||
DCHECK(VectorLoadICDescriptor::SlotRegister().is(x0));
|
||||
__ Mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(instr->hydrogen()->slot()));
|
||||
Smi::FromInt(instr->hydrogen()->slot().ToInt()));
|
||||
}
|
||||
|
||||
|
||||
|
10
src/ast.cc
10
src/ast.cc
@ -64,7 +64,7 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
|
||||
: Expression(zone, position, 0, id_gen),
|
||||
raw_name_(var->raw_name()),
|
||||
interface_(var->interface()),
|
||||
variable_feedback_slot_(kInvalidFeedbackSlot),
|
||||
variable_feedback_slot_(FeedbackVectorSlot::Invalid()),
|
||||
is_this_(var->is_this()),
|
||||
is_assigned_(false),
|
||||
is_resolved_(false) {
|
||||
@ -77,7 +77,7 @@ VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
|
||||
: Expression(zone, position, 0, id_gen),
|
||||
raw_name_(name),
|
||||
interface_(interface),
|
||||
variable_feedback_slot_(kInvalidFeedbackSlot),
|
||||
variable_feedback_slot_(FeedbackVectorSlot::Invalid()),
|
||||
is_this_(is_this),
|
||||
is_assigned_(false),
|
||||
is_resolved_(false) {}
|
||||
@ -605,9 +605,9 @@ bool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
|
||||
|
||||
|
||||
void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
int allocation_site_feedback_slot = FLAG_pretenuring_call_new
|
||||
? AllocationSiteFeedbackSlot()
|
||||
: CallNewFeedbackSlot();
|
||||
FeedbackVectorSlot allocation_site_feedback_slot =
|
||||
FLAG_pretenuring_call_new ? AllocationSiteFeedbackSlot()
|
||||
: CallNewFeedbackSlot();
|
||||
allocation_site_ =
|
||||
oracle->GetCallNewAllocationSite(allocation_site_feedback_slot);
|
||||
is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackSlot());
|
||||
|
101
src/ast.h
101
src/ast.h
@ -237,12 +237,11 @@ class AstNode: public ZoneObject {
|
||||
// node types which don't actually have this. Note that this is conceptually
|
||||
// not really nice, but multiple inheritance would introduce yet another
|
||||
// vtable entry per node, something we don't want for space reasons.
|
||||
static const int kInvalidFeedbackSlot = -1;
|
||||
virtual int ComputeFeedbackSlotCount() {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
virtual void SetFirstFeedbackSlot(int slot) { UNREACHABLE(); }
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
|
||||
|
||||
private:
|
||||
// Hidden to prevent accidental usage. It would have to load the
|
||||
@ -949,10 +948,12 @@ class ForInStatement FINAL : public ForEachStatement {
|
||||
|
||||
// Type feedback information.
|
||||
virtual int ComputeFeedbackSlotCount() { return 1; }
|
||||
virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; }
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
for_in_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int ForInFeedbackSlot() {
|
||||
DCHECK(for_in_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot ForInFeedbackSlot() {
|
||||
DCHECK(!for_in_feedback_slot_.IsInvalid());
|
||||
return for_in_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -970,7 +971,7 @@ class ForInStatement FINAL : public ForEachStatement {
|
||||
IdGen* id_gen)
|
||||
: ForEachStatement(zone, labels, pos, num_ids(), id_gen),
|
||||
for_in_type_(SLOW_FOR_IN),
|
||||
for_in_feedback_slot_(kInvalidFeedbackSlot) {}
|
||||
for_in_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
||||
|
||||
static int num_ids() { return 2; }
|
||||
int base_id() const {
|
||||
@ -979,7 +980,7 @@ class ForInStatement FINAL : public ForEachStatement {
|
||||
|
||||
private:
|
||||
ForInType for_in_type_;
|
||||
int for_in_feedback_slot_;
|
||||
FeedbackVectorSlot for_in_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -1694,11 +1695,11 @@ class VariableProxy FINAL : public Expression {
|
||||
void BindTo(Variable* var);
|
||||
|
||||
virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
variable_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int VariableFeedbackSlot() { return variable_feedback_slot_; }
|
||||
FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
|
||||
|
||||
protected:
|
||||
VariableProxy(Zone* zone, Variable* var, int position, IdGen* id_gen);
|
||||
@ -1711,7 +1712,7 @@ class VariableProxy FINAL : public Expression {
|
||||
Variable* var_; // if is_resolved_
|
||||
};
|
||||
Interface* interface_;
|
||||
int variable_feedback_slot_;
|
||||
FeedbackVectorSlot variable_feedback_slot_;
|
||||
bool is_this_ : 1;
|
||||
bool is_assigned_ : 1;
|
||||
bool is_resolved_ : 1;
|
||||
@ -1757,18 +1758,20 @@ class Property FINAL : public Expression {
|
||||
}
|
||||
|
||||
virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
property_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int PropertyFeedbackSlot() const { return property_feedback_slot_; }
|
||||
FeedbackVectorSlot PropertyFeedbackSlot() const {
|
||||
return property_feedback_slot_;
|
||||
}
|
||||
|
||||
protected:
|
||||
Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen)
|
||||
: Expression(zone, pos, num_ids(), id_gen),
|
||||
obj_(obj),
|
||||
key_(key),
|
||||
property_feedback_slot_(kInvalidFeedbackSlot),
|
||||
property_feedback_slot_(FeedbackVectorSlot::Invalid()),
|
||||
is_for_call_(false),
|
||||
is_uninitialized_(false),
|
||||
is_string_access_(false) {}
|
||||
@ -1779,7 +1782,7 @@ class Property FINAL : public Expression {
|
||||
private:
|
||||
Expression* obj_;
|
||||
Expression* key_;
|
||||
int property_feedback_slot_;
|
||||
FeedbackVectorSlot property_feedback_slot_;
|
||||
|
||||
SmallMapList receiver_types_;
|
||||
bool is_for_call_ : 1;
|
||||
@ -1797,14 +1800,12 @@ class Call FINAL : public Expression {
|
||||
|
||||
// Type feedback information.
|
||||
virtual int ComputeFeedbackSlotCount() { return 1; }
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
call_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
bool HasCallFeedbackSlot() const {
|
||||
return call_feedback_slot_ != kInvalidFeedbackSlot;
|
||||
}
|
||||
int CallFeedbackSlot() const { return call_feedback_slot_; }
|
||||
bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
|
||||
FeedbackVectorSlot CallFeedbackSlot() const { return call_feedback_slot_; }
|
||||
|
||||
virtual SmallMapList* GetReceiverTypes() OVERRIDE {
|
||||
if (expression()->IsProperty()) {
|
||||
@ -1867,7 +1868,7 @@ class Call FINAL : public Expression {
|
||||
: Expression(zone, pos, num_ids(), id_gen),
|
||||
expression_(expression),
|
||||
arguments_(arguments),
|
||||
call_feedback_slot_(kInvalidFeedbackSlot) {
|
||||
call_feedback_slot_(FeedbackVectorSlot::Invalid()) {
|
||||
if (expression->IsProperty()) {
|
||||
expression->AsProperty()->mark_for_call();
|
||||
}
|
||||
@ -1882,7 +1883,7 @@ class Call FINAL : public Expression {
|
||||
Handle<JSFunction> target_;
|
||||
Handle<Cell> cell_;
|
||||
Handle<AllocationSite> allocation_site_;
|
||||
int call_feedback_slot_;
|
||||
FeedbackVectorSlot call_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -1897,18 +1898,14 @@ class CallNew FINAL : public Expression {
|
||||
virtual int ComputeFeedbackSlotCount() {
|
||||
return FLAG_pretenuring_call_new ? 2 : 1;
|
||||
}
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
callnew_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int CallNewFeedbackSlot() {
|
||||
DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
return callnew_feedback_slot_;
|
||||
}
|
||||
int AllocationSiteFeedbackSlot() {
|
||||
DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot CallNewFeedbackSlot() { return callnew_feedback_slot_; }
|
||||
FeedbackVectorSlot AllocationSiteFeedbackSlot() {
|
||||
DCHECK(FLAG_pretenuring_call_new);
|
||||
return callnew_feedback_slot_ + 1;
|
||||
return CallNewFeedbackSlot().next();
|
||||
}
|
||||
|
||||
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
||||
@ -1929,7 +1926,7 @@ class CallNew FINAL : public Expression {
|
||||
expression_(expression),
|
||||
arguments_(arguments),
|
||||
is_monomorphic_(false),
|
||||
callnew_feedback_slot_(kInvalidFeedbackSlot) {}
|
||||
callnew_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
||||
|
||||
static int num_ids() { return 1; }
|
||||
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
|
||||
@ -1940,7 +1937,7 @@ class CallNew FINAL : public Expression {
|
||||
bool is_monomorphic_;
|
||||
Handle<JSFunction> target_;
|
||||
Handle<AllocationSite> allocation_site_;
|
||||
int callnew_feedback_slot_;
|
||||
FeedbackVectorSlot callnew_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -1962,11 +1959,11 @@ class CallRuntime FINAL : public Expression {
|
||||
virtual int ComputeFeedbackSlotCount() {
|
||||
return (FLAG_vector_ics && is_jsruntime()) ? 1 : 0;
|
||||
}
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
callruntime_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int CallRuntimeFeedbackSlot() {
|
||||
FeedbackVectorSlot CallRuntimeFeedbackSlot() {
|
||||
return callruntime_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -1981,7 +1978,8 @@ class CallRuntime FINAL : public Expression {
|
||||
: Expression(zone, pos, num_ids(), id_gen),
|
||||
raw_name_(name),
|
||||
function_(function),
|
||||
arguments_(arguments) {}
|
||||
arguments_(arguments),
|
||||
callruntime_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
||||
|
||||
static int num_ids() { return 1; }
|
||||
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
|
||||
@ -1990,7 +1988,7 @@ class CallRuntime FINAL : public Expression {
|
||||
const AstRawString* raw_name_;
|
||||
const Runtime::Function* function_;
|
||||
ZoneList<Expression*>* arguments_;
|
||||
int callruntime_feedback_slot_;
|
||||
FeedbackVectorSlot callruntime_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -2306,24 +2304,19 @@ class Yield FINAL : public Expression {
|
||||
virtual int ComputeFeedbackSlotCount() {
|
||||
return (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0;
|
||||
}
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
yield_first_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int KeyedLoadFeedbackSlot() {
|
||||
DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot KeyedLoadFeedbackSlot() {
|
||||
return yield_first_feedback_slot_;
|
||||
}
|
||||
|
||||
int DoneFeedbackSlot() {
|
||||
DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
return yield_first_feedback_slot_ + 1;
|
||||
FeedbackVectorSlot DoneFeedbackSlot() {
|
||||
return KeyedLoadFeedbackSlot().next();
|
||||
}
|
||||
|
||||
int ValueFeedbackSlot() {
|
||||
DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
return yield_first_feedback_slot_ + 2;
|
||||
}
|
||||
FeedbackVectorSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); }
|
||||
|
||||
protected:
|
||||
Yield(Zone* zone, Expression* generator_object, Expression* expression,
|
||||
@ -2333,14 +2326,14 @@ class Yield FINAL : public Expression {
|
||||
expression_(expression),
|
||||
yield_kind_(yield_kind),
|
||||
index_(-1),
|
||||
yield_first_feedback_slot_(kInvalidFeedbackSlot) {}
|
||||
yield_first_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
||||
|
||||
private:
|
||||
Expression* generator_object_;
|
||||
Expression* expression_;
|
||||
Kind yield_kind_;
|
||||
int index_;
|
||||
int yield_first_feedback_slot_;
|
||||
FeedbackVectorSlot yield_first_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -2629,13 +2622,12 @@ class SuperReference FINAL : public Expression {
|
||||
|
||||
// Type feedback information.
|
||||
virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
||||
virtual void SetFirstFeedbackSlot(int slot) {
|
||||
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
||||
homeobject_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
int HomeObjectFeedbackSlot() {
|
||||
DCHECK(!FLAG_vector_ics ||
|
||||
homeobject_feedback_slot_ != kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot HomeObjectFeedbackSlot() {
|
||||
DCHECK(!FLAG_vector_ics || !homeobject_feedback_slot_.IsInvalid());
|
||||
return homeobject_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -2643,7 +2635,7 @@ class SuperReference FINAL : public Expression {
|
||||
SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
|
||||
: Expression(zone, pos, num_ids(), id_gen),
|
||||
this_var_(this_var),
|
||||
homeobject_feedback_slot_(kInvalidFeedbackSlot) {
|
||||
homeobject_feedback_slot_(FeedbackVectorSlot::Invalid()) {
|
||||
DCHECK(this_var->is_this());
|
||||
}
|
||||
|
||||
@ -2652,7 +2644,7 @@ class SuperReference FINAL : public Expression {
|
||||
|
||||
private:
|
||||
VariableProxy* this_var_;
|
||||
int homeobject_feedback_slot_;
|
||||
FeedbackVectorSlot homeobject_feedback_slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -3118,7 +3110,8 @@ class AstConstructionVisitor BASE_EMBEDDED {
|
||||
void add_slot_node(AstNode* slot_node) {
|
||||
int count = slot_node->ComputeFeedbackSlotCount();
|
||||
if (count > 0) {
|
||||
slot_node->SetFirstFeedbackSlot(properties_.feedback_slots());
|
||||
slot_node->SetFirstFeedbackSlot(
|
||||
FeedbackVectorSlot(properties_.feedback_slots()));
|
||||
properties_.increase_feedback_slots(count);
|
||||
}
|
||||
}
|
||||
|
@ -1711,7 +1711,8 @@ StrictMode AstGraphBuilder::strict_mode() const {
|
||||
}
|
||||
|
||||
|
||||
VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(int slot) const {
|
||||
VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
|
||||
FeedbackVectorSlot slot) const {
|
||||
return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
|
||||
BailoutId bailout_id);
|
||||
Node* BuildVariableDelete(Variable* var, BailoutId bailout_id,
|
||||
OutputFrameStateCombine state_combine);
|
||||
Node* BuildVariableLoad(Variable* proxy, BailoutId bailout_id,
|
||||
Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
|
||||
const VectorSlotPair& feedback,
|
||||
ContextualMode mode = CONTEXTUAL);
|
||||
|
||||
@ -145,7 +145,7 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
|
||||
inline Scope* current_scope() const;
|
||||
|
||||
// Named and keyed loads require a VectorSlotPair for successful lowering.
|
||||
VectorSlotPair CreateVectorSlotPair(int slot) const;
|
||||
VectorSlotPair CreateVectorSlotPair(FeedbackVectorSlot slot) const;
|
||||
|
||||
// Process arguments to a call by popping {arity} elements off the operand
|
||||
// stack and build a call node using the given call operator.
|
||||
|
@ -275,7 +275,8 @@ void JSGenericLowering::LowerJSLoadProperty(Node* node) {
|
||||
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
|
||||
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
|
||||
if (FLAG_vector_ics) {
|
||||
PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().slot()));
|
||||
PatchInsertInput(node, 2,
|
||||
jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
|
||||
PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
|
||||
}
|
||||
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
|
||||
@ -288,7 +289,8 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
|
||||
CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
|
||||
PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
|
||||
if (FLAG_vector_ics) {
|
||||
PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().slot()));
|
||||
PatchInsertInput(node, 2,
|
||||
jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
|
||||
PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
|
||||
}
|
||||
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
|
||||
|
@ -109,14 +109,15 @@ ContextAccess const& ContextAccessOf(Operator const* op) {
|
||||
|
||||
|
||||
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
|
||||
return lhs.slot() == rhs.slot() && lhs.vector().is_identical_to(rhs.vector());
|
||||
return lhs.slot().ToInt() == rhs.slot().ToInt() &&
|
||||
lhs.vector().is_identical_to(rhs.vector());
|
||||
}
|
||||
|
||||
|
||||
size_t hash_value(VectorSlotPair const& p) {
|
||||
// TODO(mvstanton): include the vector in the hash.
|
||||
base::hash<int> h;
|
||||
return h(p.slot());
|
||||
return h(p.slot().ToInt());
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,15 +98,15 @@ ContextAccess const& ContextAccessOf(Operator const*);
|
||||
|
||||
class VectorSlotPair {
|
||||
public:
|
||||
VectorSlotPair(Handle<TypeFeedbackVector> vector, int slot)
|
||||
VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
|
||||
: vector_(vector), slot_(slot) {}
|
||||
|
||||
Handle<TypeFeedbackVector> vector() const { return vector_; }
|
||||
int slot() const { return slot_; }
|
||||
FeedbackVectorSlot slot() const { return slot_; }
|
||||
|
||||
private:
|
||||
const Handle<TypeFeedbackVector> vector_;
|
||||
const int slot_;
|
||||
const FeedbackVectorSlot slot_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -365,12 +365,13 @@ unsigned FullCodeGenerator::EmitBackEdgeTable() {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EnsureSlotContainsAllocationSite(int slot) {
|
||||
void FullCodeGenerator::EnsureSlotContainsAllocationSite(
|
||||
FeedbackVectorSlot slot) {
|
||||
Handle<FixedArray> vector = FeedbackVector();
|
||||
if (!vector->get(slot)->IsAllocationSite()) {
|
||||
if (!vector->get(slot.ToInt())->IsAllocationSite()) {
|
||||
Handle<AllocationSite> allocation_site =
|
||||
isolate()->factory()->NewAllocationSite();
|
||||
vector->set(slot, *allocation_site);
|
||||
vector->set(slot.ToInt(), *allocation_site);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,7 +432,10 @@ class FullCodeGenerator: public AstVisitor {
|
||||
Handle<FixedArray> FeedbackVector() {
|
||||
return info_->feedback_vector();
|
||||
}
|
||||
void EnsureSlotContainsAllocationSite(int slot);
|
||||
void EnsureSlotContainsAllocationSite(FeedbackVectorSlot slot);
|
||||
Smi* SmiFromSlot(FeedbackVectorSlot slot) const {
|
||||
return Smi::FromInt(slot.ToInt());
|
||||
}
|
||||
|
||||
// Record a call's return site offset, used to rebuild the frame if the
|
||||
// called function was inlined at the site.
|
||||
|
@ -5475,12 +5475,12 @@ class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> {
|
||||
HValue* global_object() { return OperandAt(1); }
|
||||
Handle<String> name() const { return name_; }
|
||||
bool for_typeof() const { return for_typeof_; }
|
||||
int slot() const {
|
||||
DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot slot() const {
|
||||
DCHECK(FLAG_vector_ics && !slot_.IsInvalid());
|
||||
return slot_;
|
||||
}
|
||||
Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, FeedbackVectorSlot slot) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
feedback_vector_ = vector;
|
||||
slot_ = slot;
|
||||
@ -5499,7 +5499,7 @@ class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> {
|
||||
Handle<String> name, bool for_typeof)
|
||||
: name_(name),
|
||||
for_typeof_(for_typeof),
|
||||
slot_(AstNode::kInvalidFeedbackSlot) {
|
||||
slot_(FeedbackVectorSlot::Invalid()) {
|
||||
SetOperandAt(0, context);
|
||||
SetOperandAt(1, global_object);
|
||||
set_representation(Representation::Tagged());
|
||||
@ -5509,7 +5509,7 @@ class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> {
|
||||
Handle<String> name_;
|
||||
bool for_typeof_;
|
||||
Handle<FixedArray> feedback_vector_;
|
||||
int slot_;
|
||||
FeedbackVectorSlot slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -6480,12 +6480,12 @@ class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> {
|
||||
HValue* object() const { return OperandAt(1); }
|
||||
Handle<Object> name() const { return name_; }
|
||||
|
||||
int slot() const {
|
||||
DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot slot() const {
|
||||
DCHECK(FLAG_vector_ics && !slot_.IsInvalid());
|
||||
return slot_;
|
||||
}
|
||||
Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, FeedbackVectorSlot slot) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
feedback_vector_ = vector;
|
||||
slot_ = slot;
|
||||
@ -6501,7 +6501,7 @@ class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> {
|
||||
|
||||
private:
|
||||
HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
|
||||
: name_(name), slot_(AstNode::kInvalidFeedbackSlot) {
|
||||
: name_(name), slot_(FeedbackVectorSlot::Invalid()) {
|
||||
SetOperandAt(0, context);
|
||||
SetOperandAt(1, object);
|
||||
set_representation(Representation::Tagged());
|
||||
@ -6510,7 +6510,7 @@ class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> {
|
||||
|
||||
Handle<Object> name_;
|
||||
Handle<FixedArray> feedback_vector_;
|
||||
int slot_;
|
||||
FeedbackVectorSlot slot_;
|
||||
};
|
||||
|
||||
|
||||
@ -6756,12 +6756,12 @@ class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> {
|
||||
HValue* object() const { return OperandAt(0); }
|
||||
HValue* key() const { return OperandAt(1); }
|
||||
HValue* context() const { return OperandAt(2); }
|
||||
int slot() const {
|
||||
DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot);
|
||||
FeedbackVectorSlot slot() const {
|
||||
DCHECK(FLAG_vector_ics && !slot_.IsInvalid());
|
||||
return slot_;
|
||||
}
|
||||
Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
|
||||
void SetVectorAndSlot(Handle<FixedArray> vector, FeedbackVectorSlot slot) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
feedback_vector_ = vector;
|
||||
slot_ = slot;
|
||||
@ -6780,7 +6780,7 @@ class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> {
|
||||
|
||||
private:
|
||||
HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key)
|
||||
: slot_(AstNode::kInvalidFeedbackSlot) {
|
||||
: slot_(FeedbackVectorSlot::Invalid()) {
|
||||
set_representation(Representation::Tagged());
|
||||
SetOperandAt(0, obj);
|
||||
SetOperandAt(1, key);
|
||||
@ -6789,7 +6789,7 @@ class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> {
|
||||
}
|
||||
|
||||
Handle<FixedArray> feedback_vector_;
|
||||
int slot_;
|
||||
FeedbackVectorSlot slot_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1035,7 +1035,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
|
||||
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Comment cmnt(masm_, "[ ForInStatement");
|
||||
int slot = stmt->ForInFeedbackSlot();
|
||||
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
|
||||
|
||||
SetStatementPosition(stmt);
|
||||
|
||||
@ -1117,7 +1117,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
// No need for a write barrier, we are storing a Smi in the feedback vector.
|
||||
__ LoadHeapObject(ebx, FeedbackVector());
|
||||
__ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
|
||||
__ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot.ToInt())),
|
||||
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
|
||||
__ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
|
||||
@ -1289,7 +1289,7 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
|
||||
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(expr->HomeObjectFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
|
||||
@ -1357,7 +1357,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
__ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
|
||||
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
@ -1444,7 +1444,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
||||
__ mov(LoadDescriptor::NameRegister(), var->name());
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(CONTEXTUAL);
|
||||
context()->Plug(eax);
|
||||
@ -2079,7 +2079,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ mov(load_receiver, Operand(esp, kPointerSize));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
|
||||
}
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
@ -2099,7 +2099,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->done_string()); // "done"
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(expr->DoneFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
@ -2113,7 +2113,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
isolate()->factory()->value_string()); // "value"
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(expr->ValueFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
|
||||
context()->DropAndPlug(2, eax); // drop iter and g
|
||||
@ -2279,7 +2279,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
|
||||
@ -2304,7 +2304,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallIC(ic);
|
||||
} else {
|
||||
CallIC(ic, prop->PropertyFeedbackId());
|
||||
@ -2800,7 +2800,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic = CallIC::initialize_stub(
|
||||
isolate(), arg_count, call_type);
|
||||
__ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
|
||||
__ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
|
||||
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
|
||||
// Don't assign a type feedback id to the IC, since type feedback is provided
|
||||
// by the vector above.
|
||||
@ -2991,12 +2991,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
if (FLAG_pretenuring_call_new) {
|
||||
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot() ==
|
||||
expr->CallNewFeedbackSlot() + 1);
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
|
||||
expr->CallNewFeedbackSlot().ToInt() + 1);
|
||||
}
|
||||
|
||||
__ LoadHeapObject(ebx, FeedbackVector());
|
||||
__ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
|
||||
__ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
|
||||
|
||||
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
|
||||
__ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
||||
@ -4248,7 +4248,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
|
||||
@ -4660,7 +4660,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
||||
__ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
|
@ -2834,7 +2834,7 @@ void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
// No need to allocate this register.
|
||||
DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax));
|
||||
__ mov(VectorLoadICDescriptor::SlotRegister(),
|
||||
Immediate(Smi::FromInt(instr->hydrogen()->slot())));
|
||||
Immediate(Smi::FromInt(instr->hydrogen()->slot().ToInt())));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1093,7 +1093,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
|
||||
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Comment cmnt(masm_, "[ ForInStatement");
|
||||
int slot = stmt->ForInFeedbackSlot();
|
||||
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
|
||||
SetStatementPosition(stmt);
|
||||
|
||||
Label loop, exit;
|
||||
@ -1181,7 +1181,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
__ li(a1, FeedbackVector());
|
||||
__ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
__ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
|
||||
__ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot.ToInt())));
|
||||
|
||||
__ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
|
||||
__ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
|
||||
@ -1353,7 +1353,7 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
|
||||
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->HomeObjectFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
|
||||
@ -1415,7 +1415,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
|
||||
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
@ -1504,7 +1504,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(CONTEXTUAL);
|
||||
context()->Plug(v0);
|
||||
@ -2140,7 +2140,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ lw(load_name, MemOperand(sp, 2 * kPointerSize));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
|
||||
}
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
@ -2160,7 +2160,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
|
||||
__ mov(a0, v0);
|
||||
@ -2173,7 +2173,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
|
||||
context()->DropAndPlug(2, v0); // drop iter and g
|
||||
@ -2342,7 +2342,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
|
||||
@ -2367,7 +2367,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
|
||||
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
|
||||
CallIC(ic);
|
||||
} else {
|
||||
CallIC(ic, prop->PropertyFeedbackId());
|
||||
@ -2871,7 +2871,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic = CallIC::initialize_stub(
|
||||
isolate(), arg_count, call_type);
|
||||
__ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
|
||||
__ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
|
||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
// Don't assign a type feedback id to the IC, since type feedback is provided
|
||||
// by the vector above.
|
||||
@ -3069,12 +3069,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
if (FLAG_pretenuring_call_new) {
|
||||
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot() ==
|
||||
expr->CallNewFeedbackSlot() + 1);
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
|
||||
expr->CallNewFeedbackSlot().ToInt() + 1);
|
||||
}
|
||||
|
||||
__ li(a2, FeedbackVector());
|
||||
__ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
|
||||
__ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
|
||||
|
||||
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
|
||||
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
||||
@ -4306,7 +4306,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
|
||||
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
|
||||
@ -4712,7 +4712,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
||||
__ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
|
||||
if (FLAG_vector_ics) {
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
|
||||
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
|
||||
}
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
|
@ -2893,7 +2893,7 @@ void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
// No need to allocate this register.
|
||||
DCHECK(VectorLoadICDescriptor::SlotRegister().is(a0));
|
||||
__ li(VectorLoadICDescriptor::SlotRegister(),
|
||||
Operand(Smi::FromInt(instr->hydrogen()->slot())));
|
||||
Operand(Smi::FromInt(instr->hydrogen()->slot().ToInt())));
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,9 +49,9 @@ Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> TypeFeedbackOracle::GetInfo(int slot) {
|
||||
DCHECK(slot >= 0 && slot < feedback_vector_->length());
|
||||
Object* obj = feedback_vector_->get(slot);
|
||||
Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorSlot slot) {
|
||||
DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length());
|
||||
Object* obj = feedback_vector_->get(slot.ToInt());
|
||||
if (!obj->IsJSFunction() ||
|
||||
!CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) {
|
||||
return Handle<Object>(obj, isolate());
|
||||
@ -78,13 +78,13 @@ bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
|
||||
}
|
||||
|
||||
|
||||
bool TypeFeedbackOracle::CallIsMonomorphic(int slot) {
|
||||
bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorSlot slot) {
|
||||
Handle<Object> value = GetInfo(slot);
|
||||
return value->IsAllocationSite() || value->IsJSFunction();
|
||||
}
|
||||
|
||||
|
||||
bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
|
||||
bool TypeFeedbackOracle::CallNewIsMonomorphic(FeedbackVectorSlot slot) {
|
||||
Handle<Object> info = GetInfo(slot);
|
||||
return FLAG_pretenuring_call_new
|
||||
? info->IsJSFunction()
|
||||
@ -92,7 +92,7 @@ bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
|
||||
}
|
||||
|
||||
|
||||
byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
|
||||
byte TypeFeedbackOracle::ForInType(FeedbackVectorSlot feedback_vector_slot) {
|
||||
Handle<Object> value = GetInfo(feedback_vector_slot);
|
||||
return value.is_identical_to(
|
||||
TypeFeedbackVector::UninitializedSentinel(isolate()))
|
||||
@ -114,7 +114,7 @@ KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
|
||||
}
|
||||
|
||||
|
||||
Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
|
||||
Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(FeedbackVectorSlot slot) {
|
||||
Handle<Object> info = GetInfo(slot);
|
||||
if (info->IsAllocationSite()) {
|
||||
return Handle<JSFunction>(isolate()->native_context()->array_function());
|
||||
@ -124,7 +124,8 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
|
||||
}
|
||||
|
||||
|
||||
Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(int slot) {
|
||||
Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(
|
||||
FeedbackVectorSlot slot) {
|
||||
Handle<Object> info = GetInfo(slot);
|
||||
if (FLAG_pretenuring_call_new || info->IsJSFunction()) {
|
||||
return Handle<JSFunction>::cast(info);
|
||||
@ -135,7 +136,8 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(int slot) {
|
||||
}
|
||||
|
||||
|
||||
Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(int slot) {
|
||||
Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(
|
||||
FeedbackVectorSlot slot) {
|
||||
Handle<Object> info = GetInfo(slot);
|
||||
if (info->IsAllocationSite()) {
|
||||
return Handle<AllocationSite>::cast(info);
|
||||
@ -144,7 +146,8 @@ Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(int slot) {
|
||||
}
|
||||
|
||||
|
||||
Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(int slot) {
|
||||
Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(
|
||||
FeedbackVectorSlot slot) {
|
||||
Handle<Object> info = GetInfo(slot);
|
||||
if (FLAG_pretenuring_call_new || info->IsAllocationSite()) {
|
||||
return Handle<AllocationSite>::cast(info);
|
||||
|
@ -25,16 +25,16 @@ class TypeFeedbackOracle: public ZoneObject {
|
||||
|
||||
bool LoadIsUninitialized(TypeFeedbackId id);
|
||||
bool StoreIsUninitialized(TypeFeedbackId id);
|
||||
bool CallIsMonomorphic(int slot);
|
||||
bool CallIsMonomorphic(FeedbackVectorSlot slot);
|
||||
bool CallIsMonomorphic(TypeFeedbackId aid);
|
||||
bool KeyedArrayCallIsHoley(TypeFeedbackId id);
|
||||
bool CallNewIsMonomorphic(int slot);
|
||||
bool CallNewIsMonomorphic(FeedbackVectorSlot slot);
|
||||
|
||||
// TODO(1571) We can't use ForInStatement::ForInType as the return value due
|
||||
// to various cycles in our headers.
|
||||
// TODO(rossberg): once all oracle access is removed from ast.cc, it should
|
||||
// be possible.
|
||||
byte ForInType(int feedback_vector_slot);
|
||||
byte ForInType(FeedbackVectorSlot feedback_vector_slot);
|
||||
|
||||
KeyedAccessStoreMode GetStoreMode(TypeFeedbackId id);
|
||||
|
||||
@ -59,10 +59,10 @@ class TypeFeedbackOracle: public ZoneObject {
|
||||
static bool CanRetainOtherContext(JSFunction* function,
|
||||
Context* native_context);
|
||||
|
||||
Handle<JSFunction> GetCallTarget(int slot);
|
||||
Handle<AllocationSite> GetCallAllocationSite(int slot);
|
||||
Handle<JSFunction> GetCallNewTarget(int slot);
|
||||
Handle<AllocationSite> GetCallNewAllocationSite(int slot);
|
||||
Handle<JSFunction> GetCallTarget(FeedbackVectorSlot slot);
|
||||
Handle<AllocationSite> GetCallAllocationSite(FeedbackVectorSlot slot);
|
||||
Handle<JSFunction> GetCallNewTarget(FeedbackVectorSlot slot);
|
||||
Handle<AllocationSite> GetCallNewAllocationSite(FeedbackVectorSlot slot);
|
||||
|
||||
bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id);
|
||||
|
||||
@ -112,7 +112,7 @@ class TypeFeedbackOracle: public ZoneObject {
|
||||
|
||||
// Returns an element from the type feedback vector. Returns undefined
|
||||
// if there is no information.
|
||||
Handle<Object> GetInfo(int slot);
|
||||
Handle<Object> GetInfo(FeedbackVectorSlot slot);
|
||||
|
||||
private:
|
||||
Handle<Context> native_context_;
|
||||
|
22
src/utils.h
22
src/utils.h
@ -951,6 +951,28 @@ class TypeFeedbackId {
|
||||
};
|
||||
|
||||
|
||||
class FeedbackVectorSlot {
|
||||
public:
|
||||
explicit FeedbackVectorSlot(int id) : id_(id) {}
|
||||
int ToInt() const { return id_; }
|
||||
|
||||
static FeedbackVectorSlot Invalid() {
|
||||
return FeedbackVectorSlot(kInvalidSlot);
|
||||
}
|
||||
bool IsInvalid() const { return id_ == kInvalidSlot; }
|
||||
|
||||
FeedbackVectorSlot next() const {
|
||||
DCHECK(id_ != kInvalidSlot);
|
||||
return FeedbackVectorSlot(id_ + 1);
|
||||
}
|
||||
|
||||
private:
|
||||
static const int kInvalidSlot = -1;
|
||||
|
||||
int id_;
|
||||
};
|
||||
|
||||
|
||||
class BailoutId {
|
||||
public:
|
||||
explicit BailoutId(int id) : id_(id) { }
|
||||
|
@ -1058,7 +1058,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
|
||||
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Comment cmnt(masm_, "[ ForInStatement");
|
||||
int slot = stmt->ForInFeedbackSlot();
|
||||
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
|
||||
SetStatementPosition(stmt);
|
||||
|
||||
Label loop, exit;
|
||||
@ -1149,7 +1149,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
// No need for a write barrier, we are storing a Smi in the feedback vector.
|
||||
__ Move(rbx, FeedbackVector());
|
||||
__ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)),
|
||||
__ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot.ToInt())),
|
||||
TypeFeedbackVector::MegamorphicSentinel(isolate()));
|
||||
__ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check
|
||||
__ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
|
||||
@ -1323,7 +1323,7 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
|
||||
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->HomeObjectFeedbackSlot()));
|
||||
SmiFromSlot(expr->HomeObjectFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
|
||||
@ -1393,7 +1393,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
|
||||
__ Move(LoadDescriptor::NameRegister(), proxy->var()->name());
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
|
||||
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
@ -1479,7 +1479,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
||||
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(CONTEXTUAL);
|
||||
context()->Plug(rax);
|
||||
@ -2113,7 +2113,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ movp(load_receiver, Operand(rsp, kPointerSize));
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->KeyedLoadFeedbackSlot()));
|
||||
SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
|
||||
}
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
@ -2132,7 +2132,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->DoneFeedbackSlot()));
|
||||
SmiFromSlot(expr->DoneFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
|
||||
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
|
||||
@ -2145,7 +2145,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->ValueFeedbackSlot()));
|
||||
SmiFromSlot(expr->ValueFeedbackSlot()));
|
||||
}
|
||||
CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
|
||||
context()->DropAndPlug(2, rax); // drop iter and g
|
||||
@ -2312,7 +2312,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ Move(LoadDescriptor::NameRegister(), key->value());
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(prop->PropertyFeedbackSlot()));
|
||||
SmiFromSlot(prop->PropertyFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
|
||||
@ -2337,7 +2337,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(prop->PropertyFeedbackSlot()));
|
||||
SmiFromSlot(prop->PropertyFeedbackSlot()));
|
||||
CallIC(ic);
|
||||
} else {
|
||||
CallIC(ic, prop->PropertyFeedbackId());
|
||||
@ -2798,7 +2798,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic = CallIC::initialize_stub(
|
||||
isolate(), arg_count, call_type);
|
||||
__ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot()));
|
||||
__ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot()));
|
||||
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
// Don't assign a type feedback id to the IC, since type feedback is provided
|
||||
// by the vector above.
|
||||
@ -2990,12 +2990,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code, but not in the snapshot.
|
||||
if (FLAG_pretenuring_call_new) {
|
||||
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot() ==
|
||||
expr->CallNewFeedbackSlot() + 1);
|
||||
DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
|
||||
expr->CallNewFeedbackSlot().ToInt() + 1);
|
||||
}
|
||||
|
||||
__ Move(rbx, FeedbackVector());
|
||||
__ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot()));
|
||||
__ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot()));
|
||||
|
||||
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
|
||||
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
||||
@ -4267,7 +4267,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Move(LoadDescriptor::NameRegister(), expr->name());
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(expr->CallRuntimeFeedbackSlot()));
|
||||
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
|
||||
CallLoadIC(NOT_CONTEXTUAL);
|
||||
} else {
|
||||
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
|
||||
@ -4672,7 +4672,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
||||
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
|
||||
if (FLAG_vector_ics) {
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(proxy->VariableFeedbackSlot()));
|
||||
SmiFromSlot(proxy->VariableFeedbackSlot()));
|
||||
}
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
|
@ -2856,7 +2856,7 @@ void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
// No need to allocate this register.
|
||||
DCHECK(VectorLoadICDescriptor::SlotRegister().is(rax));
|
||||
__ Move(VectorLoadICDescriptor::SlotRegister(),
|
||||
Smi::FromInt(instr->hydrogen()->slot()));
|
||||
Smi::FromInt(instr->hydrogen()->slot().ToInt()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,7 +78,8 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
|
||||
uint8_t backing_store[kLength * 8];
|
||||
Handle<JSArrayBuffer> buffer =
|
||||
NewArrayBuffer(backing_store, arraysize(backing_store));
|
||||
VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(), 0);
|
||||
VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
|
||||
FeedbackVectorSlot::Invalid());
|
||||
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
|
||||
Handle<JSTypedArray> array =
|
||||
factory()->NewJSTypedArray(type, buffer, kLength);
|
||||
|
Loading…
Reference in New Issue
Block a user