Index: src/compiler/js-inlining.cc |
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc |
index 8083388130811466d15804212dac4cc28c32c078..8e240b60de8a3a86e1b2bfdb5c62aa792f6bc4a1 100644 |
--- a/src/compiler/js-inlining.cc |
+++ b/src/compiler/js-inlining.cc |
@@ -268,10 +268,18 @@ Node* JSInliner::CreateArtificialFrameState(Node* node, Node* outer_frame_state, |
namespace { |
// TODO(mstarzinger,verwaest): Move this predicate onto SharedFunctionInfo? |
-bool NeedsImplicitReceiver(Handle<JSFunction> function, Isolate* isolate) { |
- Code* construct_stub = function->shared()->construct_stub(); |
- return construct_stub != *isolate->builtins()->JSBuiltinsConstructStub() && |
- construct_stub != *isolate->builtins()->ConstructedNonConstructable(); |
+bool NeedsImplicitReceiver(Handle<SharedFunctionInfo> shared_info) { |
+ DisallowHeapAllocation no_gc; |
+ Isolate* const isolate = shared_info->GetIsolate(); |
+ Code* const construct_stub = shared_info->construct_stub(); |
+ return construct_stub != *isolate->builtins()->JSBuiltinsConstructStub(); |
+} |
+ |
+bool IsNonConstructible(Handle<SharedFunctionInfo> shared_info) { |
+ DisallowHeapAllocation no_gc; |
+ Isolate* const isolate = shared_info->GetIsolate(); |
+ Code* const construct_stub = shared_info->construct_stub(); |
+ return construct_stub == *isolate->builtins()->ConstructedNonConstructable(); |
} |
} // namespace |
@@ -295,20 +303,21 @@ Reduction JSInliner::Reduce(Node* node) { |
Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
DCHECK(IrOpcode::IsInlineeOpcode(node->opcode())); |
JSCallAccessor call(node); |
+ Handle<SharedFunctionInfo> shared_info(function->shared()); |
// Function must be inlineable. |
- if (!function->shared()->IsInlineable()) { |
+ if (!shared_info->IsInlineable()) { |
TRACE("Not inlining %s into %s because callee is not inlineable\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
// Constructor must be constructable. |
if (node->opcode() == IrOpcode::kJSCallConstruct && |
- !function->IsConstructor()) { |
+ IsNonConstructible(shared_info)) { |
TRACE("Not inlining %s into %s because constructor is not constructable.\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
@@ -316,17 +325,17 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
// Class constructors are callable, but [[Call]] will raise an exception. |
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). |
if (node->opcode() == IrOpcode::kJSCallFunction && |
- IsClassConstructor(function->shared()->kind())) { |
+ IsClassConstructor(shared_info->kind())) { |
TRACE("Not inlining %s into %s because callee is a class constructor.\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
// Function contains break points. |
- if (function->shared()->HasDebugInfo()) { |
+ if (shared_info->HasDebugInfo()) { |
TRACE("Not inlining %s into %s because callee may contain break points\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
@@ -342,7 +351,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
if (function->context()->native_context() != |
info_->context()->native_context()) { |
TRACE("Not inlining %s into %s because of different native contexts\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
@@ -353,12 +362,12 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
for (Node* frame_state = call.frame_state_after(); |
frame_state->opcode() == IrOpcode::kFrameState; |
frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) { |
- FrameStateInfo const& info = OpParameter<FrameStateInfo>(frame_state); |
- Handle<SharedFunctionInfo> shared_info; |
- if (info.shared_info().ToHandle(&shared_info) && |
- *shared_info == function->shared()) { |
+ FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state); |
+ Handle<SharedFunctionInfo> frame_shared_info; |
+ if (frame_info.shared_info().ToHandle(&frame_shared_info) && |
+ *frame_shared_info == *shared_info) { |
TRACE("Not inlining %s into %s because call is recursive\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
@@ -367,7 +376,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
// TODO(turbofan): Inlining into a try-block is not yet supported. |
if (NodeProperties::IsExceptionalCall(node)) { |
TRACE("Not inlining %s into %s because of surrounding try-block\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
@@ -375,13 +384,11 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
Zone zone; |
ParseInfo parse_info(&zone, function); |
CompilationInfo info(&parse_info); |
- if (info_->is_deoptimization_enabled()) { |
- info.MarkAsDeoptimizationEnabled(); |
- } |
+ if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled(); |
if (!Compiler::ParseAndAnalyze(info.parse_info())) { |
TRACE("Not inlining %s into %s because parsing failed\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
if (info_->isolate()->has_pending_exception()) { |
info_->isolate()->clear_pending_exception(); |
@@ -395,28 +402,28 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
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", |
- function->shared()->DebugName()->ToCString().get(), |
+ 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", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
return NoChange(); |
} |
// Remember that we inlined this function. This needs to be called right |
// after we ensure deoptimization support so that the code flusher |
// does not remove the code with the deoptimization support. |
- info_->AddInlinedFunction(info.shared_info()); |
+ info_->AddInlinedFunction(shared_info); |
// ---------------------------------------------------------------- |
// After this point, we've made a decision to inline this function. |
// We shall not bailout from inlining if we got here. |
TRACE("Inlining %s into %s\n", |
- function->shared()->DebugName()->ToCString().get(), |
+ shared_info->DebugName()->ToCString().get(), |
info_->shared_info()->DebugName()->ToCString().get()); |
// TODO(mstarzinger): We could use the temporary zone for the graph because |
@@ -443,7 +450,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
// Note that the context has to be the callers context (input to call node). |
Node* receiver = jsgraph_->UndefinedConstant(); // Implicit receiver. |
if (node->opcode() == IrOpcode::kJSCallConstruct && |
- NeedsImplicitReceiver(function, info_->isolate())) { |
+ NeedsImplicitReceiver(shared_info)) { |
Node* effect = NodeProperties::GetEffectInput(node); |
Node* context = NodeProperties::GetContextInput(node); |
Node* create = jsgraph_->graph()->NewNode( |
@@ -492,7 +499,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
// in that frame state tho, as the conversion of the receiver can be repeated |
// any number of times, it's not observable. |
if (node->opcode() == IrOpcode::kJSCallFunction && |
- is_sloppy(info.language_mode()) && !function->shared()->native()) { |
+ is_sloppy(info.language_mode()) && !shared_info->native()) { |
const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
Node* effect = NodeProperties::GetEffectInput(node); |
Node* convert = jsgraph_->graph()->NewNode( |
@@ -510,7 +517,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { |
if (call.formal_arguments() != parameter_count) { |
frame_state = CreateArtificialFrameState( |
node, frame_state, call.formal_arguments(), |
- FrameStateType::kArgumentsAdaptor, info.shared_info()); |
+ FrameStateType::kArgumentsAdaptor, shared_info); |
} |
return InlineCall(node, new_target, context, frame_state, start, end); |