Index: src/compiler/js-generic-lowering.cc |
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc |
index c2d58018f8662f719b3d30e74275214287eb6d1a..638fbd7168ce16d42b46623f9b89ed1f59e54063 100644 |
--- a/src/compiler/js-generic-lowering.cc |
+++ b/src/compiler/js-generic-lowering.cc |
@@ -17,6 +17,19 @@ namespace v8 { |
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) {} |
@@ -52,11 +65,13 @@ Reduction JSGenericLowering::Reduce(Node* node) { |
} |
-#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) |
@@ -118,10 +133,6 @@ static CallDescriptor::Flags FlagsForNode(Node* node) { |
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()); |
@@ -141,6 +152,10 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) { |
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()); |
@@ -194,53 +209,64 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) { |
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); |
@@ -268,26 +294,32 @@ void JSGenericLowering::ReplaceWithRuntimeCall(Node* node, |
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); |
} |
@@ -307,6 +339,7 @@ void JSGenericLowering::LowerJSToObject(Node* node) { |
void JSGenericLowering::LowerJSLoadProperty(Node* node) { |
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); |
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op()); |
Callable callable = |
CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED); |
@@ -315,11 +348,13 @@ void JSGenericLowering::LowerJSLoadProperty(Node* node) { |
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 |
@@ -332,26 +367,31 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) { |
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); |
} |
@@ -373,8 +413,9 @@ void JSGenericLowering::LowerJSInstanceOf(Node* node) { |
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)); |
@@ -451,8 +492,9 @@ void JSGenericLowering::LowerJSCallConstruct(Node* node) { |
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); |
@@ -513,9 +555,9 @@ void JSGenericLowering::LowerJSCallFunction(Node* node) { |
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)); |