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();
}
}
}
+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);
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) \
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;
}
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;
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;
}
// 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));
}
}
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));
}
}
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;
function baz(a) {
for (var i = 0; i < 10; i++) {
- if (a) %OptimizeFunctionOnNextCall(baz, "osr");
+ if (a) %OptimizeOsr();
}
return /\0/;
}
function qux(a) {
for (var i = 0; i < 10; i++) {
if (i > 5 && a) {
- %OptimizeFunctionOnNextCall(qux, "osr");
+ %OptimizeOsr();
} else {
var r = /\0/;
}
// 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
--- /dev/null
+// 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);
--- /dev/null
+// 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);
--- /dev/null
+// 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);
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;
}
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;
}
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);