// 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  // 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  // 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  // 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  {
    // 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  {
    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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  {
    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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  {
    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) {
  LocalContext env;
  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 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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  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) {
  LocalContext env;
  v8::HandleScope scope(env->GetIsolate());

  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) {
  LocalContext env;
  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::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) {
  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; };";

  {
    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) {
  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; };";

  {
    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()));
}
