Commit c6433cb0 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Reduce JSInliner dependencies on JSFunction.

Ideally the JSInliner should not be concerned with JSFunction's at all,
but only look at the SharedFunctionInfo. This reduces the uses of the
concrete closure to two remaining cases, which we plan to fix soonish
too.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1714803002

Cr-Commit-Position: refs/heads/master@{#34135}
parent b5dc3dd2
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment