aboutsummaryrefslogtreecommitdiff
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.cc233
1 files changed, 144 insertions, 89 deletions
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc
index 4886442314..4720c582ec 100644
--- a/deps/v8/src/compiler/js-generic-lowering.cc
+++ b/deps/v8/src/compiler/js-generic-lowering.cc
@@ -5,32 +5,19 @@
#include "src/code-factory.h"
#include "src/code-stubs.h"
#include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
#include "src/compiler/js-generic-lowering.h"
#include "src/compiler/machine-operator.h"
-#include "src/compiler/node-aux-data-inl.h"
#include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
#include "src/unique.h"
namespace v8 {
namespace internal {
namespace compiler {
-JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph)
- : info_(info),
- jsgraph_(jsgraph),
- linkage_(new (jsgraph->zone()) Linkage(jsgraph->zone(), info)) {}
-
-
-void JSGenericLowering::PatchOperator(Node* node, const Operator* op) {
- node->set_op(op);
-}
-
-
-void JSGenericLowering::PatchInsertInput(Node* node, int index, Node* input) {
- node->InsertInput(zone(), index, input);
-}
+JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph)
+ : is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {}
Reduction JSGenericLowering::Reduce(Node* node) {
@@ -45,10 +32,13 @@ Reduction JSGenericLowering::Reduce(Node* node) {
// TODO(mstarzinger): If typing is enabled then simplified lowering will
// have inserted the correct ChangeBoolToBit, otherwise we need to perform
// poor-man's representation inference here and insert manual change.
- if (!info()->is_typing_enabled()) {
- Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
- jsgraph()->TrueConstant());
- node->ReplaceInput(0, test);
+ if (!is_typing_enabled_) {
+ Node* condition = node->InputAt(0);
+ if (condition->opcode() != IrOpcode::kAlways) {
+ Node* test = graph()->NewNode(machine()->WordEqual(), condition,
+ jsgraph()->TrueConstant());
+ node->ReplaceInput(0, test);
+ }
break;
}
// Fall-through.
@@ -101,7 +91,6 @@ REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE)
REPLACE_RUNTIME_CALL(JSTypeOf, Runtime::kTypeof)
REPLACE_RUNTIME_CALL(JSCreate, Runtime::kAbort)
REPLACE_RUNTIME_CALL(JSCreateFunctionContext, Runtime::kNewFunctionContext)
-REPLACE_RUNTIME_CALL(JSCreateCatchContext, Runtime::kPushCatchContext)
REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
REPLACE_RUNTIME_CALL(JSCreateBlockContext, Runtime::kPushBlockContext)
REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
@@ -111,7 +100,6 @@ REPLACE_RUNTIME_CALL(JSCreateScriptContext, Runtime::kAbort)
#define REPLACE_UNIMPLEMENTED(op) \
void JSGenericLowering::Lower##op(Node* node) { UNIMPLEMENTED(); }
-REPLACE_UNIMPLEMENTED(JSToName)
REPLACE_UNIMPLEMENTED(JSYield)
REPLACE_UNIMPLEMENTED(JSDebugger)
#undef REPLACE_UNIMPLEMENTED
@@ -128,10 +116,11 @@ static CallDescriptor::Flags FlagsForNode(Node* node) {
void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
Callable callable = CodeFactory::CompareIC(isolate(), token);
- bool has_frame_state = OperatorProperties::HasFrameStateInput(node->op());
- CallDescriptor* desc_compare = linkage()->GetStubCallDescriptor(
- callable.descriptor(), 0,
+ CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 0,
CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node));
+
+ // Create a new call node asking a CompareIC for help.
NodeVector inputs(zone());
inputs.reserve(node->InputCount() + 1);
inputs.push_back(jsgraph()->HeapConstant(callable.code()));
@@ -141,11 +130,12 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
if (node->op()->HasProperty(Operator::kPure)) {
// A pure (strict) comparison doesn't have an effect, control or frame
// state. But for the graph, we need to add control and effect inputs.
- DCHECK(!has_frame_state);
+ DCHECK(!OperatorProperties::HasFrameStateInput(node->op()));
inputs.push_back(graph()->start());
inputs.push_back(graph()->start());
} else {
- DCHECK(has_frame_state == FLAG_turbo_deoptimization);
+ DCHECK(OperatorProperties::HasFrameStateInput(node->op()) ==
+ FLAG_turbo_deoptimization);
if (FLAG_turbo_deoptimization) {
inputs.push_back(NodeProperties::GetFrameStateInput(node));
}
@@ -155,27 +145,65 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
Node* compare =
graph()->NewNode(common()->Call(desc_compare),
static_cast<int>(inputs.size()), &inputs.front());
-
- node->ReplaceInput(0, compare);
- node->ReplaceInput(1, jsgraph()->SmiConstant(token));
-
- if (has_frame_state) {
- // Remove the frame state from inputs.
- node->RemoveInput(NodeProperties::FirstFrameStateIndex(node));
+ NodeProperties::SetBounds(
+ compare, Bounds(Type::None(zone()), Type::UntaggedSigned(zone())));
+
+ // Decide how the return value from the above CompareIC can be converted into
+ // a JavaScript boolean oddball depending on the given token.
+ Node* false_value = jsgraph()->FalseConstant();
+ Node* true_value = jsgraph()->TrueConstant();
+ const Operator* op = nullptr;
+ switch (token) {
+ case Token::EQ: // a == 0
+ case Token::EQ_STRICT:
+ op = machine()->WordEqual();
+ break;
+ case Token::NE: // a != 0 becomes !(a == 0)
+ case Token::NE_STRICT:
+ op = machine()->WordEqual();
+ std::swap(true_value, false_value);
+ break;
+ case Token::LT: // a < 0
+ op = machine()->IntLessThan();
+ break;
+ case Token::GT: // a > 0 becomes !(a <= 0)
+ op = machine()->IntLessThanOrEqual();
+ std::swap(true_value, false_value);
+ break;
+ case Token::LTE: // a <= 0
+ op = machine()->IntLessThanOrEqual();
+ break;
+ case Token::GTE: // a >= 0 becomes !(a < 0)
+ op = machine()->IntLessThan();
+ std::swap(true_value, false_value);
+ break;
+ default:
+ UNREACHABLE();
}
-
- ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
+ Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant());
+
+ // Finally patch the original node to select a boolean.
+ NodeProperties::ReplaceWithValue(node, node, compare);
+ // TODO(mstarzinger): Just a work-around because SelectLowering might
+ // otherwise introduce a Phi without any uses, making Scheduler unhappy.
+ if (node->UseCount() == 0) return;
+ node->TrimInputCount(3);
+ node->ReplaceInput(0, booleanize);
+ node->ReplaceInput(1, true_value);
+ node->ReplaceInput(2, false_value);
+ node->set_op(common()->Select(kMachAnyTagged));
}
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags) {
Operator::Properties properties = node->op()->properties();
- CallDescriptor* desc = linkage()->GetStubCallDescriptor(
- callable.descriptor(), 0, flags | FlagsForNode(node), properties);
+ CallDescriptor* desc =
+ Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(),
+ 0, flags | FlagsForNode(node), properties);
Node* stub_code = jsgraph()->HeapConstant(callable.code());
- PatchInsertInput(node, 0, stub_code);
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, stub_code);
+ node->set_op(common()->Call(desc));
}
@@ -185,17 +213,27 @@ void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
Operator::Properties properties = node->op()->properties();
Callable callable =
CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
- CallDescriptor* desc = linkage()->GetStubCallDescriptor(
- callable.descriptor(), nargs, FlagsForNode(node), properties);
- // TODO(mstarzinger): Accessing the builtins object this way prevents sharing
- // of code across native contexts. Fix this by loading from given context.
- Handle<JSFunction> function(
- JSFunction::cast(info()->context()->builtins()->javascript_builtin(id)));
+ 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());
+ Node* builtins_object = graph()->NewNode(
+ machine()->Load(kMachAnyTagged), global_object,
+ jsgraph()->IntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag),
+ NodeProperties::GetEffectInput(node), graph()->start());
+ Node* function = graph()->NewNode(
+ machine()->Load(kMachAnyTagged), builtins_object,
+ jsgraph()->IntPtrConstant(JSBuiltinsObject::OffsetOfFunctionWithId(id) -
+ kHeapObjectTag),
+ NodeProperties::GetEffectInput(node), graph()->start());
Node* stub_code = jsgraph()->HeapConstant(callable.code());
- Node* function_node = jsgraph()->HeapConstant(function);
- PatchInsertInput(node, 0, stub_code);
- PatchInsertInput(node, 1, function_node);
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, stub_code);
+ node->InsertInput(zone(), 1, function);
+ node->set_op(common()->Call(desc));
}
@@ -206,13 +244,13 @@ void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
const Runtime::Function* fun = Runtime::FunctionForId(f);
int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
CallDescriptor* desc =
- linkage()->GetRuntimeCallDescriptor(f, nargs, properties);
+ Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties);
Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
Node* arity = jsgraph()->Int32Constant(nargs);
- PatchInsertInput(node, 0, jsgraph()->CEntryStubConstant(fun->result_size));
- PatchInsertInput(node, nargs + 1, ref);
- PatchInsertInput(node, nargs + 2, arity);
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
+ node->InsertInput(zone(), nargs + 1, ref);
+ node->InsertInput(zone(), nargs + 2, arity);
+ node->set_op(common()->Call(desc));
}
@@ -241,6 +279,11 @@ void JSGenericLowering::LowerJSToString(Node* node) {
}
+void JSGenericLowering::LowerJSToName(Node* node) {
+ ReplaceWithBuiltinCall(node, Builtins::TO_NAME, 1);
+}
+
+
void JSGenericLowering::LowerJSToObject(Node* node) {
ReplaceWithBuiltinCall(node, Builtins::TO_OBJECT, 1);
}
@@ -250,8 +293,9 @@ void JSGenericLowering::LowerJSLoadProperty(Node* node) {
const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
if (FLAG_vector_ics) {
- PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
- PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
+ node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
+ node->InsertInput(zone(), 3,
+ jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
@@ -261,34 +305,35 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable =
CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
- PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
+ node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_ics) {
- PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
- PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
+ node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
+ node->InsertInput(zone(), 3,
+ jsgraph()->HeapConstant(p.feedback().vector()));
}
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSStoreProperty(Node* node) {
- StrictMode strict_mode = OpParameter<StrictMode>(node);
- Callable callable = CodeFactory::KeyedStoreIC(isolate(), strict_mode);
+ LanguageMode language_mode = OpParameter<LanguageMode>(node);
+ Callable callable = CodeFactory::KeyedStoreIC(isolate(), language_mode);
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSStoreNamed(Node* node) {
const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
- Callable callable = CodeFactory::StoreIC(isolate(), p.strict_mode());
- PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
+ Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode());
+ node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
- StrictMode strict_mode = OpParameter<StrictMode>(node);
- PatchInsertInput(node, 2, jsgraph()->SmiConstant(strict_mode));
+ LanguageMode language_mode = OpParameter<LanguageMode>(node);
ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
+ node->InsertInput(zone(), 4, jsgraph()->SmiConstant(language_mode));
}
@@ -303,11 +348,11 @@ void JSGenericLowering::LowerJSInstanceOf(Node* node) {
InstanceofStub::kArgsInRegisters);
InstanceofStub stub(isolate(), flags);
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
- CallDescriptor* desc =
- linkage()->GetStubCallDescriptor(d, 0, FlagsForNode(node));
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(isolate(), zone(), d, 0,
+ FlagsForNode(node));
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
- PatchInsertInput(node, 0, stub_code);
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, stub_code);
+ node->set_op(common()->Call(desc));
}
@@ -325,7 +370,7 @@ void JSGenericLowering::LowerJSLoadContext(Node* node) {
node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
static_cast<int>(access.index()))));
node->AppendInput(zone(), graph()->start());
- PatchOperator(node, machine()->Load(kMachAnyTagged));
+ node->set_op(machine()->Load(kMachAnyTagged));
}
@@ -343,8 +388,15 @@ void JSGenericLowering::LowerJSStoreContext(Node* node) {
node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
static_cast<int>(access.index()))));
- PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged,
- kFullWriteBarrier)));
+ node->set_op(
+ machine()->Store(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier)));
+}
+
+
+void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
+ Unique<String> name = OpParameter<Unique<String>>(node);
+ node->InsertInput(zone(), 0, jsgraph()->HeapConstant(name));
+ ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext);
}
@@ -352,15 +404,15 @@ 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(d, arity, FlagsForNode(node));
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), d, arity, FlagsForNode(node));
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
Node* construct = NodeProperties::GetValueInput(node, 0);
- PatchInsertInput(node, 0, stub_code);
- PatchInsertInput(node, 1, jsgraph()->Int32Constant(arity - 1));
- PatchInsertInput(node, 2, construct);
- PatchInsertInput(node, 3, jsgraph()->UndefinedConstant());
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, stub_code);
+ node->InsertInput(zone(), 1, jsgraph()->Int32Constant(arity - 1));
+ node->InsertInput(zone(), 2, construct);
+ node->InsertInput(zone(), 3, jsgraph()->UndefinedConstant());
+ node->set_op(common()->Call(desc));
}
@@ -375,7 +427,9 @@ bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
Handle<Object> func = function_const.Value().handle();
if (!func->IsJSFunction()) return false; // not a function.
Handle<JSFunction> function = Handle<JSFunction>::cast(func);
- if (arg_count != function->shared()->formal_parameter_count()) return false;
+ if (arg_count != function->shared()->internal_formal_parameter_count()) {
+ return false;
+ }
// Check the receiver doesn't need to be wrapped.
Node* receiver = node->InputAt(1);
@@ -394,9 +448,9 @@ bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
context = jsgraph()->HeapConstant(Handle<Context>(function->context()));
}
node->ReplaceInput(index, context);
- CallDescriptor* desc = linkage()->GetJSCallDescriptor(
- 1 + arg_count, jsgraph()->zone(), FlagsForNode(node));
- PatchOperator(node, common()->Call(desc));
+ CallDescriptor* desc = Linkage::GetJSCallDescriptor(
+ zone(), false, 1 + arg_count, FlagsForNode(node));
+ node->set_op(common()->Call(desc));
return true;
}
@@ -410,11 +464,12 @@ 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* desc = linkage()->GetStubCallDescriptor(
- d, static_cast<int>(p.arity() - 1), FlagsForNode(node));
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), d, static_cast<int>(p.arity() - 1),
+ FlagsForNode(node));
Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
- PatchInsertInput(node, 0, stub_code);
- PatchOperator(node, common()->Call(desc));
+ node->InsertInput(zone(), 0, stub_code);
+ node->set_op(common()->Call(desc));
}