}
+// Gets the bailout id just before reading a variable proxy, but only for
+// unallocated variables.
+static BailoutId BeforeId(VariableProxy* proxy) {
+ return proxy->var()->location() == Variable::UNALLOCATED ? proxy->BeforeId()
+ : BailoutId::None();
+}
+
+
static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) {
#if DEBUG
const AstRawString* name = scope->parameter(index)->raw_name();
if (expr->scope() != NULL) {
DCHECK_NOT_NULL(expr->class_variable_proxy());
Variable* var = expr->class_variable_proxy()->var();
- BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ BuildVariableAssignment(states, var, literal, Token::INIT_CONST,
+ BailoutId::None());
}
ast_context()->ProduceValue(literal);
void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
- Node* value = BuildVariableLoad(expr->var(), expr->id(), pair);
+ FrameStateBeforeAndAfter states(this, BeforeId(expr));
+ Node* value = BuildVariableLoad(states, expr->var(), expr->id(), pair,
+ ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForValue(property->value());
+ FrameStateBeforeAndAfter states(this, property->value()->id());
Node* value = environment()->Pop();
Handle<Name> name = key->AsPropertyName();
Node* store =
BuildNamedStore(literal, name, value, TypeFeedbackId::None());
- PrepareFrameState(store, key->id());
+ states.AddToNode(store, key->id(),
+ OutputFrameStateCombine::Ignore());
BuildSetHomeObject(value, literal, property->value());
} else {
VisitForEffect(property->value());
switch (assign_type) {
case VARIABLE: {
Variable* var = expr->AsVariableProxy()->var();
- BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id);
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ BuildVariableAssignment(states, var, value, Token::ASSIGN, bailout_id);
break;
}
case NAMED_PROPERTY: {
environment()->Push(value);
VisitForValue(property->obj());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
Node* object = environment()->Pop();
value = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store =
BuildNamedStore(object, name, value, TypeFeedbackId::None());
- PrepareFrameState(store, bailout_id);
+ states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
break;
}
case KEYED_PROPERTY: {
environment()->Push(value);
VisitForValue(property->obj());
VisitForValue(property->key());
- {
- // TODO(jarin) Provide a real frame state before.
- FrameStateBeforeAndAfter states(this, BailoutId::None());
- Node* key = environment()->Pop();
- Node* object = environment()->Pop();
- value = environment()->Pop();
- Node* store =
- BuildKeyedStore(object, key, value, TypeFeedbackId::None());
- states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
- }
+ FrameStateBeforeAndAfter states(this, property->key()->id());
+ Node* key = environment()->Pop();
+ Node* object = environment()->Pop();
+ value = environment()->Pop();
+ Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None());
+ states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
break;
}
}
VariableProxy* proxy = expr->target()->AsVariableProxy();
VectorSlotPair pair =
CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
+ FrameStateBeforeAndAfter states(this, BeforeId(proxy));
+ old_value =
+ BuildVariableLoad(states, proxy->var(), expr->target()->id(), pair,
+ OutputFrameStateCombine::Push());
break;
}
case NAMED_PROPERTY: {
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
old_value =
BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
- PrepareFrameState(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
case KEYED_PROPERTY: {
Node* object = environment()->Peek(1);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
old_value =
BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
- PrepareFrameState(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
}
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
- BuildVariableAssignment(variable, value, expr->op(), expr->id(),
- ast_context()->GetStateCombine());
+ BuildVariableAssignment(store_states, variable, value, expr->op(),
+ expr->id(), ast_context()->GetStateCombine());
break;
}
case NAMED_PROPERTY: {
VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
if (expr->key()->IsPropertyName()) {
VisitForValue(expr->obj());
+ FrameStateBeforeAndAfter states(this, expr->obj()->id());
Node* object = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedLoad(object, name, pair, expr->PropertyFeedbackId());
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
} else {
VisitForValue(expr->obj());
VisitForValue(expr->key());
+ FrameStateBeforeAndAfter states(this, expr->key()->id());
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = BuildKeyedLoad(object, key, pair, expr->PropertyFeedbackId());
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
}
- PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
case Call::GLOBAL_CALL: {
VariableProxy* proxy = callee->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, BeforeId(proxy));
callee_value =
- BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
+ BuildVariableLoad(states, proxy->var(), expr->expression()->id(),
+ pair, OutputFrameStateCombine::Push());
receiver_value = jsgraph()->UndefinedConstant();
break;
}
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
if (property->key()->IsPropertyName()) {
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
callee_value =
BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
} else {
VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
Node* key = environment()->Pop();
callee_value =
BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
}
- PrepareFrameState(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
receiver_value = environment()->Pop();
// Note that a PROPERTY_CALL requires the receiver to be wrapped into an
// object for sloppy callees. This could also be modeled explicitly here,
CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
Node* receiver_value = BuildLoadBuiltinsObject();
VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
+ // TODO(jarin): bailout ids for runtime calls.
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
Node* callee_value =
BuildNamedLoad(receiver_value, name, pair, expr->CallRuntimeFeedbackId());
- // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
- // refuses to optimize functions with jsruntime calls).
- PrepareFrameState(callee_value, BailoutId::None(),
- OutputFrameStateCombine::Push());
+ states.AddToNode(callee_value, BailoutId::None(),
+ OutputFrameStateCombine::Push());
environment()->Push(callee_value);
environment()->Push(receiver_value);
case VARIABLE: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, BeforeId(proxy));
old_value =
- BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
+ BuildVariableLoad(states, proxy->var(), expr->expression()->id(),
+ pair, OutputFrameStateCombine::Push());
stack_depth = 0;
break;
}
case NAMED_PROPERTY: {
VisitForValue(property->obj());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
Node* object = environment()->Top();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value =
BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
- PrepareFrameState(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 1;
break;
}
case KEYED_PROPERTY: {
VisitForValue(property->obj());
VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value =
BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
- PrepareFrameState(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 2;
break;
}
case VARIABLE: {
Variable* variable = expr->expression()->AsVariableProxy()->var();
environment()->Push(value);
- BuildVariableAssignment(variable, value, expr->op(),
+ BuildVariableAssignment(store_states, variable, value, expr->op(),
expr->AssignmentId());
environment()->Pop();
break;
Node* store =
BuildNamedStore(object, name, value, expr->CountStoreFeedbackId());
environment()->Push(value);
- PrepareFrameState(store, expr->AssignmentId());
+ store_states.AddToNode(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
// perform a non-contextual load in case the operand is a variable proxy.
VariableProxy* proxy = expr->expression()->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair,
- NOT_CONTEXTUAL);
+ FrameStateBeforeAndAfter states(this, BeforeId(proxy));
+ operand =
+ BuildVariableLoad(states, proxy->var(), expr->expression()->id(), pair,
+ OutputFrameStateCombine::Push(), NOT_CONTEXTUAL);
} else {
VisitForValue(expr->expression());
operand = environment()->Pop();
// Assign the object to the arguments variable.
DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
// This should never lazy deopt, so it is fine to send invalid bailout id.
- BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ BuildVariableAssignment(states, arguments, object, Token::ASSIGN,
+ BailoutId::None());
return object;
}
// Assign the object to the rest array
DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
// This should never lazy deopt, so it is fine to send invalid bailout id.
- BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None());
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ BuildVariableAssignment(states, rest, object, Token::ASSIGN,
+ BailoutId::None());
return object;
}
}
-Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
+Node* AstGraphBuilder::BuildVariableLoad(FrameStateBeforeAndAfter& states,
+ Variable* variable,
BailoutId bailout_id,
const VectorSlotPair& feedback,
+ OutputFrameStateCombine combine,
ContextualMode contextual_mode) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
Handle<Name> name = variable->name();
Node* node = BuildNamedLoad(global, name, feedback,
TypeFeedbackId::None(), contextual_mode);
- PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
+ states.AddToNode(node, bailout_id, combine);
return node;
}
case Variable::PARAMETER:
}
-Node* AstGraphBuilder::BuildVariableDelete(
- Variable* variable, BailoutId bailout_id,
- OutputFrameStateCombine state_combine) {
+Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
+ BailoutId bailout_id,
+ OutputFrameStateCombine combine) {
switch (variable->location()) {
case Variable::UNALLOCATED: {
// Global var, const, or let variable.
Node* name = jsgraph()->Constant(variable->name());
const Operator* op = javascript()->DeleteProperty(language_mode());
Node* result = NewNode(op, global, name);
- PrepareFrameState(result, bailout_id, state_combine);
+ PrepareFrameState(result, bailout_id, combine);
return result;
}
case Variable::PARAMETER:
const Operator* op =
javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
Node* result = NewNode(op, current_context(), name);
- PrepareFrameState(result, bailout_id, state_combine);
+ PrepareFrameState(result, bailout_id, combine);
return result;
}
}
Node* AstGraphBuilder::BuildVariableAssignment(
- Variable* variable, Node* value, Token::Value op, BailoutId bailout_id,
- OutputFrameStateCombine combine) {
+ FrameStateBeforeAndAfter& states, Variable* variable, Node* value,
+ Token::Value op, BailoutId bailout_id, OutputFrameStateCombine combine) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
switch (variable->location()) {
Handle<Name> name = variable->name();
Node* store =
BuildNamedStore(global, name, value, TypeFeedbackId::None());
- PrepareFrameState(store, bailout_id, combine);
+ states.AddToNode(store, bailout_id, combine);
return store;
}
case Variable::PARAMETER:
Expression* expr) {
if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
Handle<Name> name = isolate()->factory()->home_object_symbol();
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
Node* store =
BuildNamedStore(value, name, home_object, TypeFeedbackId::None());
- PrepareFrameState(store, BailoutId::None());
+ states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
return store;
}
namespace internal {
namespace compiler {
+static CallDescriptor::Flags AdjustFrameStatesForCall(Node* node) {
+ int count = OperatorProperties::GetFrameStateInputCount(node->op());
+ if (count > 1) {
+ int index = NodeProperties::FirstFrameStateIndex(node) + 1;
+ do {
+ node->RemoveInput(index);
+ } while (--count > 1);
+ }
+ return count > 0 ? CallDescriptor::kNeedsFrameState
+ : CallDescriptor::kNoFlags;
+}
+
+
JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph)
: is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {}
}
-#define REPLACE_BINARY_OP_IC_CALL(op, token) \
- void JSGenericLowering::Lower##op(Node* node) { \
- ReplaceWithStubCall(node, CodeFactory::BinaryOpIC(isolate(), token, \
- OpParameter<LanguageMode>(node)), \
- CallDescriptor::kPatchableCallSiteWithNop); \
+#define REPLACE_BINARY_OP_IC_CALL(op, token) \
+ void JSGenericLowering::Lower##op(Node* node) { \
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
+ ReplaceWithStubCall( \
+ node, CodeFactory::BinaryOpIC(isolate(), token, \
+ OpParameter<LanguageMode>(node)), \
+ CallDescriptor::kPatchableCallSiteWithNop | flags); \
}
REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
Callable callable =
CodeFactory::CompareIC(isolate(), token, OpParameter<LanguageMode>(node));
- CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
- isolate(), zone(), callable.descriptor(), 0,
- CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node),
- Operator::kNoProperties, kMachIntPtr);
// Create a new call node asking a CompareIC for help.
NodeVector inputs(zone());
inputs.push_back(NodeProperties::GetEffectInput(node));
inputs.push_back(NodeProperties::GetControlInput(node));
}
+ CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 0,
+ CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node),
+ Operator::kNoProperties, kMachIntPtr);
Node* compare =
graph()->NewNode(common()->Call(desc_compare),
static_cast<int>(inputs.size()), &inputs.front());
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags) {
- Operator::Properties properties = node->op()->properties();
- flags |= FlagsForNode(node);
+ const Operator* old_op = node->op();
+ Operator::Properties properties = old_op->properties();
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, flags, properties);
const Operator* new_op = common()->Call(desc);
- // Take care of frame states.
- int old_frame_state_count =
- OperatorProperties::GetFrameStateInputCount(node->op());
- int new_frame_state_count =
- (flags & CallDescriptor::kNeedsFrameState) ? 1 : 0;
- DCHECK_GE(old_frame_state_count, new_frame_state_count);
- // If there are extra frame states, get rid of them.
- for (int i = new_frame_state_count; i < old_frame_state_count; i++) {
- node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) +
- new_frame_state_count);
- }
-
Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code);
node->set_op(new_op);
+
+#if 0 && DEBUG
+ // Check for at most one framestate and that it's at the right position.
+ int where = -1;
+ for (int index = 0; index < node->InputCount(); index++) {
+ if (node->InputAt(index)->opcode() == IrOpcode::kFrameState) {
+ if (where >= 0) {
+ V8_Fatal(__FILE__, __LINE__,
+ "node #%d:%s already has a framestate at index %d",
+ node->id(), node->op()->mnemonic(), where);
+ }
+ where = index;
+ DCHECK_EQ(NodeProperties::FirstFrameStateIndex(node), where);
+ DCHECK(flags & CallDescriptor::kNeedsFrameState);
+ }
+ }
+ if (flags & CallDescriptor::kNeedsFrameState) {
+ DCHECK_GE(where, 0); // should have found a frame state.
+ }
+#endif
}
void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
Builtins::JavaScript id,
int nargs) {
+ Node* context_input = NodeProperties::GetContextInput(node);
+ Node* effect_input = NodeProperties::GetEffectInput(node);
+
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
Operator::Properties properties = node->op()->properties();
Callable callable =
CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
- CallDescriptor* desc =
- Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(),
- nargs, FlagsForNode(node), properties);
- Node* global_object = graph()->NewNode(
- machine()->Load(kMachAnyTagged), NodeProperties::GetContextInput(node),
- jsgraph()->IntPtrConstant(
- Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)),
- NodeProperties::GetEffectInput(node), graph()->start());
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), nargs, flags, properties);
+ Node* global_object =
+ graph()->NewNode(machine()->Load(kMachAnyTagged), context_input,
+ jsgraph()->IntPtrConstant(
+ Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)),
+ effect_input, graph()->start());
Node* builtins_object = graph()->NewNode(
machine()->Load(kMachAnyTagged), global_object,
jsgraph()->IntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag),
- NodeProperties::GetEffectInput(node), graph()->start());
+ effect_input, graph()->start());
Node* function = graph()->NewNode(
machine()->Load(kMachAnyTagged), builtins_object,
jsgraph()->IntPtrConstant(JSBuiltinsObject::OffsetOfFunctionWithId(id) -
kHeapObjectTag),
- NodeProperties::GetEffectInput(node), graph()->start());
+ effect_input, graph()->start());
Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code);
node->InsertInput(zone(), 1, function);
void JSGenericLowering::LowerJSUnaryNot(Node* node) {
Callable callable = CodeFactory::ToBoolean(
isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL);
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSTypeOf(Node* node) {
Callable callable = CodeFactory::Typeof(isolate());
- ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags);
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+ ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSToBoolean(Node* node) {
Callable callable =
CodeFactory::ToBoolean(isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSToNumber(Node* node) {
Callable callable = CodeFactory::ToNumber(isolate());
- ReplaceWithStubCall(node, callable, FlagsForNode(node));
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+ ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
Callable callable =
CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
node->InsertInput(zone(), 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSLoadNamed(Node* node) {
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable =
p.load_ic() == NAMED
node->InsertInput(zone(), 3,
jsgraph()->HeapConstant(p.feedback().vector()));
}
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSStoreProperty(Node* node) {
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
LanguageMode language_mode = OpParameter<LanguageMode>(node);
Callable callable = CodeFactory::KeyedStoreICInOptimizedCode(
isolate(), language_mode, UNINITIALIZED);
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSStoreNamed(Node* node) {
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
Callable callable = p.store_ic() == NAMED
? CodeFactory::StoreIC(isolate(), p.language_mode())
: CodeFactory::KeyedStoreICInOptimizedCode(
isolate(), p.language_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
- ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+ ReplaceWithStubCall(node, callable,
+ CallDescriptor::kPatchableCallSite | flags);
}
InstanceofStub::kArgsInRegisters);
InstanceofStub stub(isolate(), flags);
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(isolate(), zone(), d, 0,
- FlagsForNode(node));
+ CallDescriptor::Flags desc_flags = AdjustFrameStatesForCall(node);
+ CallDescriptor* desc =
+ Linkage::GetStubCallDescriptor(isolate(), zone(), d, 0, desc_flags);
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
node->InsertInput(zone(), 0, stub_code);
node->set_op(common()->Call(desc));
int arity = OpParameter<int>(node);
CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- isolate(), zone(), d, arity, FlagsForNode(node));
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+ CallDescriptor* desc =
+ Linkage::GetStubCallDescriptor(isolate(), zone(), d, arity, flags);
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
Node* construct = NodeProperties::GetValueInput(node, 0);
node->InsertInput(zone(), 0, stub_code);
int arg_count = static_cast<int>(p.arity() - 2);
CallFunctionStub stub(isolate(), arg_count, p.flags());
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- isolate(), zone(), d, static_cast<int>(p.arity() - 1),
- FlagsForNode(node));
+ isolate(), zone(), d, static_cast<int>(p.arity() - 1), flags);
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
node->InsertInput(zone(), 0, stub_code);
node->set_op(common()->Call(desc));