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