Commit d1ddec78 authored by ishell's avatar ishell Committed by Commit bot

[tests] Make assertOptimized()/assertUnoptimized() great again.

The mentioned asserts did not work properly with interpreted and turbofanned functions.

To fix this issue %GetOptimizationStatus() now returns a set of flags instead of a single value.

This CL also adds more helper functions to mjsunit, like isNeverOptimize(), isAlwaysOptimize(),
isOptimized(fun), etc.

BUG=v8:5890

Review-Url: https://codereview.chromium.org/2654733004
Cr-Commit-Position: refs/heads/master@{#42703}
parent 06b46ab1
...@@ -314,18 +314,19 @@ void EnsureFeedbackMetadata(CompilationInfo* info) { ...@@ -314,18 +314,19 @@ void EnsureFeedbackMetadata(CompilationInfo* info) {
} }
bool UseTurboFan(Handle<SharedFunctionInfo> shared) { bool UseTurboFan(Handle<SharedFunctionInfo> shared) {
bool optimization_disabled = shared->optimization_disabled(); if (shared->optimization_disabled()) {
return false;
}
bool must_use_ignition_turbo = shared->must_use_ignition_turbo(); bool must_use_ignition_turbo = shared->must_use_ignition_turbo();
// Check the enabling conditions for Turbofan. // Check the enabling conditions for Turbofan.
// 1. "use asm" code. // 1. "use asm" code.
bool is_turbofanable_asm = bool is_turbofanable_asm = FLAG_turbo_asm && shared->asm_function();
FLAG_turbo_asm && shared->asm_function() && !optimization_disabled;
// 2. Fallback for features unsupported by Crankshaft. // 2. Fallback for features unsupported by Crankshaft.
bool is_unsupported_by_crankshaft_but_turbofanable = bool is_unsupported_by_crankshaft_but_turbofanable =
must_use_ignition_turbo && strcmp(FLAG_turbo_filter, "~~") == 0 && must_use_ignition_turbo && strcmp(FLAG_turbo_filter, "~~") == 0;
!optimization_disabled;
// 3. Explicitly enabled by the command-line filter. // 3. Explicitly enabled by the command-line filter.
bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter);
......
...@@ -2429,7 +2429,8 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -2429,7 +2429,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
if (strcmp(argv[i], "--stress-opt") == 0) { if (strcmp(argv[i], "--stress-opt") == 0) {
options.stress_opt = true; options.stress_opt = true;
argv[i] = NULL; argv[i] = NULL;
} else if (strcmp(argv[i], "--nostress-opt") == 0) { } else if (strcmp(argv[i], "--nostress-opt") == 0 ||
strcmp(argv[i], "--no-stress-opt") == 0) {
options.stress_opt = false; options.stress_opt = false;
argv[i] = NULL; argv[i] = NULL;
} else if (strcmp(argv[i], "--stress-deopt") == 0) { } else if (strcmp(argv[i], "--stress-deopt") == 0) {
...@@ -2438,7 +2439,8 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -2438,7 +2439,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) { } else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) {
options.mock_arraybuffer_allocator = true; options.mock_arraybuffer_allocator = true;
argv[i] = NULL; argv[i] = NULL;
} else if (strcmp(argv[i], "--noalways-opt") == 0) { } else if (strcmp(argv[i], "--noalways-opt") == 0 ||
strcmp(argv[i], "--no-always-opt") == 0) {
// No support for stressing if we can't use --always-opt. // No support for stressing if we can't use --always-opt.
options.stress_opt = false; options.stress_opt = false;
options.stress_deopt = false; options.stress_deopt = false;
......
...@@ -236,21 +236,28 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) { ...@@ -236,21 +236,28 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 1 || args.length() == 2); DCHECK(args.length() == 1 || args.length() == 2);
int status = 0;
if (!isolate->use_crankshaft()) { if (!isolate->use_crankshaft()) {
return Smi::FromInt(4); // 4 == "never". status |= static_cast<int>(OptimizationStatus::kNeverOptimize);
}
if (FLAG_always_opt || FLAG_prepare_always_opt) {
status |= static_cast<int>(OptimizationStatus::kAlwaysOptimize);
}
if (FLAG_deopt_every_n_times) {
status |= static_cast<int>(OptimizationStatus::kMaybeDeopted);
} }
// This function is used by fuzzers to get coverage for optimizations // This function is used by fuzzers to get coverage for optimizations
// in compiler. Ignore calls on non-function objects to avoid runtime errors. // in compiler. Ignore calls on non-function objects to avoid runtime errors.
CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
if (!function_object->IsJSFunction()) { if (!function_object->IsJSFunction()) {
return isolate->heap()->undefined_value(); return Smi::FromInt(status);
} }
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
status |= static_cast<int>(OptimizationStatus::kIsFunction);
bool sync_with_compiler_thread = true; bool sync_with_compiler_thread = true;
if (args.length() == 2) { if (args.length() == 2) {
...@@ -269,22 +276,16 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { ...@@ -269,22 +276,16 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
base::OS::Sleep(base::TimeDelta::FromMilliseconds(50)); base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
} }
} }
if (FLAG_always_opt || FLAG_prepare_always_opt) { if (function->IsOptimized()) {
// With --always-opt, optimization status expectations might not status |= static_cast<int>(OptimizationStatus::kOptimized);
// match up, so just return a sentinel. if (function->code()->is_turbofanned()) {
return Smi::FromInt(3); // 3 == "always". status |= static_cast<int>(OptimizationStatus::kTurboFanned);
}
if (FLAG_deopt_every_n_times) {
return Smi::FromInt(6); // 6 == "maybe deopted".
} }
if (function->IsOptimized() && function->code()->is_turbofanned()) {
return Smi::FromInt(7); // 7 == "TurboFan compiler".
} }
if (function->IsInterpreted()) { if (function->IsInterpreted()) {
return Smi::FromInt(8); // 8 == "Interpreted". status |= static_cast<int>(OptimizationStatus::kInterpreted);
} }
return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". return Smi::FromInt(status);
: Smi::FromInt(2); // 2 == "no".
} }
......
...@@ -1153,6 +1153,18 @@ class DeclareGlobalsNativeFlag : public BitField<bool, 1, 1> {}; ...@@ -1153,6 +1153,18 @@ class DeclareGlobalsNativeFlag : public BitField<bool, 1, 1> {};
STATIC_ASSERT(LANGUAGE_END == 2); STATIC_ASSERT(LANGUAGE_END == 2);
class DeclareGlobalsLanguageMode : public BitField<LanguageMode, 2, 1> {}; class DeclareGlobalsLanguageMode : public BitField<LanguageMode, 2, 1> {};
// A set of bits returned by Runtime_GetOptimizationStatus.
// These bits must be in sync with bits defined in test/mjsunit/mjsunit.js
enum class OptimizationStatus {
kIsFunction = 1 << 0,
kNeverOptimize = 1 << 1,
kAlwaysOptimize = 1 << 2,
kMaybeDeopted = 1 << 3,
kOptimized = 1 << 4,
kTurboFanned = 1 << 5,
kInterpreted = 1 << 6,
};
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "src/compilation-cache.h" #include "src/compilation-cache.h"
#include "src/execution.h" #include "src/execution.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/runtime/runtime.h"
#include "src/unicode-inl.h" #include "src/unicode-inl.h"
#include "src/utils.h" #include "src/utils.h"
...@@ -4093,6 +4094,7 @@ THREADED_TEST(NamedPropertyHandlerGetterAttributes) { ...@@ -4093,6 +4094,7 @@ THREADED_TEST(NamedPropertyHandlerGetterAttributes) {
THREADED_TEST(Regress256330) { THREADED_TEST(Regress256330) {
if (!i::FLAG_crankshaft) return;
i::FLAG_allow_natives_syntax = true; i::FLAG_allow_natives_syntax = true;
LocalContext context; LocalContext context;
v8::HandleScope scope(context->GetIsolate()); v8::HandleScope scope(context->GetIsolate());
...@@ -4108,7 +4110,10 @@ THREADED_TEST(Regress256330) { ...@@ -4108,7 +4110,10 @@ THREADED_TEST(Regress256330) {
"f(o); f(o); f(o);" "f(o); f(o); f(o);"
"%OptimizeFunctionOnNextCall(f);" "%OptimizeFunctionOnNextCall(f);"
"f(o);"); "f(o);");
ExpectBoolean("%GetOptimizationStatus(f) != 2", true); int status = v8_run_int32value(v8_compile("%GetOptimizationStatus(f)"));
int mask = static_cast<int>(i::OptimizationStatus::kIsFunction) |
static_cast<int>(i::OptimizationStatus::kOptimized);
CHECK_EQ(mask, status & mask);
} }
......
...@@ -26,12 +26,15 @@ ...@@ -26,12 +26,15 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --no-always-opt
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
Debug = debug.Debug Debug = debug.Debug
function foo() { function foo() {
......
...@@ -66,15 +66,8 @@ ...@@ -66,15 +66,8 @@
############################################################################## ##############################################################################
['variant == turbofan_opt', { ['variant == turbofan_opt', {
# TODO(mstarzinger): Debugger cannot materialize de-materialized functions.
'debug/regress/regress-crbug-323936': [FAIL],
# TODO(jarin/mstarzinger): Investigate debugger issues with TurboFan. # TODO(jarin/mstarzinger): Investigate debugger issues with TurboFan.
'debug/debug-evaluate-closure': [FAIL],
'debug/debug-evaluate-locals': [FAIL], 'debug/debug-evaluate-locals': [FAIL],
'debug/debug-liveedit-double-call': [FAIL],
'debug/debug-set-variable-value': [FAIL],
'debug/es6/debug-evaluate-blockscopes': [FAIL],
}], # variant == turbofan_opt }], # variant == turbofan_opt
############################################################################## ##############################################################################
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc // Flags: --allow-natives-syntax --expose-gc --no-always-opt
assertFalse(isAlwaysOptimize());
var a = new Int32Array(1024); var a = new Int32Array(1024);
......
...@@ -26,7 +26,10 @@ ...@@ -26,7 +26,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc // Flags: --allow-natives-syntax --expose-gc
// Flags: --noalways-opt // Flags: --no-always-opt --crankshaft
assertFalse(isNeverOptimize());
assertFalse(isAlwaysOptimize());
// Test element kind of objects. // Test element kind of objects.
...@@ -84,7 +87,6 @@ function assertKind(expected, obj, name_opt) { ...@@ -84,7 +87,6 @@ function assertKind(expected, obj, name_opt) {
%OptimizeFunctionOnNextCall(bar0); %OptimizeFunctionOnNextCall(bar0);
b = bar0(Array); b = bar0(Array);
// This only makes sense to test if we allow crankshafting // This only makes sense to test if we allow crankshafting
if (4 != %GetOptimizationStatus(bar0)) {
// We also lost our ability to record kind feedback, as the site // We also lost our ability to record kind feedback, as the site
// is megamorphic now. // is megamorphic now.
assertKind(elements_kind.fast_smi_only, b); assertKind(elements_kind.fast_smi_only, b);
...@@ -92,7 +94,6 @@ function assertKind(expected, obj, name_opt) { ...@@ -92,7 +94,6 @@ function assertKind(expected, obj, name_opt) {
b[0] = 3.5; b[0] = 3.5;
c = bar0(Array); c = bar0(Array);
assertKind(elements_kind.fast_smi_only, c); assertKind(elements_kind.fast_smi_only, c);
}
})(); })();
...@@ -144,14 +145,12 @@ function assertKind(expected, obj, name_opt) { ...@@ -144,14 +145,12 @@ function assertKind(expected, obj, name_opt) {
%OptimizeFunctionOnNextCall(bar); %OptimizeFunctionOnNextCall(bar);
b = bar(); b = bar();
// This only makes sense to test if we allow crankshafting // This only makes sense to test if we allow crankshafting
if (4 != %GetOptimizationStatus(bar)) {
assertOptimized(bar); assertOptimized(bar);
%DebugPrint(3); %DebugPrint(3);
b[0] = 3.5; b[0] = 3.5;
c = bar(); c = bar();
assertKind(elements_kind.fast_smi_only, c); assertKind(elements_kind.fast_smi_only, c);
assertOptimized(bar); assertOptimized(bar);
}
})(); })();
...@@ -192,10 +191,8 @@ function assertKind(expected, obj, name_opt) { ...@@ -192,10 +191,8 @@ function assertKind(expected, obj, name_opt) {
a = bar(0); a = bar(0);
assertOptimized(bar); assertOptimized(bar);
// Crankshafted functions don't use mementos, so feedback still // Crankshafted functions don't use mementos, so feedback still
// indicates a packed array is desired. (unless --nocrankshaft is in use). // indicates a packed array is desired.
if (4 != %GetOptimizationStatus(bar)) {
assertFalse(isHoley(a)); assertFalse(isHoley(a));
}
})(); })();
// Test: Make sure that crankshaft continues with feedback for large arrays. // Test: Make sure that crankshaft continues with feedback for large arrays.
......
...@@ -25,7 +25,11 @@ ...@@ -25,7 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --ignition-osr // Flags: --allow-natives-syntax --expose-gc --ignition-osr --no-always-opt
// Flags: --crankshaft
assertFalse(isNeverOptimize());
assertFalse(isAlwaysOptimize());
// IC and Crankshaft support for smi-only elements in dynamic array literals. // IC and Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values. function get(foo) { return foo; } // Used to generate dynamic values.
...@@ -188,9 +192,7 @@ assertEquals(foo, array[2]); ...@@ -188,9 +192,7 @@ assertEquals(foo, array[2]);
(function literals_after_osr() { (function literals_after_osr() {
var color = [0]; var color = [0];
// Trigger OSR, if optimization is not disabled. // Trigger OSR.
if (%GetOptimizationStatus(literals_after_osr) != 4) {
while (%GetOptimizationCount(literals_after_osr) == 0) {} while (%GetOptimizationCount(literals_after_osr) == 0) {}
}
return [color[0]]; return [color[0]];
})(); })();
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
var v = 0; var v = 0;
......
...@@ -25,13 +25,15 @@ ...@@ -25,13 +25,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
// Verifies that the KeyedStoreIC correctly handles out-of-bounds stores // Verifies that the KeyedStoreIC correctly handles out-of-bounds stores
// to an array that grow it by a single element. Test functions are // to an array that grow it by a single element. Test functions are
// called twice to make sure that the IC is used, first call is handled // called twice to make sure that the IC is used, first call is handled
// by the runtime in the miss stub. // by the runtime in the miss stub.
assertFalse(isAlwaysOptimize());
function array_store_1(a,b,c) { function array_store_1(a,b,c) {
return (a[b] = c); return (a[b] = c);
} }
......
...@@ -43,18 +43,6 @@ function OptTracker() { ...@@ -43,18 +43,6 @@ function OptTracker() {
this.opt_counts_ = {}; this.opt_counts_ = {};
} }
/**
* The possible optimization states of a function. Must be in sync with the
* return values of Runtime_GetOptimizationStatus() in runtime.cc!
* @enum {int}
*/
OptTracker.OptimizationState = {
YES: 1,
NO: 2,
ALWAYS: 3,
NEVER: 4
};
/** /**
* Always call this at the beginning of your test, once for each function * Always call this at the beginning of your test, once for each function
* that you later want to track de/optimizations for. It is necessary because * that you later want to track de/optimizations for. It is necessary because
...@@ -94,12 +82,10 @@ OptTracker.prototype.AssertIsOptimized = function(func, expect_optimized) { ...@@ -94,12 +82,10 @@ OptTracker.prototype.AssertIsOptimized = function(func, expect_optimized) {
if (this.DisableAsserts_(func)) { if (this.DisableAsserts_(func)) {
return; return;
} }
var raw_optimized = %GetOptimizationStatus(func); var opt_status = %GetOptimizationStatus(func);
if (expect_optimized) { assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0);
assertEquals(OptTracker.OptimizationState.YES, raw_optimized); assertEquals(expect_optimized,
} else { (opt_status & V8OptimizationStatus.kOptimized) !== 0);
assertEquals(OptTracker.OptimizationState.NO, raw_optimized);
}
} }
/** /**
...@@ -119,7 +105,8 @@ OptTracker.prototype.GetOptCount_ = function(func) { ...@@ -119,7 +105,8 @@ OptTracker.prototype.GetOptCount_ = function(func) {
*/ */
OptTracker.prototype.GetDeoptCount_ = function(func) { OptTracker.prototype.GetDeoptCount_ = function(func) {
var count = this.GetOptCount_(func); var count = this.GetOptCount_(func);
if (%GetOptimizationStatus(func) == OptTracker.OptimizationState.YES) { var opt_status = %GetOptimizationStatus(func);
if ((opt_status & V8OptimizationStatus.kOptimized) !== 0) {
count -= 1; count -= 1;
} }
return count; return count;
...@@ -129,15 +116,9 @@ OptTracker.prototype.GetDeoptCount_ = function(func) { ...@@ -129,15 +116,9 @@ OptTracker.prototype.GetDeoptCount_ = function(func) {
* @private * @private
*/ */
OptTracker.prototype.DisableAsserts_ = function(func) { OptTracker.prototype.DisableAsserts_ = function(func) {
switch(%GetOptimizationStatus(func)) { var opt_status = %GetOptimizationStatus(func);
case OptTracker.OptimizationState.YES: return (opt_status & V8OptimizationStatus.kAlwaysOptimize) !== 0 ||
case OptTracker.OptimizationState.NO: (opt_status & V8OptimizationStatus.kNeverOptimize) !== 0;
return false;
case OptTracker.OptimizationState.ALWAYS:
case OptTracker.OptimizationState.NEVER:
return true;
}
return true;
} }
// (End of class OptTracker.) // (End of class OptTracker.)
......
...@@ -27,12 +27,15 @@ ...@@ -27,12 +27,15 @@
// Flags: --track-fields --track-double-fields --allow-natives-syntax // Flags: --track-fields --track-double-fields --allow-natives-syntax
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --no-always-opt
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
function new_object() { function new_object() {
var o = {}; var o = {};
o.a = 1; o.a = 1;
......
...@@ -27,12 +27,15 @@ ...@@ -27,12 +27,15 @@
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --no-always-opt
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
function f(foo) { return foo.bar(); } function f(foo) { return foo.bar(); }
var o = {}; var o = {};
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
var s = "12345"; var s = "12345";
......
...@@ -27,12 +27,15 @@ ...@@ -27,12 +27,15 @@
// Flags: --allow-natives-syntax --expose-gc // Flags: --allow-natives-syntax --expose-gc
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --no-always-opt
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
function f(x) { function f(x) {
var xx = x * x; var xx = x * x;
var xxstr = xx.toString(); var xxstr = xx.toString();
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --nostress-opt // Flags: --nostress-opt --no-always-opt
// --nostress-opt is in place because this particular optimization // --nostress-opt is in place because this particular optimization
// (guaranteeing that the Array prototype chain has no elements) is // (guaranteeing that the Array prototype chain has no elements) is
...@@ -41,6 +41,8 @@ if (!%IsConcurrentRecompilationSupported()) { ...@@ -41,6 +41,8 @@ if (!%IsConcurrentRecompilationSupported()) {
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
function f1(a, i) { function f1(a, i) {
return a[i] + 0.5; return a[i] + 0.5;
} }
......
...@@ -81,10 +81,10 @@ test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); ...@@ -81,10 +81,10 @@ test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5);
test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5);
%OptimizeFunctionOnNextCall(test); %OptimizeFunctionOnNextCall(test);
test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5);
assertTrue(2 != %GetOptimizationStatus(test)); assertOptimized(test);
// By deleting the field we are forcing the code to deopt when the field is // By deleting the field we are forcing the code to deopt when the field is
// read on next execution. // read on next execution.
delete deopt_trigger; delete deopt_trigger;
test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5); test(10.0, 20.0, 30.0, 40.0, 50.0, 1.5);
assertTrue(1 != %GetOptimizationStatus(test)); assertUnoptimized(test);
...@@ -2,14 +2,18 @@ ...@@ -2,14 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --noverify-heap --noenable-slow-asserts // Flags: --allow-natives-syntax --noverify-heap --noenable-slow-asserts
// Flags: --no-always-opt --crankshaft
// --noverify-heap and --noenable-slow-asserts are set because the test is too // --noverify-heap and --noenable-slow-asserts are set because the test is too
// slow with it on. // slow with it on.
// Ensure that keyed stores work, and optimized functions learn if the assertFalse(isNeverOptimize());
// store required change to dictionary mode. Verify that stores that grow assertFalse(isAlwaysOptimize());
// the array into large object space don't cause a deopt.
// Ensure that keyed stores work, and optimized functions learn if the
// store required change to dictionary mode. Verify that stores that grow
// the array into large object space don't cause a deopt.
(function() { (function() {
var a = []; var a = [];
...@@ -60,8 +64,6 @@ ...@@ -60,8 +64,6 @@
%OptimizeFunctionOnNextCall(foo2); %OptimizeFunctionOnNextCall(foo2);
foo2(a, 40); foo2(a, 40);
// This test is way too slow without crankshaft.
if (4 != %GetOptimizationStatus(foo2)) {
assertOptimized(foo2); assertOptimized(foo2);
assertTrue(%HasFastSmiElements(a)); assertTrue(%HasFastSmiElements(a));
...@@ -80,7 +82,6 @@ ...@@ -80,7 +82,6 @@
assertTrue(%HasFastSmiElements(a)); assertTrue(%HasFastSmiElements(a));
assertTrue(a.length * 4 > (1024 * 1024)); assertTrue(a.length * 4 > (1024 * 1024));
assertOptimized(foo2); assertOptimized(foo2);
}
%ClearFunctionTypeFeedback(foo2); %ClearFunctionTypeFeedback(foo2);
})(); })();
...@@ -6,21 +6,6 @@ ...@@ -6,21 +6,6 @@
"use strict"; "use strict";
const kDeoptimized = 2;
const kTurbofanned = 7;
const kInterpreted = 8;
function GetOptimizationStatus(fn) {
let status = %GetOptimizationStatus(fn);
switch (status) {
case kInterpreted: // Treat interpreted frames as unoptimized
status = kDeoptimized;
break;
}
return status;
}
let global = this; let global = this;
let tests = { let tests = {
FastElementsKind() { FastElementsKind() {
...@@ -118,15 +103,27 @@ let tests = { ...@@ -118,15 +103,27 @@ let tests = {
// TODO(bmeurer): FAST_HOLEY_DOUBLE_ELEMENTS maps generally deopt when // TODO(bmeurer): FAST_HOLEY_DOUBLE_ELEMENTS maps generally deopt when
// a hole is encountered. Test should be fixed once that is corrected. // a hole is encountered. Test should be fixed once that is corrected.
let status = /HOLEY_DOUBLE/.test(key) ? kDeoptimized : kTurbofanned; let expect_deopt = /HOLEY_DOUBLE/.test(key);
assertEquals(status, GetOptimizationStatus(fn), key); if (expect_deopt) {
assertUnoptimized(fn, '', key);
} else {
assertOptimized(fn, '', key);
}
assertEquals(expected, fn(array), key); assertEquals(expected, fn(array), key);
assertEquals(status, GetOptimizationStatus(fn), key); if (expect_deopt) {
assertUnoptimized(fn, '', key);
} else {
assertOptimized(fn, '', key);
}
// Check no deopt when another arra with the same map is used // Check no deopt when another array with the same map is used
assertTrue(%HaveSameMap(array, array2), key); assertTrue(%HaveSameMap(array, array2), key);
assertEquals(status, GetOptimizationStatus(fn), key); if (expect_deopt) {
assertUnoptimized(fn, '', key);
} else {
assertOptimized(fn, '', key);
}
assertEquals(expected2, fn(array2), key); assertEquals(expected2, fn(array2), key);
// CheckMaps bailout // CheckMaps bailout
...@@ -134,7 +131,7 @@ let tests = { ...@@ -134,7 +131,7 @@ let tests = {
[1, 2, 3], 2, { enumerable: false, configurable: false, [1, 2, 3], 2, { enumerable: false, configurable: false,
get() { return 7; } }); get() { return 7; } });
fn(newArray); fn(newArray);
assertEquals(kDeoptimized, GetOptimizationStatus(fn), key); assertUnoptimized(fn, '', key);
} }
}, },
...@@ -222,12 +219,12 @@ let tests = { ...@@ -222,12 +219,12 @@ let tests = {
%OptimizeFunctionOnNextCall(sum); %OptimizeFunctionOnNextCall(sum);
assertEquals(expected, sum(array), key); assertEquals(expected, sum(array), key);
assertEquals(kTurbofanned, GetOptimizationStatus(sum), key); assertOptimized(sum, '', key);
// Not deoptimized when called on typed array of same type / map // Not deoptimized when called on typed array of same type / map
assertTrue(%HaveSameMap(array, array2)); assertTrue(%HaveSameMap(array, array2));
assertEquals(expected2, sum(array2), key); assertEquals(expected2, sum(array2), key);
assertEquals(kTurbofanned, GetOptimizationStatus(sum), key); assertOptimized(sum, '', key);
// Throw when detached // Throw when detached
let clone = new array.constructor(array); let clone = new array.constructor(array);
......
...@@ -478,5 +478,5 @@ for (var i=0; i<10; i++) { ...@@ -478,5 +478,5 @@ for (var i=0; i<10; i++) {
f(12); f(12);
g(12); g(12);
assertTrue(%GetOptimizationStatus(f) != 2); assertOptimized(f);
assertTrue(%GetOptimizationStatus(g) != 2); assertOptimized(g);
...@@ -480,5 +480,5 @@ for (var i=0; i<10; i++) { ...@@ -480,5 +480,5 @@ for (var i=0; i<10; i++) {
f(12); f(12);
g(12); g(12);
assertTrue(%GetOptimizationStatus(f) != 2); assertOptimized(f);
assertTrue(%GetOptimizationStatus(g) != 2); assertOptimized(g);
...@@ -40,7 +40,7 @@ function f1() { ...@@ -40,7 +40,7 @@ function f1() {
for (var j = 0; j < 5; ++j) f1(); for (var j = 0; j < 5; ++j) f1();
%OptimizeFunctionOnNextCall(f1); %OptimizeFunctionOnNextCall(f1);
f1(); f1();
assertTrue(%GetOptimizationStatus(f1) != 2); assertOptimized(f1);
// Dynamic lookup in and through block contexts. // Dynamic lookup in and through block contexts.
function f2(one) { function f2(one) {
......
...@@ -42,7 +42,7 @@ function f1() { ...@@ -42,7 +42,7 @@ function f1() {
for (var j = 0; j < 5; ++j) f1(); for (var j = 0; j < 5; ++j) f1();
%OptimizeFunctionOnNextCall(f1); %OptimizeFunctionOnNextCall(f1);
f1(); f1();
assertTrue(%GetOptimizationStatus(f1) != 2); assertOptimized(f1);
// Dynamic lookup in and through block contexts. // Dynamic lookup in and through block contexts.
function f2(one) { function f2(one) {
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --nostress-opt --track-field-types // Flags: --allow-natives-syntax --nostress-opt --track-field-types
// Flags: --no-always-opt
assertFalse(isAlwaysOptimize());
(function() { (function() {
var o = { text: "Hello World!" }; var o = { text: "Hello World!" };
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --harmony-do-expressions --allow-natives-syntax // Flags: --harmony-do-expressions --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
function returnValue(v) { return v; } function returnValue(v) { return v; }
function MyError() {} function MyError() {}
......
...@@ -3,13 +3,15 @@ ...@@ -3,13 +3,15 @@
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Flags: --nostress-opt // Flags: --nostress-opt --no-always-opt
// --nostress-opt is specified because the test corrupts the "pristine" // --nostress-opt is specified because the test corrupts the "pristine"
// array prototype chain by storing an element, and this is tracked // array prototype chain by storing an element, and this is tracked
// per-isolate. A subsequent stress run would send the load generic, // per-isolate. A subsequent stress run would send the load generic,
// and no more deoptimizations of foo would occur. // and no more deoptimizations of foo would occur.
assertFalse(isAlwaysOptimize());
function foo(a, i) { return a[i]; } function foo(a, i) { return a[i]; }
var a = ['one', , 'three']; var a = ['one', , 'three'];
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
var s = Symbol("foo"); var s = Symbol("foo");
var o = { var o = {
......
...@@ -120,6 +120,38 @@ var assertContains; ...@@ -120,6 +120,38 @@ var assertContains;
// Assert that a string matches a given regex. // Assert that a string matches a given regex.
var assertMatches; var assertMatches;
// These bits must be in sync with bits defined in Runtime_GetOptimizationStatus
var V8OptimizationStatus = {
kIsFunction: 1 << 0,
kNeverOptimize: 1 << 1,
kAlwaysOptimize: 1 << 2,
kMaybeDeopted: 1 << 3,
kOptimized: 1 << 4,
kTurboFanned: 1 << 5,
kInterpreted: 1 << 6
};
// Returns true if --no-crankshaft mode is on.
var isNeverOptimize;
// Returns true if --always-opt mode is on.
var isAlwaysOptimize;
// Returns true if given function in interpreted.
var isInterpreted;
// Returns true if given function is compiled by a base-line compiler.
var isBaselined;
// Returns true if given function is optimized.
var isOptimized;
// Returns true if given function is compiled by Crankshaft.
var isCrankshafted;
// Returns true if given function is compiled by TurboFan.
var isTurboFanned;
(function () { // Scope for utility functions. (function () { // Scope for utility functions.
...@@ -462,12 +494,72 @@ var assertMatches; ...@@ -462,12 +494,72 @@ var assertMatches;
assertUnoptimized = function assertUnoptimized(fun, sync_opt, name_opt) { assertUnoptimized = function assertUnoptimized(fun, sync_opt, name_opt) {
if (sync_opt === undefined) sync_opt = ""; if (sync_opt === undefined) sync_opt = "";
assertTrue(OptimizationStatus(fun, sync_opt) !== 1, name_opt); var opt_status = OptimizationStatus(fun, sync_opt);
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0, name_opt);
assertFalse((opt_status & V8OptimizationStatus.kOptimized) !== 0, name_opt);
} }
assertOptimized = function assertOptimized(fun, sync_opt, name_opt) { assertOptimized = function assertOptimized(fun, sync_opt, name_opt) {
if (sync_opt === undefined) sync_opt = ""; if (sync_opt === undefined) sync_opt = "";
assertTrue(OptimizationStatus(fun, sync_opt) !== 2, name_opt); var opt_status = OptimizationStatus(fun, sync_opt);
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0, name_opt);
if ((opt_status & V8OptimizationStatus.kNeverOptimize) !== 0) {
// TODO(ishell): every test that calls %OptimizeFunctionOnNextCall()
// does not make sense when --no-crankshaft option is provided.
return;
}
assertTrue((opt_status & V8OptimizationStatus.kOptimized) !== 0, name_opt);
}
isNeverOptimize = function isNeverOptimize() {
var opt_status = OptimizationStatus(undefined, "");
return (opt_status & V8OptimizationStatus.kNeverOptimize) !== 0;
}
isAlwaysOptimize = function isAlwaysOptimize() {
var opt_status = OptimizationStatus(undefined, "");
return (opt_status & V8OptimizationStatus.kAlwaysOptimize) !== 0;
}
isInterpreted = function isInterpreted(fun) {
var opt_status = OptimizationStatus(fun, "");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0,
"not a function");
return (opt_status & V8OptimizationStatus.kOptimized) === 0 &&
(opt_status & V8OptimizationStatus.kInterpreted) !== 0;
}
// NOTE: This predicate also returns true for functions that have never
// been compiled (i.e. that have LazyCompile stub as a code).
isBaselined = function isBaselined(fun) {
var opt_status = OptimizationStatus(fun, "");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0,
"not a function");
return (opt_status & V8OptimizationStatus.kOptimized) === 0 &&
(opt_status & V8OptimizationStatus.kInterpreted) === 0;
}
isOptimized = function isOptimized(fun) {
var opt_status = OptimizationStatus(fun, "");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0,
"not a function");
return (opt_status & V8OptimizationStatus.kOptimized) !== 0;
}
isCrankshafted = function isCrankshafted(fun) {
var opt_status = OptimizationStatus(fun, "");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0,
"not a function");
return (opt_status & V8OptimizationStatus.kOptimized) !== 0 &&
(opt_status & V8OptimizationStatus.kTurboFanned) === 0;
}
isTurboFanned = function isTurboFanned(fun) {
var opt_status = OptimizationStatus(fun, "");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0,
"not a function");
return (opt_status & V8OptimizationStatus.kOptimized) !== 0 &&
(opt_status & V8OptimizationStatus.kTurboFanned) !== 0;
} }
})(); })();
...@@ -30,34 +30,30 @@ ...@@ -30,34 +30,30 @@
function o1() { function o1() {
} }
if (%GetOptimizationStatus(o1) != 4) { o1(); o1();
// 4 == optimization disabled. %OptimizeFunctionOnNextCall(o1);
o1(); o1(); o1();
%OptimizeFunctionOnNextCall(o1);
o1();
// Check that the given function was optimized. // Check that the given function was optimized.
assertOptimized(o1); assertOptimized(o1);
// Test the %NeverOptimizeFunction runtime call. // Test the %NeverOptimizeFunction runtime call.
%NeverOptimizeFunction(u1); %NeverOptimizeFunction(u1);
function u1() { function u1() {
} }
function u2() { function u2() {
u1(); u1();
} }
u1(); u1(); u1(); u1();
u2(); u2(); u2(); u2();
%OptimizeFunctionOnNextCall(u1); %OptimizeFunctionOnNextCall(u1);
%OptimizeFunctionOnNextCall(u2); %OptimizeFunctionOnNextCall(u2);
u1(); u1(); u1(); u1();
u2(); u2(); u2(); u2();
// 2 => not optimized. assertUnoptimized(u1);
assertUnoptimized(u1); assertOptimized(u2);
assertOptimized(u2);
}
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --use-osr --allow-natives-syntax --ignition-osr // Flags: --use-osr --allow-natives-syntax --ignition-osr --crankshaft
assertFalse(isNeverOptimize());
function f() { function f() {
do { do {
...@@ -36,7 +38,7 @@ function f() { ...@@ -36,7 +38,7 @@ function f() {
} }
f(); f();
assertTrue(%GetOptimizationCount(f) > 0 || %GetOptimizationStatus(f) == 4); assertTrue(%GetOptimizationCount(f) > 0);
function g() { function g() {
for (var i = 0; i < 1; i++) { } for (var i = 0; i < 1; i++) { }
...@@ -67,4 +69,4 @@ function g() { ...@@ -67,4 +69,4 @@ function g() {
} }
g(); g();
assertTrue(%GetOptimizationCount(g) > 0 || %GetOptimizationStatus(g) == 4); assertTrue(%GetOptimizationCount(g) > 0);
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
function getobj() { function getobj() {
return { bar : function() { return 0}}; return { bar : function() { return 0}};
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
var calls = 0; var calls = 0;
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax --no-always-opt
assertFalse(isAlwaysOptimize());
function literals_sharing_test(warmup, optimize) { function literals_sharing_test(warmup, optimize) {
function closure() { function closure() {
...@@ -39,10 +41,4 @@ function test() { ...@@ -39,10 +41,4 @@ function test() {
literals_sharing_test(warmup, true); literals_sharing_test(warmup, true);
} }
test();
function stress_opt_test() {}
stress_opt_test();
if (%GetOptimizationStatus(stress_opt_test) == 2) {
// This test is not suitable for --always-opt mode.
test();
}
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
// New space must be at max capacity to trigger pretenuring decision. // New space must be at max capacity to trigger pretenuring decision.
// Flags: --allow-natives-syntax --verify-heap --max-semi-space-size=1 // Flags: --allow-natives-syntax --verify-heap --max-semi-space-size=1
// Flags: --expose-gc // Flags: --expose-gc --no-always-opt
assertFalse(isAlwaysOptimize());
var global = []; // Used to keep some objects alive. var global = []; // Used to keep some objects alive.
......
...@@ -79,4 +79,8 @@ assertOptimized(inferrable_store); ...@@ -79,4 +79,8 @@ assertOptimized(inferrable_store);
// seeing a property name key. It should have inferred a receiver map and // seeing a property name key. It should have inferred a receiver map and
// emitted an elements store, however. // emitted an elements store, however.
inferrable_store("deopt"); inferrable_store("deopt");
assertUnoptimized(inferrable_store);
// TurboFan is not sophisticated enough to use key type provided by ICs.
if (!isTurboFanned(inferrable_store)) {
assertUnoptimized(inferrable_store);
}
...@@ -28,12 +28,15 @@ ...@@ -28,12 +28,15 @@
// Flags: --fold-constants --nodead-code-elimination // Flags: --fold-constants --nodead-code-elimination
// Flags: --expose-gc --allow-natives-syntax // Flags: --expose-gc --allow-natives-syntax
// Flags: --concurrent-recompilation --block-concurrent-recompilation // Flags: --concurrent-recompilation --block-concurrent-recompilation
// Flags: --no-always-opt
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
quit(); quit();
} }
assertFalse(isAlwaysOptimize());
function test(fun) { function test(fun) {
fun(); fun();
%BaselineFunctionOnNextCall(fun); %BaselineFunctionOnNextCall(fun);
......
...@@ -9,6 +9,7 @@ function load(o) { return o.x; } ...@@ -9,6 +9,7 @@ function load(o) { return o.x; }
for (var x = 0; x < 1000; ++x) { for (var x = 0; x < 1000; ++x) {
load({x}); load({x});
load({x}); load({x});
%OptimizeFunctionOnNextCall(load);
try { load(); } catch (e) { } try { load(); } catch (e) { }
} }
...@@ -20,6 +21,7 @@ function store(o) { o.x = -1; } ...@@ -20,6 +21,7 @@ function store(o) { o.x = -1; }
for (var x = 0; x < 1000; ++x) { for (var x = 0; x < 1000; ++x) {
store({x}); store({x});
store({x}); store({x});
%OptimizeFunctionOnNextCall(store);
try { store(); } catch (e) { } try { store(); } catch (e) { }
} }
......
...@@ -13,20 +13,20 @@ ...@@ -13,20 +13,20 @@
} }
sum += f(i); sum += f(i);
if (%GetOptimizationStatus(f) == 3 || %GetOptimizationStatus(f) == 4) { if (isAlwaysOptimize() || isNeverOptimize()) {
// If we are always or never optimizing f, just exit, this test is useless. // If we are always or never optimizing f, just exit, this test is useless.
return; return;
} }
if (i == 1) { if (i == 1) {
// f must be baseline code. // f must be baseline code.
assertEquals(2, %GetOptimizationStatus(f)); assertTrue(isBaselined(f));
// Run twice (i = 0, 1), then tier-up. // Run twice (i = 0, 1), then tier-up.
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
} else if (i == 2) { } else if (i == 2) {
// Tier-up at i = 2 should go up to crankshaft. // Tier-up at i = 2 should go up to crankshaft.
assertEquals(1, %GetOptimizationStatus(f)); assertTrue(isCrankshafted(f));
} }
} }
})() })()
...@@ -13,29 +13,30 @@ ...@@ -13,29 +13,30 @@
} }
sum += f(i); sum += f(i);
if (%GetOptimizationStatus(f) == 3 || %GetOptimizationStatus(f) == 4) { if (isAlwaysOptimize() || isNeverOptimize()) {
// If we are always or never optimizing f, just exit, this test is useless. // If we are always or never optimizing f, just exit, this test is useless.
return; return;
} }
if (i == 1) { if (i == 1) {
// f must be interpreted code. // f must be interpreted code.
assertEquals(8, %GetOptimizationStatus(f)); assertTrue(isInterpreted(f));
// Allow it to run twice (i = 0, 1), then tier-up to baseline. // Allow it to run twice (i = 0, 1), then tier-up to baseline.
%BaselineFunctionOnNextCall(f); %BaselineFunctionOnNextCall(f);
} else if (i == 2) { } else if (i == 2) {
// Tier-up at i = 2 should only go up to baseline. // Tier-up at i = 2 should only go up to baseline.
assertEquals(2, %GetOptimizationStatus(f)); assertTrue(isBaselined(f));
} else if (i == 3) { } else if (i == 3) {
// Now f must be baseline code. // Now f must be baseline code.
assertEquals(2, %GetOptimizationStatus(f)); assertTrue(isBaselined(f));
// Run two more times (i = 2, 3), then tier-up to optimized. // Run two more times (i = 2, 3), then tier-up to optimized.
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
} else if (i == 4) { } else if (i == 4) {
// Tier-up at i = 4 should now go up to crankshaft. // Tier-up at i = 4 should now go up to crankshaft.
assertEquals(1, %GetOptimizationStatus(f)); assertTrue(isCrankshafted(f));
} }
} }
})() })()
...@@ -13,20 +13,20 @@ ...@@ -13,20 +13,20 @@
} }
sum += f(i); sum += f(i);
if (%GetOptimizationStatus(f) == 3 || %GetOptimizationStatus(f) == 4) { if (isAlwaysOptimize() || isNeverOptimize()) {
// If we are always or never optimizing f, just exit, this test is useless. // If we are always or never optimizing f, just exit, this test is useless.
return; return;
} }
if (i == 1) { if (i == 1) {
// f must be interpreted code. // f must be interpreted code.
assertEquals(8, %GetOptimizationStatus(f)); assertTrue(isInterpreted(f));
// Run twice (i = 0, 1), then tier-up. // Run twice (i = 0, 1), then tier-up.
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
} else if (i == 2) { } else if (i == 2) {
// Tier-up at i = 2 should go up to turbofan. // Tier-up at i = 2 should go up to turbofan.
assertEquals(7, %GetOptimizationStatus(f)); assertTrue(isTurboFanned(f));
} }
} }
})() })()
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