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