Reviewers: Jakob,

Description:
Allow inlining of multiple closures from shared function.

This allows Crankshaft to allow inlining of multiple different closures
that were all derived from the same shared function info. This pattern
appears when libraries provide generic closures that are used over and
over again at different call-sites.

[email protected]
TEST=mjsunit/compiler/inline-closures


Please review this at https://chromiumcodereview.appspot.com/12071002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/hydrogen.cc
  A + test/mjsunit/compiler/inline-closures.js


Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 019f39a20f96050f55cbab1d67390afbcf1b8707..1231337c889f86647c27f39c0a018b7c4b0f0c77 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -7081,8 +7081,6 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
     return false;
   }

-  Handle<SharedFunctionInfo> target_shared(target->shared());
-
 #if !defined(V8_TARGET_ARCH_IA32)
   // Target must be able to use caller's context.
   CompilationInfo* outer_info = info();
@@ -7113,7 +7111,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
   for (FunctionState* state = function_state();
        state != NULL;
        state = state->outer()) {
-    if (state->compilation_info()->closure()->shared() == *target_shared) {
+    if (*state->compilation_info()->closure() == *target) {
       TraceInline(target, caller, "target is recursive");
       return false;
     }
@@ -7128,6 +7126,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,

   // Parse and allocate variables.
   CompilationInfo target_info(target, zone());
+  Handle<SharedFunctionInfo> target_shared(target->shared());
   if (!ParserApi::Parse(&target_info, kNoParsingFlags) ||
       !Scope::Analyze(&target_info)) {
     if (target_info.isolate()->has_pending_exception()) {
Index: test/mjsunit/compiler/inline-closures.js
diff --git a/test/mjsunit/regress/regress-171641.js b/test/mjsunit/compiler/inline-closures.js
similarity index 75%
copy from test/mjsunit/regress/regress-171641.js
copy to test/mjsunit/compiler/inline-closures.js
index 8db6781821325f8f6253eb2df4abb2b362b001c0..69161e505e5f28c25c0d5a8a87d48e0cedf6c389 100644
--- a/test/mjsunit/regress/regress-171641.js
+++ b/test/mjsunit/compiler/inline-closures.js
@@ -27,14 +27,23 @@

 // Flags: --allow-natives-syntax

-function foo(k, p) {
-  for (var i = 0; i < 1; i++) {
-    p = Math.min(p, i);
+// Test inlining of multiple closures derived from one shared function.
+
+function mkClosure(continuation) {
+  return function(value) {
+    if (continuation == 'g') return this.g(value);
+    if (continuation == 'h') return this.h(value);
+    return value.value;
   }
-  m = Math.floor((k | 0) / p);
 }

-foo(0, 1);
-foo(0, 1);
-%OptimizeFunctionOnNextCall(foo);
-foo(0, 1);
+var object = {};
+object.f = mkClosure('g');
+object.g = mkClosure('h');
+object.h = mkClosure('x');
+
+assertSame(1, object.f({value:1}));
+assertSame(2, object.f({value:2}));
+%OptimizeFunctionOnNextCall(object.f);
+assertSame(3, object.f({value:3}));
+assertSame(undefined, object.f({}));


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev


Reply via email to