Teach TurboFan to call vector-based ICs.

Additional static information needs to be passed to Load and KeyedLoad calls if
--vector-ics is turned on.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/633423002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24519 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2014-10-10 09:49:43 +00:00
parent b9cc56dd34
commit 52575220d4
16 changed files with 246 additions and 49 deletions

View File

@ -3015,7 +3015,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3137,7 +3137,8 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
@ -3428,7 +3429,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}

View File

@ -3391,7 +3391,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3645,7 +3645,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).Is(x0));
@ -3701,7 +3701,8 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
DCHECK(ToRegister(instr->result()).is(x0));

View File

@ -19,13 +19,35 @@ Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode) {
}
// static
Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate,
ContextualMode mode) {
if (FLAG_vector_ics) {
return Callable(LoadIC::initialize_stub_in_optimized_code(
isolate, LoadICState(mode).GetExtraICState()),
VectorLoadICDescriptor(isolate));
}
return CodeFactory::LoadIC(isolate, mode);
}
// static
Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
return Callable(isolate->builtins()->KeyedLoadIC_Initialize(),
return Callable(KeyedLoadIC::initialize_stub(isolate),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
if (FLAG_vector_ics) {
return Callable(KeyedLoadIC::initialize_stub_in_optimized_code(isolate),
VectorLoadICDescriptor(isolate));
}
return CodeFactory::KeyedLoadIC(isolate);
}
// static
Callable CodeFactory::StoreIC(Isolate* isolate, StrictMode mode) {
return Callable(StoreIC::initialize_stub(isolate, mode),

View File

@ -33,7 +33,9 @@ class CodeFactory FINAL {
public:
// Initial states for ICs.
static Callable LoadIC(Isolate* isolate, ContextualMode mode);
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode);
static Callable KeyedLoadIC(Isolate* isolate);
static Callable KeyedLoadICInOptimizedCode(Isolate* isolate);
static Callable StoreIC(Isolate* isolate, StrictMode mode);
static Callable KeyedStoreIC(Isolate* isolate, StrictMode mode);

View File

@ -837,7 +837,8 @@ void AstGraphBuilder::VisitConditional(Conditional* expr) {
void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
Node* value = BuildVariableLoad(expr->var(), expr->id());
VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
Node* value = BuildVariableLoad(expr->var(), expr->id(), pair);
ast_context()->ProduceValue(value);
}
@ -1091,15 +1092,19 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* old_value = NULL;
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
old_value = BuildVariableLoad(variable, expr->target()->id());
VariableProxy* proxy = expr->target()->AsVariableProxy();
VectorSlotPair pair =
CreateVectorSlotPair(proxy->VariableFeedbackSlot());
old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Top();
Unique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
old_value = NewNode(javascript()->LoadNamed(name), object);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = NewNode(javascript()->LoadNamed(name, pair), object);
PrepareFrameState(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -1107,7 +1112,9 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
case KEYED_PROPERTY: {
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
old_value = NewNode(javascript()->LoadProperty(), object, key);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = NewNode(javascript()->LoadProperty(pair), object, key);
PrepareFrameState(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -1179,17 +1186,18 @@ void AstGraphBuilder::VisitThrow(Throw* expr) {
void AstGraphBuilder::VisitProperty(Property* expr) {
Node* value;
VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
if (expr->key()->IsPropertyName()) {
VisitForValue(expr->obj());
Node* object = environment()->Pop();
Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
value = NewNode(javascript()->LoadNamed(name), object);
value = NewNode(javascript()->LoadNamed(name, pair), object);
} else {
VisitForValue(expr->obj());
VisitForValue(expr->key());
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = NewNode(javascript()->LoadProperty(), object, key);
value = NewNode(javascript()->LoadProperty(pair), object, key);
}
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
@ -1208,8 +1216,10 @@ void AstGraphBuilder::VisitCall(Call* expr) {
bool possibly_eval = false;
switch (call_type) {
case Call::GLOBAL_CALL: {
Variable* variable = callee->AsVariableProxy()->var();
callee_value = BuildVariableLoad(variable, expr->expression()->id());
VariableProxy* proxy = callee->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
callee_value =
BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
receiver_value = jsgraph()->UndefinedConstant();
break;
}
@ -1231,14 +1241,16 @@ void AstGraphBuilder::VisitCall(Call* expr) {
Property* property = callee->AsProperty();
VisitForValue(property->obj());
Node* object = environment()->Top();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
if (property->key()->IsPropertyName()) {
Unique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
callee_value = NewNode(javascript()->LoadNamed(name), object);
callee_value = NewNode(javascript()->LoadNamed(name, pair), object);
} else {
VisitForValue(property->key());
Node* key = environment()->Pop();
callee_value = NewNode(javascript()->LoadProperty(), object, key);
callee_value = NewNode(javascript()->LoadProperty(pair), object, key);
}
PrepareFrameState(callee_value, property->LoadId(),
OutputFrameStateCombine::Push());
@ -1326,7 +1338,9 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
Node* receiver_value = BuildLoadBuiltinsObject();
Unique<String> unique = MakeUnique(name);
Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
Node* callee_value =
NewNode(javascript()->LoadNamed(unique, pair), receiver_value);
// TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
// refuses to optimize functions with jsruntime calls).
PrepareFrameState(callee_value, BailoutId::None(),
@ -1401,8 +1415,10 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
int stack_depth = -1;
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->expression()->AsVariableProxy()->var();
old_value = BuildVariableLoad(variable, expr->expression()->id());
VariableProxy* proxy = expr->expression()->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
old_value =
BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
stack_depth = 0;
break;
}
@ -1411,7 +1427,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* object = environment()->Top();
Unique<Name> name =
MakeUnique(property->key()->AsLiteral()->AsPropertyName());
old_value = NewNode(javascript()->LoadNamed(name), object);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = NewNode(javascript()->LoadNamed(name, pair), object);
PrepareFrameState(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 1;
@ -1422,7 +1440,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
VisitForValue(property->key());
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
old_value = NewNode(javascript()->LoadProperty(), object, key);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = NewNode(javascript()->LoadProperty(pair), object, key);
PrepareFrameState(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 2;
@ -1632,9 +1652,10 @@ void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
if (expr->expression()->IsVariableProxy()) {
// Typeof does not throw a reference error on global variables, hence we
// perform a non-contextual load in case the operand is a variable proxy.
Variable* variable = expr->expression()->AsVariableProxy()->var();
operand =
BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL);
VariableProxy* proxy = expr->expression()->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair,
NOT_CONTEXTUAL);
} else {
VisitForValue(expr->expression());
operand = environment()->Pop();
@ -1690,6 +1711,11 @@ StrictMode AstGraphBuilder::strict_mode() const {
}
VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(int slot) const {
return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
}
Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
DCHECK(environment()->stack_height() >= arity);
Node** all = info()->zone()->NewArray<Node*>(arity);
@ -1779,6 +1805,7 @@ Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
BailoutId bailout_id,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
@ -1787,7 +1814,8 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
// Global var, const, or let variable.
Node* global = BuildLoadGlobalObject();
Unique<Name> name = MakeUnique(variable->name());
const Operator* op = javascript()->LoadNamed(name, contextual_mode);
const Operator* op =
javascript()->LoadNamed(name, feedback, contextual_mode);
Node* node = NewNode(op, global);
PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
return node;

View File

@ -82,7 +82,8 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
BailoutId bailout_id);
Node* BuildVariableDelete(Variable* var, BailoutId bailout_id,
OutputFrameStateCombine state_combine);
Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
Node* BuildVariableLoad(Variable* proxy, BailoutId bailout_id,
const VectorSlotPair& feedback,
ContextualMode mode = CONTEXTUAL);
// Builders for accessing the function context.
@ -143,6 +144,9 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
// Current scope during visitation.
inline Scope* current_scope() const;
// Named and keyed loads require a VectorSlotPair for successful lowering.
VectorSlotPair CreateVectorSlotPair(int 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.
Node* ProcessArguments(const Operator* op, int arity);

View File

@ -272,15 +272,25 @@ void JSGenericLowering::LowerJSToObject(Node* node) {
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
Callable callable = CodeFactory::KeyedLoadIC(isolate());
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, 3, jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSLoadNamed(Node* node) {
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable = CodeFactory::LoadIC(isolate(), p.contextual_mode());
Callable callable =
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, 3, jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}

View File

@ -108,10 +108,23 @@ 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());
}
size_t hash_value(VectorSlotPair const& p) {
// TODO(mvstanton): include the vector in the hash.
base::hash<int> h;
return h(p.slot());
}
bool operator==(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
lhs.contextual_mode() == rhs.contextual_mode();
lhs.contextual_mode() == rhs.contextual_mode() &&
lhs.feedback() == rhs.feedback();
}
@ -122,7 +135,7 @@ bool operator!=(LoadNamedParameters const& lhs,
size_t hash_value(LoadNamedParameters const& p) {
return base::hash_combine(p.name(), p.contextual_mode());
return base::hash_combine(p.name(), p.contextual_mode(), p.feedback());
}
@ -131,6 +144,35 @@ std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
}
std::ostream& operator<<(std::ostream& os, LoadPropertyParameters const& p) {
// Nothing special to print.
return os;
}
bool operator==(LoadPropertyParameters const& lhs,
LoadPropertyParameters const& rhs) {
return lhs.feedback() == rhs.feedback();
}
bool operator!=(LoadPropertyParameters const& lhs,
LoadPropertyParameters const& rhs) {
return !(lhs == rhs);
}
const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSLoadProperty, op->opcode());
return OpParameter<LoadPropertyParameters>(op);
}
size_t hash_value(LoadPropertyParameters const& p) {
return hash_value(p.feedback());
}
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode());
return OpParameter<LoadNamedParameters>(op);
@ -193,7 +235,6 @@ const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 0, 1) \
V(LoadProperty, Operator::kNoProperties, 2, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \
V(TypeOf, Operator::kPure, 1, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \
@ -261,14 +302,24 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, contextual_mode);
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>(
IrOpcode::kJSLoadNamed, Operator::kNoProperties, 1, 1, "JSLoadNamed",
parameters);
}
const Operator* JSOperatorBuilder::LoadProperty(
const VectorSlotPair& feedback) {
LoadPropertyParameters parameters(feedback);
return new (zone()) Operator1<LoadPropertyParameters>(
IrOpcode::kJSLoadProperty, Operator::kNoProperties, 2, 1,
"JSLoadProperty", parameters);
}
const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) {
return new (zone())
Operator1<StrictMode>(IrOpcode::kJSStoreProperty, Operator::kNoProperties,

View File

@ -96,19 +96,40 @@ std::ostream& operator<<(std::ostream&, ContextAccess const&);
ContextAccess const& ContextAccessOf(Operator const*);
class VectorSlotPair {
public:
VectorSlotPair(Handle<TypeFeedbackVector> vector, int slot)
: vector_(vector), slot_(slot) {}
Handle<TypeFeedbackVector> vector() const { return vector_; }
int slot() const { return slot_; }
private:
const Handle<TypeFeedbackVector> vector_;
const int slot_;
};
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs);
// Defines the property being loaded from an object by a named load. This is
// used as a parameter by JSLoadNamed operators.
class LoadNamedParameters FINAL {
public:
LoadNamedParameters(const Unique<Name>& name, ContextualMode contextual_mode)
: name_(name), contextual_mode_(contextual_mode) {}
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
ContextualMode contextual_mode)
: name_(name), contextual_mode_(contextual_mode), feedback_(feedback) {}
const Unique<Name>& name() const { return name_; }
ContextualMode contextual_mode() const { return contextual_mode_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const Unique<Name> name_;
const ContextualMode contextual_mode_;
const VectorSlotPair feedback_;
};
bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
@ -121,6 +142,29 @@ std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
// Defines the property being loaded from an object. This is
// used as a parameter by JSLoadProperty operators.
class LoadPropertyParameters FINAL {
public:
explicit LoadPropertyParameters(const VectorSlotPair& feedback)
: feedback_(feedback) {}
const VectorSlotPair& feedback() const { return feedback_; }
private:
const VectorSlotPair feedback_;
};
bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
bool operator!=(LoadPropertyParameters const&, LoadPropertyParameters const&);
size_t hash_value(LoadPropertyParameters const&);
std::ostream& operator<<(std::ostream&, LoadPropertyParameters const&);
const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
// Defines the property being stored to an object by a named store. This is
// used as a parameter by JSStoreNamed operators.
class StoreNamedParameters FINAL {
@ -188,8 +232,9 @@ class JSOperatorBuilder FINAL {
const Operator* CallConstruct(int arguments);
const Operator* LoadProperty();
const Operator* LoadProperty(const VectorSlotPair& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreProperty(StrictMode strict_mode);

View File

@ -2849,7 +2849,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -2985,7 +2985,8 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3211,7 +3212,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -832,6 +832,32 @@ Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
}
Handle<Code> LoadIC::initialize_stub_in_optimized_code(
Isolate* isolate, ExtraICState extra_state) {
if (FLAG_vector_ics) {
return VectorLoadStub(isolate, LoadICState(extra_state)).GetCode();
}
return initialize_stub(isolate, extra_state);
}
Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
if (FLAG_vector_ics) {
return KeyedLoadICTrampolineStub(isolate).GetCode();
}
return isolate->builtins()->KeyedLoadIC_Initialize();
}
Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(Isolate* isolate) {
if (FLAG_vector_ics) {
return VectorKeyedLoadStub(isolate).GetCode();
}
return initialize_stub(isolate);
}
Handle<Code> LoadIC::megamorphic_stub() {
if (kind() == Code::LOAD_IC) {
MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state()));

View File

@ -353,6 +353,8 @@ class LoadIC : public IC {
static Handle<Code> initialize_stub(Isolate* isolate,
ExtraICState extra_state);
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, ExtraICState extra_state);
MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
Handle<Name> name);
@ -420,6 +422,8 @@ class KeyedLoadIC : public LoadIC {
static const int kSlowCaseBitFieldMask =
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
static Handle<Code> initialize_stub(Isolate* isolate);
static Handle<Code> initialize_stub_in_optimized_code(Isolate* isolate);
static Handle<Code> generic_stub(Isolate* isolate);
static Handle<Code> pre_monomorphic_stub(Isolate* isolate);

View File

@ -2908,7 +2908,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3035,7 +3035,8 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3343,7 +3344,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -2871,7 +2871,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
}
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3013,7 +3013,8 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
if (FLAG_vector_ics) {
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -3295,7 +3296,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
}
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}

View File

@ -69,7 +69,6 @@ const SharedOperator kSharedOperators[] = {
SHARED(ToObject, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
SHARED(Create, Operator::kEliminatable, 0, 0, 1, 0, 1, 1),
SHARED(LoadProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
SHARED(HasProperty, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0),
SHARED(InstanceOf, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),

View File

@ -78,6 +78,7 @@ 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);
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, kLength);
@ -87,8 +88,8 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
Node* node =
graph()->NewNode(javascript()->LoadProperty(), base, key, context);
Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
key, context);
if (FLAG_turbo_deoptimization) {
node->AppendInput(zone(), UndefinedConstant());
}