diff options
Diffstat (limited to 'deps/v8/test/cctest/test-deoptimization.cc')
-rw-r--r-- | deps/v8/test/cctest/test-deoptimization.cc | 623 |
1 files changed, 349 insertions, 274 deletions
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc index 3127acc6a6..a201ccd7e4 100644 --- a/deps/v8/test/cctest/test-deoptimization.cc +++ b/deps/v8/test/cctest/test-deoptimization.cc @@ -35,7 +35,6 @@ #include "src/debug.h" #include "src/deoptimizer.h" #include "src/isolate.h" -#include "src/stub-cache.h" #include "test/cctest/cctest.h" using ::v8::base::OS; @@ -99,8 +98,8 @@ class AllowNativesSyntaxNoInlining { // Abort any ongoing incremental marking to make sure that all weak global // handle callbacks are processed. -static void NonIncrementalGC() { - CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); +static void NonIncrementalGC(i::Isolate* isolate) { + isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); } @@ -128,7 +127,7 @@ TEST(DeoptimizeSimple) { "function f() { g(); };" "f();"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -144,7 +143,7 @@ TEST(DeoptimizeSimple) { "function f(x) { if (x) { g(); } else { return } };" "f(true);"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -168,7 +167,7 @@ TEST(DeoptimizeSimpleWithArguments) { "function f(x, y, z) { g(1,x); y+z; };" "f(1, \"2\", false);"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -185,7 +184,7 @@ TEST(DeoptimizeSimpleWithArguments) { "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" "f(true, 1, \"2\");"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); @@ -210,7 +209,7 @@ TEST(DeoptimizeSimpleNested) { "function g(z) { count++; %DeoptimizeFunction(f); return z;}" "function f(x,y,z) { return h(x, y, g(z)); };" "result = f(1, 2, 3);"); - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -236,7 +235,7 @@ TEST(DeoptimizeRecursive) { "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" "f(10);"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); @@ -269,7 +268,7 @@ TEST(DeoptimizeMultiple) { "function f1(x) { return f2(x + 1, x + 1) + x; };" "result = f1(1);"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -291,7 +290,7 @@ TEST(DeoptimizeConstructor) { "function f() { g(); };" "result = new f() instanceof f;"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); @@ -308,7 +307,7 @@ TEST(DeoptimizeConstructor) { "result = new f(1, 2);" "result = result.x + result.y;"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -338,7 +337,7 @@ TEST(DeoptimizeConstructorMultiple) { "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" "result = new f1(1).result;"); } - NonIncrementalGC(); + NonIncrementalGC(CcTest::i_isolate()); CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); @@ -346,51 +345,61 @@ TEST(DeoptimizeConstructorMultiple) { } -TEST(DeoptimizeBinaryOperationADDString) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; AllowNativesSyntaxNoInlining options; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - - const char* f_source = "function f(x, y) { return x + y; };"; - + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); { - // Compile function f and collect to type feedback to insert binary op stub - // call in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun("var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.toString = function () {" - " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" - "};"); - CompileRun(f_source); - CompileRun("for (var i = 0; i < 5; i++) {" - " f('a+', new X());" - "};"); - - // Compile an optimized version of f. - i::FLAG_always_opt = true; - CompileRun(f_source); - CompileRun("f('a+', new X());"); - CHECK(!CcTest::i_isolate()->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); - - // Call f and force deoptimization while processing the binary operation. - CompileRun("deopt = true;" - "var result = f('a+', new X());"); - } - NonIncrementalGC(); + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); + + const char* f_source = "function f(x, y) { return x + y; };"; + + { + // Compile function f and collect to type feedback to insert binary op + // stub call in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun( + "var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.toString = function () {" + " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" + "};"); + CompileRun(f_source); + CompileRun( + "for (var i = 0; i < 5; i++) {" + " f('a+', new X());" + "};"); + + // Compile an optimized version of f. + i::FLAG_always_opt = true; + CompileRun(f_source); + CompileRun("f('a+', new X());"); + CHECK(!i_isolate->use_crankshaft() || + GetJSFunction(env->Global(), "f")->IsOptimized()); + + // Call f and force deoptimization while processing the binary operation. + CompileRun( + "deopt = true;" + "var result = f('a+', new X());"); + } + NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); - CHECK(result->IsString()); - v8::String::Utf8Value utf8(result); - CHECK_EQ("a+an X", *utf8); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); + CHECK(result->IsString()); + v8::String::Utf8Value utf8(result); + CHECK_EQ("a+an X", *utf8); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } @@ -407,6 +416,7 @@ static void CompileConstructorWithDeoptimizingValueOf() { static void TestDeoptimizeBinaryOpHelper(LocalContext* env, const char* binary_op) { + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>((*env)->GetIsolate()); EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer; SNPrintF(f_source_buffer, "function f(x, y) { return x %s y; };", @@ -427,290 +437,355 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, i::FLAG_always_opt = true; CompileRun(f_source); CompileRun("f(7, new X());"); - CHECK(!CcTest::i_isolate()->use_crankshaft() || + CHECK(!i_isolate->use_crankshaft() || GetJSFunction((*env)->Global(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. CompileRun("deopt = true;" "var result = f(7, new X());"); - NonIncrementalGC(); + NonIncrementalGC(i_isolate); CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); } -TEST(DeoptimizeBinaryOperationADD) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); + { + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "+"); + TestDeoptimizeBinaryOpHelper(&env, "+"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeBinaryOperationSUB) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); + { + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "-"); + TestDeoptimizeBinaryOpHelper(&env, "-"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeBinaryOperationMUL) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); + { + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "*"); + TestDeoptimizeBinaryOpHelper(&env, "*"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeBinaryOperationDIV) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); + { + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "/"); + TestDeoptimizeBinaryOpHelper(&env, "/"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeBinaryOperationMOD) { +UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); + { + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); - TestDeoptimizeBinaryOpHelper(&env, "%"); + TestDeoptimizeBinaryOpHelper(&env, "%"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeCompare) { +UNINITIALIZED_TEST(DeoptimizeCompare) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - - const char* f_source = "function f(x, y) { return x < y; };"; - + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); { - AllowNativesSyntaxNoInlining options; - // Compile function f and collect to type feedback to insert compare ic - // call in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun("var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.toString = function () {" - " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" - "};"); - CompileRun(f_source); - CompileRun("for (var i = 0; i < 5; i++) {" - " f('a', new X());" - "};"); - - // Compile an optimized version of f. - i::FLAG_always_opt = true; - CompileRun(f_source); - CompileRun("f('a', new X());"); - CHECK(!CcTest::i_isolate()->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); - - // Call f and force deoptimization while processing the comparison. - CompileRun("deopt = true;" - "var result = f('a', new X());"); - } - NonIncrementalGC(); + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); + + const char* f_source = "function f(x, y) { return x < y; };"; + + { + AllowNativesSyntaxNoInlining options; + // Compile function f and collect to type feedback to insert compare ic + // call in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun( + "var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.toString = function () {" + " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" + "};"); + CompileRun(f_source); + CompileRun( + "for (var i = 0; i < 5; i++) {" + " f('a', new X());" + "};"); + + // Compile an optimized version of f. + i::FLAG_always_opt = true; + CompileRun(f_source); + CompileRun("f('a', new X());"); + CHECK(!i_isolate->use_crankshaft() || + GetJSFunction(env->Global(), "f")->IsOptimized()); + + // Call f and force deoptimization while processing the comparison. + CompileRun( + "deopt = true;" + "var result = f('a', new X());"); + } + NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); + CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); + CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); + } + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeLoadICStoreIC) { +UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - - // Functions to generate load/store/keyed load/keyed store IC calls. - const char* f1_source = "function f1(x) { return x.y; };"; - const char* g1_source = "function g1(x) { x.y = 1; };"; - const char* f2_source = "function f2(x, y) { return x[y]; };"; - const char* g2_source = "function g2(x, y) { x[y] = 1; };"; - + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); { - AllowNativesSyntaxNoInlining options; - // Compile functions and collect to type feedback to insert ic - // calls in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun("var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.__defineGetter__('y', function () {" - " if (deopt) { count++; %DeoptimizeFunction(f1); };" - " return 13;" - "});" - "X.prototype.__defineSetter__('y', function () {" - " if (deopt) { count++; %DeoptimizeFunction(g1); };" - "});" - "X.prototype.__defineGetter__('z', function () {" - " if (deopt) { count++; %DeoptimizeFunction(f2); };" - " return 13;" - "});" - "X.prototype.__defineSetter__('z', function () {" - " if (deopt) { count++; %DeoptimizeFunction(g2); };" - "});"); - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("for (var i = 0; i < 5; i++) {" - " f1(new X());" - " g1(new X());" - " f2(new X(), 'z');" - " g2(new X(), 'z');" - "};"); - - // Compile an optimized version of the functions. - i::FLAG_always_opt = true; - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("f1(new X());"); - CompileRun("g1(new X());"); - CompileRun("f2(new X(), 'z');"); - CompileRun("g2(new X(), 'z');"); - if (CcTest::i_isolate()->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); + + // Functions to generate load/store/keyed load/keyed store IC calls. + const char* f1_source = "function f1(x) { return x.y; };"; + const char* g1_source = "function g1(x) { x.y = 1; };"; + const char* f2_source = "function f2(x, y) { return x[y]; };"; + const char* g2_source = "function g2(x, y) { x[y] = 1; };"; + + { + AllowNativesSyntaxNoInlining options; + // Compile functions and collect to type feedback to insert ic + // calls in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun( + "var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.__defineGetter__('y', function () {" + " if (deopt) { count++; %DeoptimizeFunction(f1); };" + " return 13;" + "});" + "X.prototype.__defineSetter__('y', function () {" + " if (deopt) { count++; %DeoptimizeFunction(g1); };" + "});" + "X.prototype.__defineGetter__('z', function () {" + " if (deopt) { count++; %DeoptimizeFunction(f2); };" + " return 13;" + "});" + "X.prototype.__defineSetter__('z', function () {" + " if (deopt) { count++; %DeoptimizeFunction(g2); };" + "});"); + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun( + "for (var i = 0; i < 5; i++) {" + " f1(new X());" + " g1(new X());" + " f2(new X(), 'z');" + " g2(new X(), 'z');" + "};"); + + // Compile an optimized version of the functions. + i::FLAG_always_opt = true; + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("f1(new X());"); + CompileRun("g1(new X());"); + CompileRun("f2(new X(), 'z');"); + CompileRun("g2(new X(), 'z');"); + if (i_isolate->use_crankshaft()) { + CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + } + + // Call functions and force deoptimization while processing the ics. + CompileRun( + "deopt = true;" + "var result = f1(new X());" + "g1(new X());" + "f2(new X(), 'z');" + "g2(new X(), 'z');"); } - - // Call functions and force deoptimization while processing the ics. - CompileRun("deopt = true;" - "var result = f1(new X());" - "g1(new X());" - "f2(new X(), 'z');" - "g2(new X(), 'z');"); + NonIncrementalGC(i_isolate); + + CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); } - NonIncrementalGC(); - - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + isolate->Exit(); + isolate->Dispose(); } -TEST(DeoptimizeLoadICStoreICNested) { +UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) { i::FLAG_turbo_deoptimization = true; i::FLAG_concurrent_recompilation = false; - LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - - // Functions to generate load/store/keyed load/keyed store IC calls. - const char* f1_source = "function f1(x) { return x.y; };"; - const char* g1_source = "function g1(x) { x.y = 1; };"; - const char* f2_source = "function f2(x, y) { return x[y]; };"; - const char* g2_source = "function g2(x, y) { x[y] = 1; };"; - + v8::Isolate* isolate = v8::Isolate::New(); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + isolate->Enter(); { - AllowNativesSyntaxNoInlining options; - // Compile functions and collect to type feedback to insert ic - // calls in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileRun("var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.__defineGetter__('y', function () {" - " g1(this);" - " return 13;" - "});" - "X.prototype.__defineSetter__('y', function () {" - " f2(this, 'z');" - "});" - "X.prototype.__defineGetter__('z', function () {" - " g2(this, 'z');" - "});" - "X.prototype.__defineSetter__('z', function () {" - " if (deopt) {" - " count++;" - " %DeoptimizeFunction(f1);" - " %DeoptimizeFunction(g1);" - " %DeoptimizeFunction(f2);" - " %DeoptimizeFunction(g2); };" - "});"); - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("for (var i = 0; i < 5; i++) {" - " f1(new X());" - " g1(new X());" - " f2(new X(), 'z');" - " g2(new X(), 'z');" - "};"); - - // Compile an optimized version of the functions. - i::FLAG_always_opt = true; - CompileRun(f1_source); - CompileRun(g1_source); - CompileRun(f2_source); - CompileRun(g2_source); - CompileRun("f1(new X());"); - CompileRun("g1(new X());"); - CompileRun("f2(new X(), 'z');"); - CompileRun("g2(new X(), 'z');"); - if (CcTest::i_isolate()->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + LocalContext env(isolate); + v8::HandleScope scope(env->GetIsolate()); + + // Functions to generate load/store/keyed load/keyed store IC calls. + const char* f1_source = "function f1(x) { return x.y; };"; + const char* g1_source = "function g1(x) { x.y = 1; };"; + const char* f2_source = "function f2(x, y) { return x[y]; };"; + const char* g2_source = "function g2(x, y) { x[y] = 1; };"; + + { + AllowNativesSyntaxNoInlining options; + // Compile functions and collect to type feedback to insert ic + // calls in the optimized code. + i::FLAG_prepare_always_opt = true; + CompileRun( + "var count = 0;" + "var result = 0;" + "var deopt = false;" + "function X() { };" + "X.prototype.__defineGetter__('y', function () {" + " g1(this);" + " return 13;" + "});" + "X.prototype.__defineSetter__('y', function () {" + " f2(this, 'z');" + "});" + "X.prototype.__defineGetter__('z', function () {" + " g2(this, 'z');" + "});" + "X.prototype.__defineSetter__('z', function () {" + " if (deopt) {" + " count++;" + " %DeoptimizeFunction(f1);" + " %DeoptimizeFunction(g1);" + " %DeoptimizeFunction(f2);" + " %DeoptimizeFunction(g2); };" + "});"); + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun( + "for (var i = 0; i < 5; i++) {" + " f1(new X());" + " g1(new X());" + " f2(new X(), 'z');" + " g2(new X(), 'z');" + "};"); + + // Compile an optimized version of the functions. + i::FLAG_always_opt = true; + CompileRun(f1_source); + CompileRun(g1_source); + CompileRun(f2_source); + CompileRun(g2_source); + CompileRun("f1(new X());"); + CompileRun("g1(new X());"); + CompileRun("f2(new X(), 'z');"); + CompileRun("g2(new X(), 'z');"); + if (i_isolate->use_crankshaft()) { + CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + } + + // Call functions and force deoptimization while processing the ics. + CompileRun( + "deopt = true;" + "var result = f1(new X());"); } + NonIncrementalGC(i_isolate); - // Call functions and force deoptimization while processing the ics. - CompileRun("deopt = true;" - "var result = f1(new X());"); + CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); + CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); } - NonIncrementalGC(); - - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + isolate->Exit(); + isolate->Dispose(); } |