Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
index 2244f9b..e3254bd 100644
--- a/src/compiler/js-inlining.cc
+++ b/src/compiler/js-inlining.cc
@@ -263,6 +263,35 @@
node->InputAt(0), outer_frame_state);
}
+Node* JSInliner::CreateTailCallerFrameState(Node* node, Node* frame_state) {
+ FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state);
+ Handle<SharedFunctionInfo> shared;
+ frame_info.shared_info().ToHandle(&shared);
+
+ Node* function = frame_state->InputAt(kFrameStateFunctionInput);
+
+ // If we are inlining a tail call drop caller's frame state and an
+ // arguments adaptor if it exists.
+ frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
+ if (frame_state->opcode() == IrOpcode::kFrameState) {
+ FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state);
+ if (frame_info.type() == FrameStateType::kArgumentsAdaptor) {
+ frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
+ }
+ }
+
+ const FrameStateFunctionInfo* state_info =
+ jsgraph_->common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kTailCallerFunction, 0, 0, shared);
+
+ const Operator* op = jsgraph_->common()->FrameState(
+ BailoutId(-1), OutputFrameStateCombine::Ignore(), state_info);
+ const Operator* op0 = jsgraph_->common()->StateValues(0);
+ Node* node0 = jsgraph_->graph()->NewNode(op0);
+ return jsgraph_->graph()->NewNode(op, node0, node0, node0,
+ jsgraph_->UndefinedConstant(), function,
+ frame_state);
+}
namespace {
@@ -271,7 +300,10 @@
DisallowHeapAllocation no_gc;
Isolate* const isolate = shared_info->GetIsolate();
Code* const construct_stub = shared_info->construct_stub();
- return construct_stub != *isolate->builtins()->JSBuiltinsConstructStub();
+ return construct_stub != *isolate->builtins()->JSBuiltinsConstructStub() &&
+ construct_stub !=
+ *isolate->builtins()->JSBuiltinsConstructStubForDerived() &&
+ construct_stub != *isolate->builtins()->JSConstructStubApi();
}
bool IsNonConstructible(Handle<SharedFunctionInfo> shared_info) {
@@ -380,7 +412,7 @@
return NoChange();
}
- Zone zone;
+ Zone zone(info_->isolate()->allocator());
ParseInfo parse_info(&zone, function);
CompilationInfo info(&parse_info);
if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled();
@@ -395,17 +427,6 @@
return NoChange();
}
- // In strong mode, in case of too few arguments we need to throw a TypeError
- // so we must not inline this call.
- int parameter_count = info.literal()->parameter_count();
- if (is_strong(info.language_mode()) &&
- call.formal_arguments() < parameter_count) {
- TRACE("Not inlining %s into %s because too few arguments for strong mode\n",
- shared_info->DebugName()->ToCString().get(),
- info_->shared_info()->DebugName()->ToCString().get());
- return NoChange();
- }
-
if (!Compiler::EnsureDeoptimizationSupport(&info)) {
TRACE("Not inlining %s into %s because deoptimization support failed\n",
shared_info->DebugName()->ToCString().get(),
@@ -508,10 +529,25 @@
NodeProperties::ReplaceEffectInput(node, convert);
}
+ // If we are inlining a JS call at tail position then we have to pop current
+ // frame state and its potential arguments adaptor frame state in order to
+ // make the call stack be consistent with non-inlining case.
+ // After that we add a tail caller frame state which lets deoptimizer handle
+ // the case when the outermost function inlines a tail call (it should remove
+ // potential arguments adaptor frame that belongs to outermost function when
+ // deopt happens).
+ if (node->opcode() == IrOpcode::kJSCallFunction) {
+ const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+ if (p.tail_call_mode() == TailCallMode::kAllow) {
+ frame_state = CreateTailCallerFrameState(node, frame_state);
+ }
+ }
+
// Insert argument adaptor frame if required. The callees formal parameter
// count (i.e. value outputs of start node minus target, receiver, new target,
// arguments count and context) have to match the number of arguments passed
// to the call.
+ int parameter_count = info.literal()->parameter_count();
DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 5);
if (call.formal_arguments() != parameter_count) {
frame_state = CreateArtificialFrameState(