void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
- int slot = stmt->ForInFeedbackSlot();
+ FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
__ 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
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());
__ 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)
__ 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);
__ 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());
__ 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());
__ 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
__ 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());
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());
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.
// 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);
__ 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());
__ 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.
// 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())));
}
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);
__ 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.
if (FLAG_vector_ics) {
__ Mov(VectorLoadICDescriptor::SlotRegister(),
- Smi::FromInt(expr->HomeObjectFeedbackSlot()));
+ SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
__ 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
__ 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);
__ 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());
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());
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.
// 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);
__ 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());
__ 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.
__ 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());
__ 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.
__ 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
// 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()));
}
: 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) {
: 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) {}
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());
// 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
// 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_;
}
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 {
private:
ForInType for_in_type_;
- int for_in_feedback_slot_;
+ FeedbackVectorSlot for_in_feedback_slot_;
};
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);
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;
}
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) {}
private:
Expression* obj_;
Expression* key_;
- int property_feedback_slot_;
+ FeedbackVectorSlot property_feedback_slot_;
SmallMapList receiver_types_;
bool is_for_call_ : 1;
// 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()) {
: 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();
}
Handle<JSFunction> target_;
Handle<Cell> cell_;
Handle<AllocationSite> allocation_site_;
- int call_feedback_slot_;
+ FeedbackVectorSlot call_feedback_slot_;
};
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);
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(); }
bool is_monomorphic_;
Handle<JSFunction> target_;
Handle<AllocationSite> allocation_site_;
- int callnew_feedback_slot_;
+ FeedbackVectorSlot callnew_feedback_slot_;
};
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_;
}
: 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(); }
const AstRawString* raw_name_;
const Runtime::Function* function_;
ZoneList<Expression*>* arguments_;
- int callruntime_feedback_slot_;
+ FeedbackVectorSlot callruntime_feedback_slot_;
};
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,
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_;
};
// 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_;
}
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());
}
private:
VariableProxy* this_var_;
- int homeobject_feedback_slot_;
+ FeedbackVectorSlot homeobject_feedback_slot_;
};
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);
}
}
}
-VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(int slot) const {
+VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
+ FeedbackVectorSlot slot) const {
return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
}
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);
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.
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);
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);
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());
}
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_;
};
}
-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);
}
}
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.
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;
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());
Handle<String> name_;
bool for_typeof_;
Handle<FixedArray> feedback_vector_;
- int slot_;
+ FeedbackVectorSlot slot_;
};
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;
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());
Handle<Object> name_;
Handle<FixedArray> feedback_vector_;
- int slot_;
+ FeedbackVectorSlot slot_;
};
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;
private:
HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key)
- : slot_(AstNode::kInvalidFeedbackSlot) {
+ : slot_(FeedbackVectorSlot::Invalid()) {
set_representation(Representation::Tagged());
SetOperandAt(0, obj);
SetOperandAt(1, key);
}
Handle<FixedArray> feedback_vector_;
- int slot_;
+ FeedbackVectorSlot slot_;
};
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
- int slot = stmt->ForInFeedbackSlot();
+ FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(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
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());
__ 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)
__ 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);
__ 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());
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());
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
__ 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());
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());
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.
// 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);
__ 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());
__ 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.
// 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())));
}
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
- int slot = stmt->ForInFeedbackSlot();
+ FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
__ 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
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());
__ 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)
__ 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);
__ 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());
__ 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);
__ 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
__ 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());
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());
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.
// 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);
__ 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());
__ 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.
// 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())));
}
}
-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());
}
-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()
}
-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()))
}
-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());
}
-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);
}
-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);
}
-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);
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);
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);
// 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_;
};
+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) { }
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
- int slot = stmt->ForInFeedbackSlot();
+ FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
// 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
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
- Smi::FromInt(expr->HomeObjectFeedbackSlot()));
+ SmiFromSlot(expr->HomeObjectFeedbackSlot()));
CallLoadIC(NOT_CONTEXTUAL);
} else {
CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
__ 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)
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
if (FLAG_vector_ics) {
__ Move(VectorLoadICDescriptor::SlotRegister(),
- Smi::FromInt(proxy->VariableFeedbackSlot()));
+ SmiFromSlot(proxy->VariableFeedbackSlot()));
}
CallLoadIC(CONTEXTUAL);
context()->Plug(rax);
__ 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());
__ 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());
__ 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
__ 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());
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());
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.
// 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);
__ 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());
__ 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.
// 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()));
}
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);