Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc
index 300604e..4886442 100644
--- a/src/compiler/js-generic-lowering.cc
+++ b/src/compiler/js-generic-lowering.cc
@@ -9,6 +9,7 @@
#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/unique.h"
@@ -19,7 +20,7 @@
JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph)
: info_(info),
jsgraph_(jsgraph),
- linkage_(new (jsgraph->zone()) Linkage(info)) {}
+ linkage_(new (jsgraph->zone()) Linkage(jsgraph->zone(), info)) {}
void JSGenericLowering::PatchOperator(Node* node, const Operator* op) {
@@ -32,40 +33,25 @@
}
-Node* JSGenericLowering::SmiConstant(int32_t immediate) {
- return jsgraph()->SmiConstant(immediate);
-}
-
-
-Node* JSGenericLowering::Int32Constant(int immediate) {
- return jsgraph()->Int32Constant(immediate);
-}
-
-
-Node* JSGenericLowering::CodeConstant(Handle<Code> code) {
- return jsgraph()->HeapConstant(code);
-}
-
-
-Node* JSGenericLowering::FunctionConstant(Handle<JSFunction> function) {
- return jsgraph()->HeapConstant(function);
-}
-
-
-Node* JSGenericLowering::ExternalConstant(ExternalReference ref) {
- return jsgraph()->ExternalConstant(ref);
-}
-
-
Reduction JSGenericLowering::Reduce(Node* node) {
switch (node->opcode()) {
-#define DECLARE_CASE(x) \
- case IrOpcode::k##x: \
- Lower##x(node); \
- break;
- DECLARE_CASE(Branch)
+#define DECLARE_CASE(x) \
+ case IrOpcode::k##x: \
+ Lower##x(node); \
+ break;
JS_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
+ case IrOpcode::kBranch:
+ // 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);
+ break;
+ }
+ // Fall-through.
default:
// Nothing to see.
return NoChange();
@@ -93,18 +79,18 @@
#undef REPLACE_BINARY_OP_IC_CALL
-#define REPLACE_COMPARE_IC_CALL(op, token, pure) \
+#define REPLACE_COMPARE_IC_CALL(op, token) \
void JSGenericLowering::Lower##op(Node* node) { \
- ReplaceWithCompareIC(node, token, pure); \
+ ReplaceWithCompareIC(node, token); \
}
-REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ, false)
-REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE, false)
-REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT, true)
-REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT, true)
-REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT, false)
-REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT, false)
-REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE, false)
-REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE, false)
+REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ)
+REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE)
+REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT)
+REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT)
+REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT)
+REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT)
+REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE)
+REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE)
#undef REPLACE_COMPARE_IC_CALL
@@ -119,7 +105,7 @@
REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
REPLACE_RUNTIME_CALL(JSCreateBlockContext, Runtime::kPushBlockContext)
REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
-REPLACE_RUNTIME_CALL(JSCreateGlobalContext, Runtime::kAbort)
+REPLACE_RUNTIME_CALL(JSCreateScriptContext, Runtime::kAbort)
#undef REPLACE_RUNTIME
@@ -140,8 +126,7 @@
}
-void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token,
- bool pure) {
+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(
@@ -149,11 +134,11 @@
CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node));
NodeVector inputs(zone());
inputs.reserve(node->InputCount() + 1);
- inputs.push_back(CodeConstant(callable.code()));
+ inputs.push_back(jsgraph()->HeapConstant(callable.code()));
inputs.push_back(NodeProperties::GetValueInput(node, 0));
inputs.push_back(NodeProperties::GetValueInput(node, 1));
inputs.push_back(NodeProperties::GetContextInput(node));
- if (pure) {
+ 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);
@@ -172,7 +157,7 @@
static_cast<int>(inputs.size()), &inputs.front());
node->ReplaceInput(0, compare);
- node->ReplaceInput(1, SmiConstant(token));
+ node->ReplaceInput(1, jsgraph()->SmiConstant(token));
if (has_frame_state) {
// Remove the frame state from inputs.
@@ -185,9 +170,10 @@
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));
- Node* stub_code = CodeConstant(callable.code());
+ callable.descriptor(), 0, flags | FlagsForNode(node), properties);
+ Node* stub_code = jsgraph()->HeapConstant(callable.code());
PatchInsertInput(node, 0, stub_code);
PatchOperator(node, common()->Call(desc));
}
@@ -196,16 +182,17 @@
void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
Builtins::JavaScript id,
int nargs) {
+ Operator::Properties properties = node->op()->properties();
Callable callable =
CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
- CallDescriptor* desc =
- linkage()->GetStubCallDescriptor(callable.descriptor(), nargs);
+ 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)));
- Node* stub_code = CodeConstant(callable.code());
- Node* function_node = FunctionConstant(function);
+ 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));
@@ -220,30 +207,15 @@
int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
CallDescriptor* desc =
linkage()->GetRuntimeCallDescriptor(f, nargs, properties);
- Node* ref = ExternalConstant(ExternalReference(f, isolate()));
- Node* arity = Int32Constant(nargs);
- if (!centrystub_constant_.is_set()) {
- centrystub_constant_.set(CodeConstant(CEntryStub(isolate(), 1).GetCode()));
- }
- PatchInsertInput(node, 0, centrystub_constant_.get());
+ 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));
}
-void JSGenericLowering::LowerBranch(Node* node) {
- if (!info()->is_typing_enabled()) {
- // 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.
- Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
- jsgraph()->TrueConstant());
- node->ReplaceInput(0, test);
- }
-}
-
-
void JSGenericLowering::LowerJSUnaryNot(Node* node) {
Callable callable = CodeFactory::ToBoolean(
isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL);
@@ -260,7 +232,7 @@
void JSGenericLowering::LowerJSToNumber(Node* node) {
Callable callable = CodeFactory::ToNumber(isolate());
- ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags);
+ ReplaceWithStubCall(node, callable, FlagsForNode(node));
}
@@ -275,15 +247,25 @@
void JSGenericLowering::LowerJSLoadProperty(Node* node) {
- Callable callable = CodeFactory::KeyedLoadIC(isolate());
+ 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()));
+ }
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSLoadNamed(Node* node) {
- LoadNamedParameters p = OpParameter<LoadNamedParameters>(node);
- Callable callable = CodeFactory::LoadIC(isolate(), p.contextual_mode);
- PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name));
+ const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
+ Callable callable =
+ CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
+ PatchInsertInput(node, 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()));
+ }
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
@@ -296,16 +278,16 @@
void JSGenericLowering::LowerJSStoreNamed(Node* node) {
- StoreNamedParameters params = OpParameter<StoreNamedParameters>(node);
- Callable callable = CodeFactory::StoreIC(isolate(), params.strict_mode);
- PatchInsertInput(node, 1, jsgraph()->HeapConstant(params.name));
+ const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
+ Callable callable = CodeFactory::StoreIC(isolate(), p.strict_mode());
+ PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
}
void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
StrictMode strict_mode = OpParameter<StrictMode>(node);
- PatchInsertInput(node, 2, SmiConstant(strict_mode));
+ PatchInsertInput(node, 2, jsgraph()->SmiConstant(strict_mode));
ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
}
@@ -321,44 +303,46 @@
InstanceofStub::kArgsInRegisters);
InstanceofStub stub(isolate(), flags);
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
- CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, 0);
- Node* stub_code = CodeConstant(stub.GetCode());
+ CallDescriptor* desc =
+ linkage()->GetStubCallDescriptor(d, 0, FlagsForNode(node));
+ Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
PatchInsertInput(node, 0, stub_code);
PatchOperator(node, common()->Call(desc));
}
void JSGenericLowering::LowerJSLoadContext(Node* node) {
- ContextAccess access = OpParameter<ContextAccess>(node);
- // TODO(mstarzinger): Use simplified operators instead of machine operators
- // here so that load/store optimization can be applied afterwards.
- for (int i = 0; i < access.depth(); ++i) {
+ const ContextAccess& access = ContextAccessOf(node->op());
+ for (size_t i = 0; i < access.depth(); ++i) {
node->ReplaceInput(
- 0, graph()->NewNode(
- machine()->Load(kMachAnyTagged),
- NodeProperties::GetValueInput(node, 0),
- Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
- NodeProperties::GetEffectInput(node)));
+ 0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+ NodeProperties::GetValueInput(node, 0),
+ jsgraph()->Int32Constant(
+ Context::SlotOffset(Context::PREVIOUS_INDEX)),
+ NodeProperties::GetEffectInput(node),
+ graph()->start()));
}
- node->ReplaceInput(1, Int32Constant(Context::SlotOffset(access.index())));
+ node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
+ static_cast<int>(access.index()))));
+ node->AppendInput(zone(), graph()->start());
PatchOperator(node, machine()->Load(kMachAnyTagged));
}
void JSGenericLowering::LowerJSStoreContext(Node* node) {
- ContextAccess access = OpParameter<ContextAccess>(node);
- // TODO(mstarzinger): Use simplified operators instead of machine operators
- // here so that load/store optimization can be applied afterwards.
- for (int i = 0; i < access.depth(); ++i) {
+ const ContextAccess& access = ContextAccessOf(node->op());
+ for (size_t i = 0; i < access.depth(); ++i) {
node->ReplaceInput(
- 0, graph()->NewNode(
- machine()->Load(kMachAnyTagged),
- NodeProperties::GetValueInput(node, 0),
- Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
- NodeProperties::GetEffectInput(node)));
+ 0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+ NodeProperties::GetValueInput(node, 0),
+ jsgraph()->Int32Constant(
+ Context::SlotOffset(Context::PREVIOUS_INDEX)),
+ NodeProperties::GetEffectInput(node),
+ graph()->start()));
}
node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
- node->ReplaceInput(1, Int32Constant(Context::SlotOffset(access.index())));
+ node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
+ static_cast<int>(access.index()))));
PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged,
kFullWriteBarrier)));
}
@@ -370,32 +354,73 @@
CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
CallDescriptor* desc =
linkage()->GetStubCallDescriptor(d, arity, FlagsForNode(node));
- Node* stub_code = CodeConstant(stub.GetCode());
+ Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
Node* construct = NodeProperties::GetValueInput(node, 0);
PatchInsertInput(node, 0, stub_code);
- PatchInsertInput(node, 1, Int32Constant(arity - 1));
+ PatchInsertInput(node, 1, jsgraph()->Int32Constant(arity - 1));
PatchInsertInput(node, 2, construct);
PatchInsertInput(node, 3, jsgraph()->UndefinedConstant());
PatchOperator(node, common()->Call(desc));
}
+bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
+ // Lower to a direct call to a constant JSFunction if legal.
+ const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+ int arg_count = static_cast<int>(p.arity() - 2);
+
+ // Check the function is a constant and is really a JSFunction.
+ HeapObjectMatcher<Object> function_const(node->InputAt(0));
+ if (!function_const.HasValue()) return false; // not a constant.
+ 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;
+
+ // Check the receiver doesn't need to be wrapped.
+ Node* receiver = node->InputAt(1);
+ if (!NodeProperties::IsTyped(receiver)) return false;
+ Type* ok_receiver = Type::Union(Type::Undefined(), Type::Receiver(), zone());
+ if (!NodeProperties::GetBounds(receiver).upper->Is(ok_receiver)) return false;
+
+ int index = NodeProperties::FirstContextIndex(node);
+
+ // TODO(titzer): total hack to share function context constants.
+ // Remove this when the JSGraph canonicalizes heap constants.
+ Node* context = node->InputAt(index);
+ HeapObjectMatcher<Context> context_const(context);
+ if (!context_const.HasValue() ||
+ *(context_const.Value().handle()) != function->context()) {
+ 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));
+ return true;
+}
+
+
void JSGenericLowering::LowerJSCallFunction(Node* node) {
- CallParameters p = OpParameter<CallParameters>(node);
- CallFunctionStub stub(isolate(), p.arity - 2, p.flags);
+ // Fast case: call function directly.
+ if (TryLowerDirectJSCall(node)) return;
+
+ // General case: CallFunctionStub.
+ const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+ 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, p.arity - 1, FlagsForNode(node));
- Node* stub_code = CodeConstant(stub.GetCode());
+ CallDescriptor* desc = linkage()->GetStubCallDescriptor(
+ 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));
}
void JSGenericLowering::LowerJSCallRuntime(Node* node) {
- Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(node);
- int arity = OperatorProperties::GetValueInputCount(node->op());
- ReplaceWithRuntimeCall(node, function, arity);
+ const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
+ ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
}
} // namespace compiler