41 using ::v8::internal::Deoptimizer;
 
   42 using ::v8::internal::EmbeddedVector;
 
   43 using ::v8::internal::Handle;
 
   44 using ::v8::internal::Isolate;
 
   45 using ::v8::internal::JSFunction;
 
   46 using ::v8::internal::OS;
 
   50 #define SMALL_STRING_BUFFER_SIZE 80 
   57       : always_opt_(i::FLAG_always_opt),
 
   58         allow_natives_syntax_(i::FLAG_allow_natives_syntax),
 
   59         use_inlining_(i::FLAG_use_inlining) {
 
   60     i::FLAG_always_opt = 
true;
 
   61     i::FLAG_allow_natives_syntax = 
true;
 
   62     i::FLAG_use_inlining = 
false;
 
   66     i::FLAG_allow_natives_syntax = allow_natives_syntax_;
 
   67     i::FLAG_always_opt = always_opt_;
 
   68     i::FLAG_use_inlining = use_inlining_;
 
   73   bool allow_natives_syntax_;
 
   83       : allow_natives_syntax_(i::FLAG_allow_natives_syntax),
 
   84         use_inlining_(i::FLAG_use_inlining) {
 
   85     i::FLAG_allow_natives_syntax = 
true;
 
   86     i::FLAG_use_inlining = 
false;
 
   90     i::FLAG_allow_natives_syntax = allow_natives_syntax_;
 
   91     i::FLAG_use_inlining = use_inlining_;
 
   95   bool allow_natives_syntax_;
 
  102 static void NonIncrementalGC() {
 
  108                                         const char* property_name) {
 
  111   return v8::Utils::OpenHandle(*fun);
 
  124         "function h() { %DeoptimizeFunction(f); }" 
  125         "function g() { count++; h(); }" 
  126         "function f() { g(); };" 
  132   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  133   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  141         "function g() { count++; %DeoptimizeFunction(f); f(false); }" 
  142         "function f(x) { if (x) { g(); } else { return } };" 
  148   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  149   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  153 TEST(DeoptimizeSimpleWithArguments) {
 
  162         "function h(x) { %DeoptimizeFunction(f); }" 
  163         "function g(x, y) { count++; h(x); }" 
  164         "function f(x, y, z) { g(1,x); y+z; };" 
  165         "f(1, \"2\", false);");
 
  170   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  171   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  180         "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" 
  181         "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" 
  182         "f(true, 1, \"2\");");
 
  187   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  188   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  203         "function h(x, y, z) { return x + y + z; }" 
  204         "function g(z) { count++; %DeoptimizeFunction(f); return z;}" 
  205         "function f(x,y,z) { return h(x, y, g(z)); };" 
  206         "result = f(1, 2, 3);");
 
  211     CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  212     CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  228         "function g() { count++; %DeoptimizeFunction(f); }" 
  229         "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" 
  236   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  253         "function g() { count++;" 
  254         "               %DeoptimizeFunction(f1);" 
  255         "               %DeoptimizeFunction(f2);" 
  256         "               %DeoptimizeFunction(f3);" 
  257         "               %DeoptimizeFunction(f4);}" 
  258         "function f4(x) { g(); };" 
  259         "function f3(x, y, z) { f4(); return x + y + z; };" 
  260         "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" 
  261         "function f1(x) { return f2(x + 1, x + 1) + x; };" 
  268   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  280         "function g() { count++;" 
  281         "               %DeoptimizeFunction(f); }" 
  282         "function f() {  g(); };" 
  283         "result = new f() instanceof f;");
 
  288   CHECK(env->
Global()->Get(v8_str(
"result"))->IsTrue());
 
  289   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  296         "function g() { count++;" 
  297         "               %DeoptimizeFunction(f); }" 
  298         "function f(x, y) { this.x = x; g(); this.y = y; };" 
  299         "result = new f(1, 2);" 
  300         "result = result.x + result.y;");
 
  306   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  310 TEST(DeoptimizeConstructorMultiple) {
 
  319         "function g() { count++;" 
  320         "               %DeoptimizeFunction(f1);" 
  321         "               %DeoptimizeFunction(f2);" 
  322         "               %DeoptimizeFunction(f3);" 
  323         "               %DeoptimizeFunction(f4);}" 
  324         "function f4(x) { this.result = x; g(); };" 
  325         "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" 
  326         "function f2(x, y) {" 
  327         "    this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" 
  328         "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" 
  329         "result = new f1(1).result;");
 
  335   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  339 TEST(DeoptimizeBinaryOperationADDString) {
 
  343   const char* f_source = 
"function f(x, y) { return x + y; };";
 
  349     i::FLAG_prepare_always_opt = 
true;
 
  350     CompileRun(
"var count = 0;" 
  354                "X.prototype.toString = function () {" 
  355                "  if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" 
  357     CompileRun(f_source);
 
  358     CompileRun(
"for (var i = 0; i < 5; i++) {" 
  363     i::FLAG_always_opt = 
true;
 
  364     CompileRun(f_source);
 
  365     CompileRun(
"f('a+', new X());");
 
  367           GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  370     CompileRun(
"deopt = true;" 
  371                "var result = f('a+', new X());");
 
  375   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  378   CHECK(result->IsString());
 
  381   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  385 static void CompileConstructorWithDeoptimizingValueOf() {
 
  386   CompileRun(
"var count = 0;" 
  390              "X.prototype.valueOf = function () {" 
  391              "  if (deopt) { count++; %DeoptimizeFunction(f); } return 8" 
  396 static void TestDeoptimizeBinaryOpHelper(
LocalContext* env,
 
  397                                          const char* binary_op) {
 
  398   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer;
 
  399   OS::SNPrintF(f_source_buffer,
 
  400                "function f(x, y) { return x %s y; };",
 
  402   char* f_source = f_source_buffer.start();
 
  407   i::FLAG_prepare_always_opt = 
true;
 
  408   CompileConstructorWithDeoptimizingValueOf();
 
  409   CompileRun(f_source);
 
  410   CompileRun(
"for (var i = 0; i < 5; i++) {" 
  415   i::FLAG_always_opt = 
true;
 
  416   CompileRun(f_source);
 
  417   CompileRun(
"f(7, new X());");
 
  419         GetJSFunction((*env)->Global(), 
"f")->IsOptimized());
 
  422   CompileRun(
"deopt = true;" 
  423              "var result = f(7, new X());");
 
  425   CHECK(!GetJSFunction((*env)->Global(), 
"f")->IsOptimized());
 
  429 TEST(DeoptimizeBinaryOperationADD) {
 
  433   TestDeoptimizeBinaryOpHelper(&env, 
"+");
 
  437   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  441 TEST(DeoptimizeBinaryOperationSUB) {
 
  445   TestDeoptimizeBinaryOpHelper(&env, 
"-");
 
  449   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  453 TEST(DeoptimizeBinaryOperationMUL) {
 
  457   TestDeoptimizeBinaryOpHelper(&env, 
"*");
 
  461   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  465 TEST(DeoptimizeBinaryOperationDIV) {
 
  469   TestDeoptimizeBinaryOpHelper(&env, 
"/");
 
  473   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  477 TEST(DeoptimizeBinaryOperationMOD) {
 
  481   TestDeoptimizeBinaryOpHelper(&env, 
"%");
 
  485   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  493   const char* f_source = 
"function f(x, y) { return x < y; };";
 
  499     i::FLAG_prepare_always_opt = 
true;
 
  500     CompileRun(
"var count = 0;" 
  504                "X.prototype.toString = function () {" 
  505                "  if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" 
  507     CompileRun(f_source);
 
  508     CompileRun(
"for (var i = 0; i < 5; i++) {" 
  513     i::FLAG_always_opt = 
true;
 
  514     CompileRun(f_source);
 
  515     CompileRun(
"f('a', new X());");
 
  517           GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  520     CompileRun(
"deopt = true;" 
  521                "var result = f('a', new X());");
 
  525   CHECK(!GetJSFunction(env->
Global(), 
"f")->IsOptimized());
 
  527   CHECK_EQ(
true, env->
Global()->Get(v8_str(
"result"))->BooleanValue());
 
  528   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  532 TEST(DeoptimizeLoadICStoreIC) {
 
  537   const char* f1_source = 
"function f1(x) { return x.y; };";
 
  538   const char* g1_source = 
"function g1(x) { x.y = 1; };";
 
  539   const char* f2_source = 
"function f2(x, y) { return x[y]; };";
 
  540   const char* g2_source = 
"function g2(x, y) { x[y] = 1; };";
 
  546     i::FLAG_prepare_always_opt = 
true;
 
  547     CompileRun(
"var count = 0;" 
  551                "X.prototype.__defineGetter__('y', function () {" 
  552                "  if (deopt) { count++; %DeoptimizeFunction(f1); };" 
  555                "X.prototype.__defineSetter__('y', function () {" 
  556                "  if (deopt) { count++; %DeoptimizeFunction(g1); };" 
  558                "X.prototype.__defineGetter__('z', function () {" 
  559                "  if (deopt) { count++; %DeoptimizeFunction(f2); };" 
  562                "X.prototype.__defineSetter__('z', function () {" 
  563                "  if (deopt) { count++; %DeoptimizeFunction(g2); };" 
  565     CompileRun(f1_source);
 
  566     CompileRun(g1_source);
 
  567     CompileRun(f2_source);
 
  568     CompileRun(g2_source);
 
  569     CompileRun(
"for (var i = 0; i < 5; i++) {" 
  577     i::FLAG_always_opt = 
true;
 
  578     CompileRun(f1_source);
 
  579     CompileRun(g1_source);
 
  580     CompileRun(f2_source);
 
  581     CompileRun(g2_source);
 
  582     CompileRun(
"f1(new X());");
 
  583     CompileRun(
"g1(new X());");
 
  584     CompileRun(
"f2(new X(), 'z');");
 
  585     CompileRun(
"g2(new X(), 'z');");
 
  587       CHECK(GetJSFunction(env->
Global(), 
"f1")->IsOptimized());
 
  588       CHECK(GetJSFunction(env->
Global(), 
"g1")->IsOptimized());
 
  589       CHECK(GetJSFunction(env->
Global(), 
"f2")->IsOptimized());
 
  590       CHECK(GetJSFunction(env->
Global(), 
"g2")->IsOptimized());
 
  594     CompileRun(
"deopt = true;" 
  595                "var result = f1(new X());" 
  598                "g2(new X(), 'z');");
 
  602   CHECK(!GetJSFunction(env->
Global(), 
"f1")->IsOptimized());
 
  603   CHECK(!GetJSFunction(env->
Global(), 
"g1")->IsOptimized());
 
  604   CHECK(!GetJSFunction(env->
Global(), 
"f2")->IsOptimized());
 
  605   CHECK(!GetJSFunction(env->
Global(), 
"g2")->IsOptimized());
 
  608   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
  612 TEST(DeoptimizeLoadICStoreICNested) {
 
  617   const char* f1_source = 
"function f1(x) { return x.y; };";
 
  618   const char* g1_source = 
"function g1(x) { x.y = 1; };";
 
  619   const char* f2_source = 
"function f2(x, y) { return x[y]; };";
 
  620   const char* g2_source = 
"function g2(x, y) { x[y] = 1; };";
 
  626     i::FLAG_prepare_always_opt = 
true;
 
  627     CompileRun(
"var count = 0;" 
  631                "X.prototype.__defineGetter__('y', function () {" 
  635                "X.prototype.__defineSetter__('y', function () {" 
  638                "X.prototype.__defineGetter__('z', function () {" 
  641                "X.prototype.__defineSetter__('z', function () {" 
  644                "    %DeoptimizeFunction(f1);" 
  645                "    %DeoptimizeFunction(g1);" 
  646                "    %DeoptimizeFunction(f2);" 
  647                "    %DeoptimizeFunction(g2); };" 
  649     CompileRun(f1_source);
 
  650     CompileRun(g1_source);
 
  651     CompileRun(f2_source);
 
  652     CompileRun(g2_source);
 
  653     CompileRun(
"for (var i = 0; i < 5; i++) {" 
  661     i::FLAG_always_opt = 
true;
 
  662     CompileRun(f1_source);
 
  663     CompileRun(g1_source);
 
  664     CompileRun(f2_source);
 
  665     CompileRun(g2_source);
 
  666     CompileRun(
"f1(new X());");
 
  667     CompileRun(
"g1(new X());");
 
  668     CompileRun(
"f2(new X(), 'z');");
 
  669     CompileRun(
"g2(new X(), 'z');");
 
  671       CHECK(GetJSFunction(env->
Global(), 
"f1")->IsOptimized());
 
  672       CHECK(GetJSFunction(env->
Global(), 
"g1")->IsOptimized());
 
  673       CHECK(GetJSFunction(env->
Global(), 
"f2")->IsOptimized());
 
  674       CHECK(GetJSFunction(env->
Global(), 
"g2")->IsOptimized());
 
  678     CompileRun(
"deopt = true;" 
  679                "var result = f1(new X());");
 
  683   CHECK(!GetJSFunction(env->
Global(), 
"f1")->IsOptimized());
 
  684   CHECK(!GetJSFunction(env->
Global(), 
"g1")->IsOptimized());
 
  685   CHECK(!GetJSFunction(env->
Global(), 
"f2")->IsOptimized());
 
  686   CHECK(!GetJSFunction(env->
Global(), 
"g2")->IsOptimized());
 
  689   CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
 
#define CHECK_EQ(expected, value)
static bool UseCrankshaft()
V8EXPORT Local< Value > Get(Handle< Value > key)
static V8EXPORT Local< String > New(const char *data, int length=-1)
AlwaysOptimizeAllowNativesSyntaxNoInlining()
static const int kAbortIncrementalMarkingMask
static Local< T > Cast(Local< S > that)
~AllowNativesSyntaxNoInlining()
~AlwaysOptimizeAllowNativesSyntaxNoInlining()
AllowNativesSyntaxNoInlining()