diff options
Diffstat (limited to 'deps/v8/src/compiler/js-generic-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/js-generic-lowering.cc | 125 |
1 files changed, 90 insertions, 35 deletions
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc index 81bafa6183..0b38bd538d 100644 --- a/deps/v8/src/compiler/js-generic-lowering.cc +++ b/deps/v8/src/compiler/js-generic-lowering.cc @@ -7,6 +7,7 @@ #include "src/ast/ast.h" #include "src/builtins/builtins-constructor.h" #include "src/codegen/code-factory.h" +#include "src/compiler/access-builder.h" #include "src/compiler/common-operator.h" #include "src/compiler/js-graph.h" #include "src/compiler/js-heap-broker.h" @@ -15,6 +16,7 @@ #include "src/compiler/node-properties.h" #include "src/compiler/operator-properties.h" #include "src/compiler/processed-feedback.h" +#include "src/compiler/simplified-operator.h" #include "src/objects/feedback-cell.h" #include "src/objects/feedback-vector.h" #include "src/objects/scope-info.h" @@ -316,8 +318,10 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) { } void JSGenericLowering::LowerJSLoadNamedFromSuper(Node* node) { + // TODO(marja, v8:9237): Call a builtin which collects feedback. JSLoadNamedFromSuperNode n(node); NamedAccess const& p = n.Parameters(); + node->RemoveInput(2); // Feedback vector node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.name())); ReplaceWithRuntimeCall(node, Runtime::kLoadFromSuper); } @@ -480,7 +484,21 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) { } void JSGenericLowering::LowerJSGetSuperConstructor(Node* node) { - ReplaceWithBuiltinCall(node, Builtins::kGetSuperConstructor); + Node* active_function = NodeProperties::GetValueInput(node, 0); + Node* effect = NodeProperties::GetEffectInput(node); + Node* control = NodeProperties::GetControlInput(node); + + Node* function_map = effect = graph()->NewNode( + jsgraph()->simplified()->LoadField(AccessBuilder::ForMap()), + active_function, effect, control); + + RelaxControls(node); + node->ReplaceInput(0, function_map); + node->ReplaceInput(1, effect); + node->ReplaceInput(2, control); + node->TrimInputCount(3); + NodeProperties::ChangeOp(node, jsgraph()->simplified()->LoadField( + AccessBuilder::ForMapPrototype())); } void JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) { @@ -828,9 +846,7 @@ void JSGenericLowering::LowerJSConstruct(Node* node) { Node* stub_arity = jsgraph()->Int32Constant(arg_count); Node* slot = jsgraph()->Int32Constant(p.feedback().index()); Node* receiver = jsgraph()->UndefinedConstant(); -#ifdef V8_REVERSE_JSARGS Node* feedback_vector = node->RemoveInput(n.FeedbackVectorIndex()); -#endif // Register argument inputs are followed by stack argument inputs (such as // feedback_vector). Both are listed in ascending order. Note that // the receiver is implicitly placed on the stack and is thus inserted @@ -839,16 +855,10 @@ void JSGenericLowering::LowerJSConstruct(Node* node) { node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 3, stub_arity); node->InsertInput(zone(), 4, slot); -#ifdef V8_REVERSE_JSARGS node->InsertInput(zone(), 5, feedback_vector); node->InsertInput(zone(), 6, receiver); // After: {code, target, new_target, arity, slot, vector, receiver, // ...args}. -#else - node->InsertInput(zone(), 5, receiver); - // After: {code, target, new_target, arity, slot, receiver, ...args, - // vector}. -#endif NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); } else { @@ -897,9 +907,7 @@ void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) { Node* stub_code = jsgraph()->HeapConstant(callable.code()); Node* receiver = jsgraph()->UndefinedConstant(); Node* slot = jsgraph()->Int32Constant(p.feedback().index()); -#ifdef V8_REVERSE_JSARGS Node* feedback_vector = node->RemoveInput(n.FeedbackVectorIndex()); -#endif // Register argument inputs are followed by stack argument inputs (such as // feedback_vector). Both are listed in ascending order. Note that // the receiver is implicitly placed on the stack and is thus inserted @@ -907,16 +915,10 @@ void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) { // TODO(jgruber): Implement a simpler way to specify these mutations. node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 4, slot); -#ifdef V8_REVERSE_JSARGS node->InsertInput(zone(), 5, feedback_vector); node->InsertInput(zone(), 6, receiver); // After: {code, target, new_target, arguments_list, slot, vector, // receiver}. -#else - node->InsertInput(zone(), 5, receiver); - // After: {code, target, new_target, arguments_list, slot, receiver, - // vector}. -#endif NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); } else { @@ -972,10 +974,8 @@ void JSGenericLowering::LowerJSConstructWithSpread(Node* node) { // on the stack here. Node* stub_arity = jsgraph()->Int32Constant(arg_count - kTheSpread); Node* receiver = jsgraph()->UndefinedConstant(); -#ifdef V8_REVERSE_JSARGS Node* feedback_vector = node->RemoveInput(n.FeedbackVectorIndex()); Node* spread = node->RemoveInput(n.LastArgumentIndex()); -#endif // Register argument inputs are followed by stack argument inputs (such as // feedback_vector). Both are listed in ascending order. Note that @@ -985,17 +985,11 @@ void JSGenericLowering::LowerJSConstructWithSpread(Node* node) { node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 3, stub_arity); node->InsertInput(zone(), 4, slot); -#ifdef V8_REVERSE_JSARGS node->InsertInput(zone(), 5, spread); node->InsertInput(zone(), 6, feedback_vector); node->InsertInput(zone(), 7, receiver); // After: {code, target, new_target, arity, slot, spread, vector, receiver, // ...args}. -#else - node->InsertInput(zone(), 5, receiver); - // After: {code, target, new_target, arity, slot, receiver, ...args, spread, - // vector}. -#endif NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); } else { @@ -1179,20 +1173,14 @@ void JSGenericLowering::LowerJSCallWithSpread(Node* node) { // Shuffling inputs. // Before: {target, receiver, ...args, spread, vector}. -#ifdef V8_REVERSE_JSARGS Node* feedback_vector = node->RemoveInput(n.FeedbackVectorIndex()); -#endif Node* spread = node->RemoveInput(n.LastArgumentIndex()); node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 2, stub_arity); node->InsertInput(zone(), 3, spread); node->InsertInput(zone(), 4, slot); -#ifdef V8_REVERSE_JSARGS node->InsertInput(zone(), 5, feedback_vector); // After: {code, target, arity, spread, slot, vector, receiver, ...args}. -#else - // After: {code, target, arity, spread, slot, receiver, ...args, vector}. -#endif NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); } else { @@ -1230,12 +1218,79 @@ void JSGenericLowering::LowerJSCallRuntime(Node* node) { ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); } -void JSGenericLowering::LowerJSForInNext(Node* node) { - UNREACHABLE(); // Eliminated in typed lowering. +void JSGenericLowering::LowerJSForInPrepare(Node* node) { + JSForInPrepareNode n(node); + Effect effect(node); // {node} is kept in the effect chain. + Control control = n.control(); // .. but not in the control chain. + Node* enumerator = n.enumerator(); + Node* slot = + jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt()); + + std::vector<Edge> use_edges; + for (Edge edge : node->use_edges()) use_edges.push_back(edge); + + // {node} will be changed to a builtin call (see below). The returned value + // is a fixed array containing {cache_array} and {cache_length}. + // TODO(jgruber): This is awkward; what we really want is two return values, + // the {cache_array} and {cache_length}, or better yet three return values + // s.t. we can avoid the graph rewrites below. Builtin support for multiple + // return types is unclear though. + + Node* result_fixed_array = node; + Node* cache_type = enumerator; // Just to clarify the rename. + Node* cache_array; + Node* cache_length; + + cache_array = effect = graph()->NewNode( + machine()->Load(MachineType::AnyTagged()), result_fixed_array, + jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(0) - + kHeapObjectTag), + effect, control); + cache_length = effect = graph()->NewNode( + machine()->Load(MachineType::AnyTagged()), result_fixed_array, + jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(1) - + kHeapObjectTag), + effect, control); + + // Update the uses of {node}. + for (Edge edge : use_edges) { + Node* const user = edge.from(); + if (NodeProperties::IsEffectEdge(edge)) { + edge.UpdateTo(effect); + } else if (NodeProperties::IsControlEdge(edge)) { + edge.UpdateTo(control); + } else { + DCHECK(NodeProperties::IsValueEdge(edge)); + switch (ProjectionIndexOf(user->op())) { + case 0: + Replace(user, cache_type); + break; + case 1: + Replace(user, cache_array); + break; + case 2: + Replace(user, cache_length); + break; + default: + UNREACHABLE(); + } + } + } + + // Finally, change the original node into a builtin call. This happens here, + // after graph rewrites, since the Call does not have a control output and + // thus must not have any control uses. Any previously existing control + // outputs have been replaced by the graph rewrite above. + node->InsertInput(zone(), n.FeedbackVectorIndex(), slot); + ReplaceWithBuiltinCall(node, Builtins::kForInPrepare); } -void JSGenericLowering::LowerJSForInPrepare(Node* node) { - UNREACHABLE(); // Eliminated in typed lowering. +void JSGenericLowering::LowerJSForInNext(Node* node) { + JSForInNextNode n(node); + node->InsertInput( + zone(), 0, + jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt())); + ReplaceWithBuiltinCall(node, Builtins::kForInNext); } void JSGenericLowering::LowerJSLoadMessage(Node* node) { |