summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/js-generic-lowering.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/js-generic-lowering.cc')
-rw-r--r--deps/v8/src/compiler/js-generic-lowering.cc125
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) {