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:
mvstanton@chromium.org 2014-10-10 13:22:10 +00:00
parent 8f983e7672
commit d04617b2db
24 changed files with 219 additions and 192 deletions

View File

@ -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.

View File

@ -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())));
}

View File

@ -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

View File

@ -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()));
}

View File

@ -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
View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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);

View File

@ -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());
}

View File

@ -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_;
};

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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_;
};

View File

@ -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.

View File

@ -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())));
}

View File

@ -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.

View File

@ -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())));
}

View File

@ -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);

View File

@ -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_;

View File

@ -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) { }

View File

@ -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.

View File

@ -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()));
}

View File

@ -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);