| 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);
|
|
|