Commit 9e7819fa authored by titzer@chromium.org's avatar titzer@chromium.org

Added %NeverOptimize runtime call that can disable optimizations for a method for tests.

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15632 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 90a8ac78
......@@ -7435,6 +7435,14 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
const Runtime::Function* function = expr->function();
ASSERT(function != NULL);
if (static_cast<int>(function->function_id)
== static_cast<int>(Runtime::kNeverOptimize)
&& expr->arguments()->length() == 0) {
// %NeverOptimize() without arguments marks the caller as never optimize.
return Bailout("function marked itself as never optimize");
}
if (function->intrinsic_type == Runtime::INLINE) {
ASSERT(expr->name()->length() > 0);
ASSERT(expr->name()->Get(0) == '_');
......
......@@ -8346,6 +8346,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimize) {
HandleScope scope(isolate);
if (args.length() == 0) {
// Disable optimization for the calling function.
JavaScriptFrameIterator it(isolate);
if (!it.done()) {
JSFunction *function = JSFunction::cast(it.frame()->function());
function->shared()->set_optimization_disabled(true);
}
return isolate->heap()->undefined_value();
}
// Disable optimization for the functions passed.
for (int i = 0; i < args.length(); i++) {
CONVERT_ARG_CHECKED(JSFunction, function, i);
function->shared()->set_optimization_disabled(true);
}
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompleteOptimization) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
......
......@@ -97,6 +97,7 @@ namespace internal {
F(RunningInSimulator, 0, 1) \
F(IsParallelRecompilationSupported, 0, 1) \
F(OptimizeFunctionOnNextCall, -1, 1) \
F(NeverOptimize, -1, 1) \
F(CompleteOptimization, 1, 1) \
F(GetOptimizationStatus, 1, 1) \
F(GetOptimizationCount, 1, 1) \
......
......@@ -117,7 +117,7 @@ F4(1);
// Test arguments access from the inlined function.
function uninlinable(v) {
assertEquals(0, v);
try { } catch (e) { }
%NeverOptimize();
return 0;
}
......
......@@ -171,21 +171,21 @@ monomorphic(smi_only);
if (support_smi_only_arrays) {
function construct_smis() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = [0, 0, 0];
a[0] = 0; // Send the COW array map to the steak house.
assertKind(elements_kind.fast_smi_only, a);
return a;
}
function construct_doubles() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = construct_smis();
a[0] = 1.5;
assertKind(elements_kind.fast_double, a);
return a;
}
function construct_objects() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = construct_smis();
a[0] = "one";
assertKind(elements_kind.fast, a);
......@@ -194,7 +194,7 @@ if (support_smi_only_arrays) {
// Test crankshafted transition SMI->DOUBLE.
function convert_to_double(array) {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
array[1] = 2.5;
assertKind(elements_kind.fast_double, array);
assertEquals(2.5, array[1]);
......@@ -206,7 +206,7 @@ if (support_smi_only_arrays) {
convert_to_double(smis);
// Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
function convert_to_fast(array) {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
array[1] = "two";
assertKind(elements_kind.fast, array);
assertEquals("two", array[1]);
......@@ -223,7 +223,7 @@ if (support_smi_only_arrays) {
// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
// transition to FAST directly).
function convert_mixed(array, value, kind) {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
array[1] = value;
assertKind(kind, array);
assertEquals(value, array[1]);
......
......@@ -30,7 +30,7 @@
var do_set = false;
function set_proto_elements() {
try {} catch (e) {} // Don't optimize or inline
%NeverOptimize();
if (do_set) Array.prototype[1] = 1.5;
}
......
......@@ -27,7 +27,7 @@
// Flags: --allow-natives-syntax --compiled_transitions
try {} catch (e) {}
%NeverOptimize();
var iteration_count = 1;
......
// Copyright 2013 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.
// Flags: --allow-natives-syntax
function o1() {
}
if (%GetOptimizationStatus(o1) != 4) {
// 4 == optimization disabled.
o1(); o1();
%OptimizeFunctionOnNextCall(o1);
o1();
// check that the given function was optimized.
var o1_status = %GetOptimizationStatus(o1);
assertTrue(o1_status == 1 // optimized
|| o1_status == 3 // optimized (always opt)
|| o1_status == 5); // lazy recompile requested
// Test the %NeverOptimize runtime call.
function u1() {
%NeverOptimize();
}
function u2() {
}
%NeverOptimize(u2);
u1(); u1();
u2(); u2();
%OptimizeFunctionOnNextCall(u1);
%OptimizeFunctionOnNextCall(u2);
u1(); u1();
u2(); u2();
// 2 => not optimized.
assertEquals(2, %GetOptimizationStatus(u1));
assertEquals(2, %GetOptimizationStatus(u2));
}
\ No newline at end of file
......@@ -109,7 +109,7 @@ function assertKind(expected, obj, name_opt) {
}
function construct_smis() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = [0, 0, 0];
a[0] = 0; // Send the COW array map to the steak house.
assertKind(elements_kind.fast_smi_only, a);
......@@ -117,7 +117,7 @@ function construct_smis() {
}
function construct_doubles() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = construct_smis();
a[0] = 1.5;
assertKind(elements_kind.fast_double, a);
......@@ -125,7 +125,7 @@ function construct_doubles() {
}
function convert_mixed(array, value, kind) {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
array[1] = value;
assertKind(kind, array);
assertEquals(value, array[1]);
......
......@@ -113,14 +113,14 @@ for (var i = 0; i < 1000000; i++) { }
if (support_smi_only_arrays) {
function construct_smis() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = [0, 0, 0];
a[0] = 0; // Send the COW array map to the steak house.
assertKind(elements_kind.fast_smi_only, a);
return a;
}
function construct_doubles() {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
var a = construct_smis();
a[0] = 1.5;
assertKind(elements_kind.fast_double, a);
......@@ -130,7 +130,7 @@ if (support_smi_only_arrays) {
// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
// transition to FAST directly).
function convert_mixed(array, value, kind) {
try {} catch (e) {} // TODO(titzer): DisableOptimization
%NeverOptimize();
array[1] = value;
assertKind(kind, array);
assertEquals(value, array[1]);
......
// Copyright 2011 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.
// Flags: --allow-natives-syntax --always-compact --expose-gc
var O = { get f() { return 0; } };
var CODE = [];
var R = [];
function Allocate4Kb(N) {
var arr = [];
do {arr.push(new Array(1024));} while (--N > 0);
return arr;
}
function AllocateXMb(X) {
return Allocate4Kb((1024 * X) / 4);
}
function Node(v, next) { this.v = v; this.next = next; }
Node.prototype.execute = function (O) {
var n = this;
while (n.next !== null) n = n.next;
n.v(O);
};
function LongList(N, x) {
if (N == 0) return new Node(x, null);
return new Node(new Array(1024), LongList(N - 1, x));
}
var L = LongList(1024, function (O) {
for (var i = 0; i < 5; i++) O.f;
});
function Incremental(O, x) {
if (!x) {
return;
}
function CreateCode(i) {
var f = new Function("return O.f_" + i);
CODE.push(f);
f(); // compile
f(); // compile
f(); // compile
}
for (var i = 0; i < 1e4; i++) CreateCode(i);
gc();
gc();
gc();
print(">>> 1 <<<");
L.execute(O);
%NeverOptimize();
L = null;
print(">>> 2 <<<");
AllocateXMb(8);
//rint("1");
//llocateXMb(8);
//rint("1");
//llocateXMb(8);
}
function foo(O, x) {
Incremental(O, x);
print('f');
for (var i = 0; i < 5; i++) O.f;
print('g');
bar(x);
}
function bar(x) {
if (!x) return;
%DeoptimizeFunction(foo);
AllocateXMb(8);
AllocateXMb(8);
}
var O1 = {};
var O2 = {};
var O3 = {};
var O4 = {f:0};
foo(O1, false);
foo(O2, false);
foo(O3, false);
%OptimizeFunctionOnNextCall(foo);
foo(O4, true);
// Copyright 2011 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.
// Flags: --expose-gc --allow-natives-syntax
// Check that we are not flushing code for inlined functions that
// have a pending lazy deoptimization on the stack.
function deopt() {
%NeverOptimize();
%DeoptimizeFunction(outer);
for (var i = 0; i < 10; i++) gc(); // Force code flushing.
}
function outer(should_deopt) {
inner(should_deopt);
}
function inner(should_deopt) {
if (should_deopt) deopt();
}
outer(false);
outer(false);
%OptimizeFunctionOnNextCall(outer);
outer(true);
// Copyright 2013 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.
// Flags: --allow-natives-syntax
var X = 1.1;
var K = 0.5;
var O = 0;
var result = new Float64Array(2);
function spill() {
%NeverOptimize();
}
function buggy() {
var v = X;
var phi1 = v + K;
var phi2 = v - K;
spill(); // At this point initial values for phi1 and phi2 are spilled.
var xmm1 = v;
var xmm2 = v*v*v;
var xmm3 = v*v*v*v;
var xmm4 = v*v*v*v*v;
var xmm5 = v*v*v*v*v*v;
var xmm6 = v*v*v*v*v*v*v;
var xmm7 = v*v*v*v*v*v*v*v;
var xmm8 = v*v*v*v*v*v*v*v*v;
// All registers are blocked and phis for phi1 and phi2 are spilled because
// their left (incoming) value is spilled, there are no free registers,
// and phis themselves have only ANY-policy uses.
for (var x = 0; x < 2; x++) {
xmm1 += xmm1 * xmm6;
xmm2 += xmm1 * xmm5;
xmm3 += xmm1 * xmm4;
xmm4 += xmm1 * xmm3;
xmm5 += xmm1 * xmm2;
// Now swap values of phi1 and phi2 to create cycle between phis.
var t = phi1;
phi1 = phi2;
phi2 = t;
}
// Now we want to get values of phi1 and phi2. However we would like to
// do it in a way that does not produce any uses of phi1&phi2 that have
// a register beneficial policy. How? We just hide these uses behind phis.
result[0] = (O === 0) ? phi1 : phi2;
result[1] = (O !== 0) ? phi1 : phi2;
}
function test() {
buggy();
assertArrayEquals([X + K, X - K], result);
}
test();
test();
%OptimizeFunctionOnNextCall(buggy);
test();
// Copyright 2011 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.
// Flags: --allow-natives-syntax --expose-gc
// This tests that we can correctly handle a GC immediately after a function
// has been deoptimized, even when we have an activation of this function on
// the stack.
// Ensure that there is code objects before the code for the opt_me function.
(function() { var a = 10; a++; })();
function opt_me() {
deopt();
}
function deopt() {
// Make sure we don't inline this function
%NeverOptimize();
%DeoptimizeFunction(opt_me);
gc();
}
opt_me();
// Copyright 2013 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.
// Flags: --allow-natives-syntax
function boom(a) {
return ((a | 0) * (a | 0)) | 0;
}
function boom_unoptimized(a) {
%NeverOptimize();
return ((a | 0) * (a | 0)) | 0;
}
boom(1, 1);
boom(2, 2);
%OptimizeFunctionOnNextCall(boom);
var big_int = 0x5F00000F;
var expected = boom_unoptimized(big_int);
var actual = boom(big_int)
assertEquals(expected, actual);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment