From 7a4054b7d7db60d7031736ea0fabc24950c68a72 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Fri, 27 Jun 2014 11:04:35 +0000 Subject: [PATCH] Allow inlining of functions containing %_Arguments. R=svenpanne@chromium.org TEST=mjsunit/compiler/inline-arguments Review URL: https://codereview.chromium.org/356773002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22060 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ast.cc | 5 ---- src/hydrogen.cc | 44 ++++++++++++++++++------------- test/mjsunit/compiler/inline-arguments.js | 26 ++++++++++++++++++ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/ast.cc b/src/ast.cc index 5939eb1..edea0f5 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -1114,11 +1114,6 @@ void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { // Don't try to inline JS runtime calls because we don't (currently) even // optimize them. add_flag(kDontInline); - } else if (node->function()->intrinsic_type == Runtime::INLINE && - node->raw_name()->IsOneByteEqualTo("_Arguments")) { - // Don't inline the %_Arguments because it's implementation will not work. - // There is no stack frame to get them from. - add_flag(kDontInline); } } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index d447bbc..89f61de 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -7738,19 +7738,19 @@ bool HOptimizedGraphBuilder::TryInline(Handle target, HConstant* context = Add(Handle(target->context())); inner_env->BindContext(context); - HArgumentsObject* arguments_object = NULL; - - // If the function uses arguments object create and bind one, also copy + // Create a dematerialized arguments object for the function, also copy the // current arguments values to use them for materialization. + HEnvironment* arguments_env = inner_env->arguments_environment(); + int parameter_count = arguments_env->parameter_count(); + HArgumentsObject* arguments_object = Add(parameter_count); + for (int i = 0; i < parameter_count; i++) { + arguments_object->AddArgument(arguments_env->Lookup(i), zone()); + } + + // If the function uses arguments object then bind bind one. if (function->scope()->arguments() != NULL) { ASSERT(function->scope()->arguments()->IsStackAllocated()); - HEnvironment* arguments_env = inner_env->arguments_environment(); - int arguments_count = arguments_env->parameter_count(); - arguments_object = Add(arguments_count); inner_env->Bind(function->scope()->arguments(), arguments_object); - for (int i = 0; i < arguments_count; i++) { - arguments_object->AddArgument(arguments_env->Lookup(i), zone()); - } } // Capture the state before invoking the inlined function for deopt in the @@ -11326,18 +11326,26 @@ void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { - // Our implementation of arguments (based on this stack frame or an - // adapter below it) does not work for inlined functions. This runtime - // function is blacklisted by AstNode::IsInlineable. - ASSERT(function_state()->outer() == NULL); ASSERT(call->arguments()->length() == 1); CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); HValue* index = Pop(); - HInstruction* elements = Add(false); - HInstruction* length = Add(elements); - HInstruction* checked_index = Add(index, length); - HAccessArgumentsAt* result = New( - elements, length, checked_index); + HInstruction* result = NULL; + if (function_state()->outer() == NULL) { + HInstruction* elements = Add(false); + HInstruction* length = Add(elements); + HInstruction* checked_index = Add(index, length); + result = New(elements, length, checked_index); + } else { + EnsureArgumentsArePushedForAccess(); + + // Number of arguments without receiver. + HInstruction* elements = function_state()->arguments_elements(); + int argument_count = environment()-> + arguments_environment()->parameter_count() - 1; + HInstruction* length = Add(argument_count); + HInstruction* checked_key = Add(index, length); + result = New(elements, length, checked_key); + } return ast_context()->ReturnInstruction(result, call->id()); } diff --git a/test/mjsunit/compiler/inline-arguments.js b/test/mjsunit/compiler/inline-arguments.js index 1337ab2..d52f31b 100644 --- a/test/mjsunit/compiler/inline-arguments.js +++ b/test/mjsunit/compiler/inline-arguments.js @@ -309,3 +309,29 @@ test_toarr(toarr2); delete forceDeopt.deopt; outer(); })(); + + +// Test inlining of functions with %_Arguments and %_ArgumentsLength intrinsic. +(function () { + function inner(len,a,b,c) { + assertSame(len, %_ArgumentsLength()); + for (var i = 1; i < len; ++i) { + var c = String.fromCharCode(96 + i); + assertSame(c, %_Arguments(i)); + } + } + + function outer() { + inner(1); + inner(2, 'a'); + inner(3, 'a', 'b'); + inner(4, 'a', 'b', 'c'); + inner(5, 'a', 'b', 'c', 'd'); + inner(6, 'a', 'b', 'c', 'd', 'e'); + } + + outer(); + outer(); + %OptimizeFunctionOnNextCall(outer); + outer(); +})(); -- 2.7.4