Make it easier to test OSR with %OptimizeOsr() runtime call.
authortitzer <titzer@chromium.org>
Mon, 9 Feb 2015 12:47:31 +0000 (04:47 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 9 Feb 2015 12:47:43 +0000 (12:47 +0000)
This call triggers OSR for the current function. And also allows explicitly testing OSR on the top-level code.

R=mstarzinger@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#26523}

13 files changed:
src/runtime/runtime-test.cc
src/runtime/runtime.h
test/mjsunit/compiler/optimized-for-in.js
test/mjsunit/compiler/osr-manual1.js
test/mjsunit/compiler/osr-manual2.js
test/mjsunit/compiler/osr-regex-id.js
test/mjsunit/compiler/osr-simple.js
test/mjsunit/compiler/osr-top1.js [new file with mode: 0644]
test/mjsunit/compiler/osr-top2.js [new file with mode: 0644]
test/mjsunit/compiler/osr-top3.js [new file with mode: 0644]
test/mjsunit/regress-sync-optimized-lists.js
test/mjsunit/regress/regress-379770.js
test/mjsunit/regress/regress-crbug-387599.js

index 1778401..89e1f2a 100644 (file)
@@ -69,13 +69,8 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
   Code* unoptimized = function->shared()->code();
   if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
-      // Start patching from the currently patched loop nesting level.
-      DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
-      isolate->runtime_profiler()->AttemptOnStackReplacement(
-          *function, Code::kMaxLoopNestingMarker);
-    } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
-               isolate->concurrent_recompilation_enabled()) {
+    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
+        isolate->concurrent_recompilation_enabled()) {
       function->AttemptConcurrentOptimization();
     }
   }
@@ -84,6 +79,45 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
 }
 
 
+RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 0);
+  Handle<JSFunction> function = Handle<JSFunction>::null();
+
+  {
+    // Find the JavaScript function on the top of the stack.
+    JavaScriptFrameIterator it(isolate);
+    while (!it.done()) {
+      if (it.frame()->is_java_script()) {
+        function = Handle<JSFunction>(it.frame()->function());
+        break;
+      }
+    }
+    if (function.is_null()) return isolate->heap()->undefined_value();
+  }
+
+  // The following assertion was lifted from the DCHECK inside
+  // JSFunction::MarkForOptimization().
+  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
+                 (function->code()->kind() == Code::FUNCTION &&
+                  function->code()->optimizable()));
+
+  if (!isolate->use_crankshaft()) return isolate->heap()->undefined_value();
+
+  // If the function is already optimized, just return.
+  if (function->IsOptimized()) return isolate->heap()->undefined_value();
+
+  Code* unoptimized = function->shared()->code();
+  if (unoptimized->kind() == Code::FUNCTION) {
+    DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
+    isolate->runtime_profiler()->AttemptOnStackReplacement(
+        *function, Code::kMaxLoopNestingMarker);
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
index 3f8aa21..a73fb24 100644 (file)
@@ -66,6 +66,7 @@ namespace internal {
   F(RunningInSimulator, 0, 1)                              \
   F(IsConcurrentRecompilationSupported, 0, 1)              \
   F(OptimizeFunctionOnNextCall, -1, 1)                     \
+  F(OptimizeOsr, 0, 1)                                     \
   F(NeverOptimizeFunction, 1, 1)                           \
   F(GetOptimizationStatus, -1, 1)                          \
   F(GetOptimizationCount, 1, 1)                            \
index 9c756aa..f3ff6be 100644 (file)
@@ -251,9 +251,7 @@ function osr_inner(t, limit) {
     if (t.hasOwnProperty(x)) {
       for (var i = 0; i < t[x].length; i++) {
         r += t[x][i];
-        if (i === limit) {
-          %OptimizeFunctionOnNextCall(osr_inner, "osr");
-        }
+        if (i === limit) %OptimizeOsr();
       }
       r += x;
     }
@@ -267,9 +265,7 @@ function osr_outer(t, osr_after) {
     for (var i = 0; i < t[x].length; i++) {
       r += t[x][i];
     }
-    if (x === osr_after) {
-      %OptimizeFunctionOnNextCall(osr_outer, "osr");
-    }
+    if (x === osr_after) %OptimizeOsr();
     r += x;
   }
   return r;
@@ -279,9 +275,7 @@ function osr_outer_and_deopt(t, osr_after) {
   var r = 1;
   for (var x in t) {
     r += x;
-    if (x == osr_after) {
-      %OptimizeFunctionOnNextCall(osr_outer_and_deopt, "osr");
-    }
+    if (x == osr_after) %OptimizeOsr();
   }
   return r;
 }
index 786a70d..29a4948 100644 (file)
@@ -4,41 +4,29 @@
 
 // Flags: --allow-natives-syntax --use-osr --turbo-osr
 
-var counter = 188;
+var counter = 111;
 
-function gen() {  // defeat compiler cache.
+function gen(w) {  // defeat compiler cache.
  var num = counter++;
- var src =
-  "function f" + num + "(Z,a,b,c) {" +
-  "  var x = 0;" +
-  "  var y = 0;" +
-  "  var z = 0;" +
-  "  while (a > 0) { Z(0); x += 19; a--; }" +
-  "  while (b > 0) { Z(1); y += 23; b--; }" +
-  "  while (c > 0) { Z(2); z += 29; c--; }" +
-  "  return x + y + z;" +
-  "} f" + num;
-
+  var Z = [ "", "", "", ];
+  Z[w] = "%OptimizeOsr()";
+  var src =
+    "function f" + num + "(a,b,c) {" +
+    "  var x = 0;" +
+    "  var y = 0;" +
+    "  var z = 0;" +
+    "  while (a > 0) { " + Z[0] + "; x += 19; a--; }" +
+    "  while (b > 0) { " + Z[1] + "; y += 23; b--; }" +
+    "  while (c > 0) { " + Z[2] + "; z += 29; c--; }" +
+    "  return x + y + z;" +
+    "} f" + num;
   return eval(src);
 }
 
-function compiler(a) {  // manual control of OSR compiles.
-  var x = 0;
-  function count(l) {
-    if (l == a && (x++) > 0) {
-      %OptimizeFunctionOnNextCall(count.caller, "osr");
-    }
-  }
-  return count;
-}
-
 function check(x,a,b,c) {
-  function none(l) { }
-
   for (var i = 0; i < 3; i++) {
-    var f = gen();
-    assertEquals(x, f(compiler(i), a, b, c));
-    assertEquals(x, f(none, a, b, c));
+    var f = gen(i);
+    assertEquals(x, f(a, b, c));
   }
 }
 
index 463ba89..8aa5d69 100644 (file)
@@ -6,39 +6,27 @@
 
 var counter = 188;
 
-function gen() {  // defeat compiler cache.
+function gen(w) {  // defeat compiler cache.
  var num = counter++;
- var src =
-  "function f" + num + "(Z,a,b,c) {" +
-  "  var x = 0;" +
-  "  var y = 0;" +
-  "  var z = 0;" +
-  "  while (a > 0) { Z(0); x += 19; a--; var j=2; while(j--); }" +
-  "  while (b > 0) { Z(1); y += 23; b--; var j=2; while(j--); }" +
-  "  while (c > 0) { Z(2); z += 29; c--; var j=2; while(j--); }" +
-  "  return x + y + z;" +
-  "} f" + num;
-
+  var Z = [ "", "", "", ];
+  Z[w] = "%OptimizeOsr()";
+  var src =
+    "function f" + num + "(a,b,c) {" +
+    "  var x = 0;" +
+    "  var y = 0;" +
+    "  var z = 0;" +
+    "  while (a > 0) { " + Z[0] + "; x += 19; a--; var j=2; while(j--); }" +
+    "  while (b > 0) { " + Z[1] + "; y += 23; b--; var j=2; while(j--); }" +
+    "  while (c > 0) { " + Z[2] + "; z += 29; c--; var j=2; while(j--); }" +
+    "  return x + y + z;" +
+    "} f" + num;
   return eval(src);
 }
 
-function compiler(a) {  // manual control of OSR compiles.
-  var x = 0;
-  function count(l) {
-    if (l == a && (x++) > 0) {
-      %OptimizeFunctionOnNextCall(count.caller, "osr");
-    }
-  }
-  return count;
-}
-
 function check(x,a,b,c) {
-  function none(l) { }
-
   for (var i = 0; i < 3; i++) {
-    var f = gen();
-    assertEquals(x, f(compiler(i), a, b, c));
-    assertEquals(x, f(none, a, b, c));
+    var f = gen(i);
+    assertEquals(x, f(a, b, c));
   }
 }
 
index f703e3b..7831b14 100644 (file)
@@ -9,14 +9,14 @@ function id(f) { return f; }
 function foo(a) {
   var r = /\0/;
   for (var i = 0; i < 10; i++) {
-    if (a) %OptimizeFunctionOnNextCall(foo, "osr");
+    if (a) %OptimizeOsr();
   }
   return r;
 }
 
 function bar(a) {
   for (var i = 0; i < 10; i++) {
-    if (a) %OptimizeFunctionOnNextCall(bar, "osr");
+    if (a) %OptimizeOsr();
     var r = /\0/;
   }
   return r;
@@ -24,7 +24,7 @@ function bar(a) {
 
 function baz(a) {
   for (var i = 0; i < 10; i++) {
-    if (a) %OptimizeFunctionOnNextCall(baz, "osr");
+    if (a) %OptimizeOsr();
   }
   return /\0/;
 }
@@ -32,7 +32,7 @@ function baz(a) {
 function qux(a) {
   for (var i = 0; i < 10; i++) {
     if (i > 5 && a) {
-      %OptimizeFunctionOnNextCall(qux, "osr");
+      %OptimizeOsr();
     } else {
       var r = /\0/;
     }
index 8ec1b2b..24a3c8f 100644 (file)
@@ -1,29 +1,6 @@
 // Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 // Flags: --use-osr
 
diff --git a/test/mjsunit/compiler/osr-top1.js b/test/mjsunit/compiler/osr-top1.js
new file mode 100644 (file)
index 0000000..742b71d
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --use-osr --allow-natives-syntax
+
+var sum = 0;
+for (var i = 0; i < 10000; i++) {
+  if (i == 100) %OptimizeOsr();
+  var x = i + 2;
+  var y = x + 5;
+  var z = y + 3;
+  sum += z;
+}
+
+assertEquals(50095000, sum);
diff --git a/test/mjsunit/compiler/osr-top2.js b/test/mjsunit/compiler/osr-top2.js
new file mode 100644 (file)
index 0000000..a15aa15
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --use-osr --allow-natives-syntax
+
+for (var j = 0; j < 3; j++) {
+  var sum = 0;
+  for (var i = 0; i < 1000; i++) {
+    if (i == 100) %OptimizeOsr();
+    var x = i + 2;
+    var y = x + 5;
+    var z = y + 3;
+    sum += z;
+  }
+  assertEquals(509500, sum);
+}
+
+assertEquals(509500, sum);
diff --git a/test/mjsunit/compiler/osr-top3.js b/test/mjsunit/compiler/osr-top3.js
new file mode 100644 (file)
index 0000000..4c4a364
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --use-osr --allow-natives-syntax
+
+for (var k = 0; k < 2; k++) {
+  for (var j = 0; j < 3; j++) {
+    var sum = 0;
+    for (var i = 0; i < 1000; i++) {
+      if (i == 100) %OptimizeOsr();
+      var x = i + 2;
+      var y = x + 5;
+      var z = y + 3;
+      sum += z;
+    }
+    assertEquals(509500, sum);
+  }
+  assertEquals(509500, sum);
+}
+
+assertEquals(509500, sum);
index f07c12b..2ce60aa 100644 (file)
@@ -13,9 +13,7 @@ function get_closure() {
   return function add_field(obj, osr) {
     obj.c = 3;
     var x = 0;
-    if (osr) {
-      %OptimizeFunctionOnNextCall(add_field, "osr");
-    }
+    if (osr) %OptimizeOsr();
     for (var i = 0; i < 10; i++) {
       x = i + 1;
     }
index a6653c2..ab1b339 100644 (file)
@@ -6,9 +6,7 @@
 
 function foo(obj) {
   var counter = 1;
-  for (var i = 0; i < obj.length; i++) {
-    %OptimizeFunctionOnNextCall(foo, "osr");
-  }
+  for (var i = 0; i < obj.length; i++) %OptimizeOsr();
   counter += obj;
   return counter;
 }
index 98750aa..753dcfa 100644 (file)
@@ -8,9 +8,7 @@ Debug = debug.Debug;
 Debug.setListener(function() {});
 
 function f() {
-  for (var i = 0; i < 100; i++) {
-    %OptimizeFunctionOnNextCall(f, "osr");
-  }
+  for (var i = 0; i < 100; i++) %OptimizeOsr();
 }
 
 Debug.setBreakPoint(f, 0, 0);