Reviewers: Sven Panne,
Description:
Allow inlining of functions containing %_Arguments.
[email protected]
TEST=mjsunit/compiler/inline-arguments
Please review this at https://codereview.chromium.org/356773002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+52, -23 lines):
M src/ast.cc
M src/hydrogen.cc
M test/mjsunit/compiler/inline-arguments.js
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index
bf16b9c076b8786ce1cb4a2eecf4963f79d70fe9..8d25bacfa6dda99b2ea7decf71e582c2bc6c1caa
100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1116,11 +1116,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);
}
}
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
d447bbc9f76cbcb6d16990ed22233d11b154e1d1..89f61decba5c833f9bafc5e94a829fc3b2216ee1
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -7738,19 +7738,19 @@ bool
HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
HConstant* context = Add<HConstant>(Handle<Context>(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<HArgumentsObject>(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<HArgumentsObject>(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<HArgumentsElements>(false);
- HInstruction* length = Add<HArgumentsLength>(elements);
- HInstruction* checked_index = Add<HBoundsCheck>(index, length);
- HAccessArgumentsAt* result = New<HAccessArgumentsAt>(
- elements, length, checked_index);
+ HInstruction* result = NULL;
+ if (function_state()->outer() == NULL) {
+ HInstruction* elements = Add<HArgumentsElements>(false);
+ HInstruction* length = Add<HArgumentsLength>(elements);
+ HInstruction* checked_index = Add<HBoundsCheck>(index, length);
+ result = New<HAccessArgumentsAt>(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<HConstant>(argument_count);
+ HInstruction* checked_key = Add<HBoundsCheck>(index, length);
+ result = New<HAccessArgumentsAt>(elements, length, checked_key);
+ }
return ast_context()->ReturnInstruction(result, call->id());
}
Index: test/mjsunit/compiler/inline-arguments.js
diff --git a/test/mjsunit/compiler/inline-arguments.js
b/test/mjsunit/compiler/inline-arguments.js
index
1337ab237a4cadd8a053e6e95d0d58ffff717ccb..d52f31b5e9171fa22e248720e8d36c6bc976072c
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();
+})();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.