diff options
Diffstat (limited to 'src/3rdparty/v8/test/cctest/test-deoptimization.cc')
-rw-r--r-- | src/3rdparty/v8/test/cctest/test-deoptimization.cc | 690 |
1 files changed, 0 insertions, 690 deletions
diff --git a/src/3rdparty/v8/test/cctest/test-deoptimization.cc b/src/3rdparty/v8/test/cctest/test-deoptimization.cc deleted file mode 100644 index c52c578..0000000 --- a/src/3rdparty/v8/test/cctest/test-deoptimization.cc +++ /dev/null @@ -1,690 +0,0 @@ -// Copyright 2012 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. - -#include <stdlib.h> - -#include "v8.h" - -#include "api.h" -#include "cctest.h" -#include "compilation-cache.h" -#include "debug.h" -#include "deoptimizer.h" -#include "isolate.h" -#include "platform.h" -#include "stub-cache.h" - -using ::v8::internal::Deoptimizer; -using ::v8::internal::EmbeddedVector; -using ::v8::internal::Handle; -using ::v8::internal::Isolate; -using ::v8::internal::JSFunction; -using ::v8::internal::OS; -using ::v8::internal::Object; - -// Size of temp buffer for formatting small strings. -#define SMALL_STRING_BUFFER_SIZE 80 - -// Utility class to set --allow-natives-syntax --always-opt and --nouse-inlining -// when constructed and return to their default state when destroyed. -class AlwaysOptimizeAllowNativesSyntaxNoInlining { - public: - AlwaysOptimizeAllowNativesSyntaxNoInlining() - : always_opt_(i::FLAG_always_opt), - allow_natives_syntax_(i::FLAG_allow_natives_syntax), - use_inlining_(i::FLAG_use_inlining) { - i::FLAG_always_opt = true; - i::FLAG_allow_natives_syntax = true; - i::FLAG_use_inlining = false; - } - - ~AlwaysOptimizeAllowNativesSyntaxNoInlining() { - i::FLAG_allow_natives_syntax = allow_natives_syntax_; - i::FLAG_always_opt = always_opt_; - i::FLAG_use_inlining = use_inlining_; - } - - private: - bool always_opt_; - bool allow_natives_syntax_; - bool use_inlining_; -}; - - -// Utility class to set --allow-natives-syntax and --nouse-inlining when -// constructed and return to their default state when destroyed. -class AllowNativesSyntaxNoInlining { - public: - AllowNativesSyntaxNoInlining() - : allow_natives_syntax_(i::FLAG_allow_natives_syntax), - use_inlining_(i::FLAG_use_inlining) { - i::FLAG_allow_natives_syntax = true; - i::FLAG_use_inlining = false; - } - - ~AllowNativesSyntaxNoInlining() { - i::FLAG_allow_natives_syntax = allow_natives_syntax_; - i::FLAG_use_inlining = use_inlining_; - } - - private: - bool allow_natives_syntax_; - bool use_inlining_; -}; - - -// Abort any ongoing incremental marking to make sure that all weak global -// handle callbacks are processed. -static void NonIncrementalGC() { - HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); -} - - -static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, - const char* property_name) { - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); - return v8::Utils::OpenHandle(*fun); -} - - -TEST(DeoptimizeSimple) { - v8::HandleScope scope; - LocalContext env; - - // Test lazy deoptimization of a simple function. - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "function h() { %DeoptimizeFunction(f); }" - "function g() { count++; h(); }" - "function f() { g(); };" - "f();"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); - - // Test lazy deoptimization of a simple function. Call the function after the - // deoptimization while it is still activated further down the stack. - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "function g() { count++; %DeoptimizeFunction(f); f(false); }" - "function f(x) { if (x) { g(); } else { return } };" - "f(true);"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeSimpleWithArguments) { - v8::HandleScope scope; - LocalContext env; - - // Test lazy deoptimization of a simple function with some arguments. - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "function h(x) { %DeoptimizeFunction(f); }" - "function g(x, y) { count++; h(x); }" - "function f(x, y, z) { g(1,x); y+z; };" - "f(1, \"2\", false);"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); - - // Test lazy deoptimization of a simple function with some arguments. Call the - // function after the deoptimization while it is still activated further down - // the stack. - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" - "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" - "f(true, 1, \"2\");"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeSimpleNested) { - v8::HandleScope scope; - LocalContext env; - - // Test lazy deoptimization of a simple function. Have a nested function call - // do the deoptimization. - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "var result = 0;" - "function h(x, y, z) { return x + y + z; }" - "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(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); - } -} - - -TEST(DeoptimizeRecursive) { - v8::HandleScope scope; - LocalContext env; - - { - // Test lazy deoptimization of a simple function called recursively. Call - // the function recursively a number of times before deoptimizing it. - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "var calls = 0;" - "function g() { count++; %DeoptimizeFunction(f); }" - "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" - "f(10);"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); - - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); - CHECK(!fun.IsEmpty()); -} - - -TEST(DeoptimizeMultiple) { - v8::HandleScope scope; - LocalContext env; - - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "var result = 0;" - "function g() { count++;" - " %DeoptimizeFunction(f1);" - " %DeoptimizeFunction(f2);" - " %DeoptimizeFunction(f3);" - " %DeoptimizeFunction(f4);}" - "function f4(x) { g(); };" - "function f3(x, y, z) { f4(); return x + y + z; };" - "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" - "function f1(x) { return f2(x + 1, x + 1) + x; };" - "result = f1(1);"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeConstructor) { - v8::HandleScope scope; - LocalContext env; - - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "function g() { count++;" - " %DeoptimizeFunction(f); }" - "function f() { g(); };" - "result = new f() instanceof f;"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); - - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "var result = 0;" - "function g() { count++;" - " %DeoptimizeFunction(f); }" - "function f(x, y) { this.x = x; g(); this.y = y; };" - "result = new f(1, 2);" - "result = result.x + result.y;"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeConstructorMultiple) { - v8::HandleScope scope; - LocalContext env; - - { - AlwaysOptimizeAllowNativesSyntaxNoInlining options; - CompileRun( - "var count = 0;" - "var result = 0;" - "function g() { count++;" - " %DeoptimizeFunction(f1);" - " %DeoptimizeFunction(f2);" - " %DeoptimizeFunction(f3);" - " %DeoptimizeFunction(f4);}" - "function f4(x) { this.result = x; g(); };" - "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" - "function f2(x, y) {" - " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" - "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" - "result = new f1(1).result;"); - } - NonIncrementalGC(); - - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeBinaryOperationADDString) { - v8::HandleScope scope; - LocalContext env; - - const char* f_source = "function f(x, y) { return x + y; };"; - - { - AllowNativesSyntaxNoInlining options; - // 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::V8::UseCrankshaft() || - 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(); - - 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::AsciiValue ascii(result); - CHECK_EQ("a+an X", *ascii); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -static void CompileConstructorWithDeoptimizingValueOf() { - CompileRun("var count = 0;" - "var result = 0;" - "var deopt = false;" - "function X() { };" - "X.prototype.valueOf = function () {" - " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" - "};"); -} - - -static void TestDeoptimizeBinaryOpHelper(LocalContext* env, - const char* binary_op) { - EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer; - OS::SNPrintF(f_source_buffer, - "function f(x, y) { return x %s y; };", - binary_op); - char* f_source = f_source_buffer.start(); - - AllowNativesSyntaxNoInlining options; - // Compile function f and collect to type feedback to insert binary op stub - // call in the optimized code. - i::FLAG_prepare_always_opt = true; - CompileConstructorWithDeoptimizingValueOf(); - CompileRun(f_source); - CompileRun("for (var i = 0; i < 5; i++) {" - " f(8, new X());" - "};"); - - // Compile an optimized version of f. - i::FLAG_always_opt = true; - CompileRun(f_source); - CompileRun("f(7, new X());"); - CHECK(!i::V8::UseCrankshaft() || - 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(); - CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); -} - - -TEST(DeoptimizeBinaryOperationADD) { - v8::HandleScope scope; - LocalContext 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(Isolate::Current())); -} - - -TEST(DeoptimizeBinaryOperationSUB) { - v8::HandleScope scope; - LocalContext 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(Isolate::Current())); -} - - -TEST(DeoptimizeBinaryOperationMUL) { - v8::HandleScope scope; - LocalContext 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(Isolate::Current())); -} - - -TEST(DeoptimizeBinaryOperationDIV) { - v8::HandleScope scope; - LocalContext 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(Isolate::Current())); -} - - -TEST(DeoptimizeBinaryOperationMOD) { - v8::HandleScope scope; - LocalContext 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(Isolate::Current())); -} - - -TEST(DeoptimizeCompare) { - v8::HandleScope scope; - LocalContext env; - - 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::V8::UseCrankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); - - // Call f and force deoptimization while processing the comparison. - CompileRun("deopt = true;" - "var result = f('a', new X());"); - } - NonIncrementalGC(); - - 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(Isolate::Current())); -} - - -TEST(DeoptimizeLoadICStoreIC) { - v8::HandleScope scope; - LocalContext env; - - // 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::V8::UseCrankshaft()) { - 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');"); - } - 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()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} - - -TEST(DeoptimizeLoadICStoreICNested) { - v8::HandleScope scope; - LocalContext env; - - // 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::V8::UseCrankshaft()) { - 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(); - - 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()); - CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); -} |