Merge V8 at 3.9.24.13

Bug: 5688872
Change-Id: Id0aa8d23375030494d3189c31774059c0f5398fc
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 45da6dc..ffa8458 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// 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:
@@ -409,11 +409,8 @@
 
 
 static Handle<Code> ComputeCallDebugBreak(int argc) {
-  CALL_HEAP_FUNCTION(
-      v8::internal::Isolate::Current(),
-      v8::internal::Isolate::Current()->stub_cache()->ComputeCallDebugBreak(
-          argc, Code::CALL_IC),
-      Code);
+  return Isolate::Current()->stub_cache()->ComputeCallDebugBreak(argc,
+                                                                 Code::CALL_IC);
 }
 
 
@@ -425,8 +422,8 @@
   CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_);
 
   // Collect garbage to ensure weak handles are cleared.
-  HEAP->CollectAllGarbage(false);
-  HEAP->CollectAllGarbage(false);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask);
 
   // Iterate the head and check that there are no debugger related objects left.
   HeapIterator iterator;
@@ -859,7 +856,7 @@
 
   if (event == v8::Break) {
     break_point_hit_count++;
-    v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(data);
+    CHECK(data->IsFunction());
     ClearBreakPoint(debug_event_remove_break_point);
   }
 }
@@ -944,7 +941,7 @@
       HEAP->CollectGarbage(v8::internal::NEW_SPACE);
     } else {
       // Mark sweep compact.
-      HEAP->CollectAllGarbage(true);
+      HEAP->CollectAllGarbage(Heap::kNoGCFlags);
     }
   }
 }
@@ -1417,8 +1414,7 @@
 // Call the function three times with different garbage collections in between
 // and make sure that the break point survives.
 static void CallAndGC(v8::Local<v8::Object> recv,
-                      v8::Local<v8::Function> f,
-                      bool force_compaction) {
+                      v8::Local<v8::Function> f) {
   break_point_hit_count = 0;
 
   for (int i = 0; i < 3; i++) {
@@ -1432,14 +1428,15 @@
     CHECK_EQ(2 + i * 3, break_point_hit_count);
 
     // Mark sweep (and perhaps compact) and call function.
-    HEAP->CollectAllGarbage(force_compaction);
+    HEAP->CollectAllGarbage(Heap::kNoGCFlags);
     f->Call(recv, 0, NULL);
     CHECK_EQ(3 + i * 3, break_point_hit_count);
   }
 }
 
 
-static void TestBreakPointSurviveGC(bool force_compaction) {
+// Test that a break point can be set at a return store location.
+TEST(BreakPointSurviveGC) {
   break_point_hit_count = 0;
   v8::HandleScope scope;
   DebugLocalContext env;
@@ -1450,50 +1447,45 @@
 
   // Test IC store break point with garbage collection.
   {
-    v8::Local<v8::Function> bar =
-        CompileFunction(&env, "function foo(){}", "foo");
+    CompileFunction(&env, "function foo(){}", "foo");
     foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
     SetBreakPoint(foo, 0);
   }
-  CallAndGC(env->Global(), foo, force_compaction);
+  CallAndGC(env->Global(), foo);
 
   // Test IC load break point with garbage collection.
   {
-    v8::Local<v8::Function> bar =
-        CompileFunction(&env, "function foo(){}", "foo");
+    CompileFunction(&env, "function foo(){}", "foo");
     foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
     SetBreakPoint(foo, 0);
   }
-  CallAndGC(env->Global(), foo, force_compaction);
+  CallAndGC(env->Global(), foo);
 
   // Test IC call break point with garbage collection.
   {
-    v8::Local<v8::Function> bar =
-        CompileFunction(&env, "function foo(){}", "foo");
+    CompileFunction(&env, "function foo(){}", "foo");
     foo = CompileFunction(&env,
                           "function bar(){};function foo(){bar();}",
                           "foo");
     SetBreakPoint(foo, 0);
   }
-  CallAndGC(env->Global(), foo, force_compaction);
+  CallAndGC(env->Global(), foo);
 
   // Test return break point with garbage collection.
   {
-    v8::Local<v8::Function> bar =
-        CompileFunction(&env, "function foo(){}", "foo");
+    CompileFunction(&env, "function foo(){}", "foo");
     foo = CompileFunction(&env, "function foo(){}", "foo");
     SetBreakPoint(foo, 0);
   }
-  CallAndGC(env->Global(), foo, force_compaction);
+  CallAndGC(env->Global(), foo);
 
   // Test non IC break point with garbage collection.
   {
-    v8::Local<v8::Function> bar =
-        CompileFunction(&env, "function foo(){}", "foo");
+    CompileFunction(&env, "function foo(){}", "foo");
     foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo");
     SetBreakPoint(foo, 0);
   }
-  CallAndGC(env->Global(), foo, force_compaction);
+  CallAndGC(env->Global(), foo);
 
 
   v8::Debug::SetDebugEventListener(NULL);
@@ -1501,13 +1493,6 @@
 }
 
 
-// Test that a break point can be set at a return store location.
-TEST(BreakPointSurviveGC) {
-  TestBreakPointSurviveGC(false);
-  TestBreakPointSurviveGC(true);
-}
-
-
 // Test that break points can be set using the global Debug object.
 TEST(BreakPointThroughJavaScript) {
   break_point_hit_count = 0;
@@ -2259,7 +2244,7 @@
   }
   f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
 
-  HEAP->CollectAllGarbage(false);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
   SetScriptBreakPointByNameFromJS("test.html", 3, -1);
 
@@ -2753,14 +2738,14 @@
   v8::Handle<v8::Value> args[kArgc] = { a };
   foo->Call(env->Global(), kArgc, args);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
   foo->Call(env->Global(), kArgc, args);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(33, break_point_hit_count);
+  CHECK_EQ(34, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2800,14 +2785,14 @@
   v8::Handle<v8::Value> args[kArgc] = { a };
   foo->Call(env->Global(), kArgc, args);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
   foo->Call(env->Global(), kArgc, args);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(32, break_point_hit_count);
+  CHECK_EQ(33, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2844,14 +2829,14 @@
   // Call function without any break points to ensure inlining is in place.
   foo->Call(env->Global(), 0, NULL);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 4);
   step_action = StepNext;
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(53, break_point_hit_count);
+  CHECK_EQ(54, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2879,7 +2864,7 @@
   // Call function without any break points to ensure inlining is in place.
   foo->Call(env->Global(), 0, NULL);
 
-  // Setup break point and step through the function.
+  // Set up break point and step through the function.
   SetBreakPoint(foo, 3);
   step_action = StepNext;
   break_point_hit_count = 0;
@@ -2895,7 +2880,7 @@
 
 // Test of the stepping mechanism for named load in a loop.
 TEST(DebugStepNamedStoreLoop) {
-  DoDebugStepNamedStoreLoop(22);
+  DoDebugStepNamedStoreLoop(23);
 }
 
 
@@ -3267,7 +3252,7 @@
   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   result = foo->Call(env->Global(), argc, argv_10);
   CHECK_EQ(5, result->Int32Value());
-  CHECK_EQ(50, break_point_hit_count);
+  CHECK_EQ(51, break_point_hit_count);
 
   // Looping 100 times.
   step_action = StepIn;
@@ -3275,7 +3260,7 @@
   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   result = foo->Call(env->Global(), argc, argv_100);
   CHECK_EQ(50, result->Int32Value());
-  CHECK_EQ(455, break_point_hit_count);
+  CHECK_EQ(456, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -3319,7 +3304,7 @@
   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
   result = foo->Call(env->Global(), argc, argv_10);
   CHECK_EQ(9, result->Int32Value());
-  CHECK_EQ(53, break_point_hit_count);
+  CHECK_EQ(54, break_point_hit_count);
 
   // Looping 100 times.
   step_action = StepIn;
@@ -3327,7 +3312,7 @@
   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
   result = foo->Call(env->Global(), argc, argv_100);
   CHECK_EQ(99, result->Int32Value());
-  CHECK_EQ(503, break_point_hit_count);
+  CHECK_EQ(504, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -3761,8 +3746,7 @@
   v8::internal::Isolate::Current()->TraceException(false);
 
   // Create functions for testing break on exception.
-  v8::Local<v8::Function> throws =
-      CompileFunction(&env, "function throws(){throw 1;}", "throws");
+  CompileFunction(&env, "function throws(){throw 1;}", "throws");
   v8::Local<v8::Function> caught =
       CompileFunction(&env,
                       "function caught(){try {throws();} catch(e) {};}",
@@ -4238,9 +4222,9 @@
 
   // Get mirrors for the three objects with interceptor.
   CompileRun(
-      "named_mirror = debug.MakeMirror(intercepted_named);"
-      "indexed_mirror = debug.MakeMirror(intercepted_indexed);"
-      "both_mirror = debug.MakeMirror(intercepted_both)");
+      "var named_mirror = debug.MakeMirror(intercepted_named);"
+      "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
+      "var both_mirror = debug.MakeMirror(intercepted_both)");
   CHECK(CompileRun(
        "named_mirror instanceof debug.ObjectMirror")->BooleanValue());
   CHECK(CompileRun(
@@ -4281,7 +4265,7 @@
   CHECK_EQ(5, CompileRun(source)->Int32Value());
 
   // Get the interceptor properties for the object with only named interceptor.
-  CompileRun("named_values = named_mirror.properties()");
+  CompileRun("var named_values = named_mirror.properties()");
 
   // Check that the properties are interceptor properties.
   for (int i = 0; i < 3; i++) {
@@ -4300,7 +4284,7 @@
 
   // Get the interceptor properties for the object with only indexed
   // interceptor.
-  CompileRun("indexed_values = indexed_mirror.properties()");
+  CompileRun("var indexed_values = indexed_mirror.properties()");
 
   // Check that the properties are interceptor properties.
   for (int i = 0; i < 2; i++) {
@@ -4312,7 +4296,7 @@
 
   // Get the interceptor properties for the object with both types of
   // interceptors.
-  CompileRun("both_values = both_mirror.properties()");
+  CompileRun("var both_values = both_mirror.properties()");
 
   // Check that the properties are interceptor properties.
   for (int i = 0; i < 5; i++) {
@@ -4368,10 +4352,10 @@
 
   // Get mirrors for the four objects.
   CompileRun(
-      "o0_mirror = debug.MakeMirror(o0);"
-      "o1_mirror = debug.MakeMirror(o1);"
-      "o2_mirror = debug.MakeMirror(o2);"
-      "o3_mirror = debug.MakeMirror(o3)");
+      "var o0_mirror = debug.MakeMirror(o0);"
+      "var o1_mirror = debug.MakeMirror(o1);"
+      "var o2_mirror = debug.MakeMirror(o2);"
+      "var o3_mirror = debug.MakeMirror(o3)");
   CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
   CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
   CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
@@ -4457,11 +4441,11 @@
   CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
 
   // Get mirror for the object with property getter.
-  CompileRun("instance_mirror = debug.MakeMirror(instance);");
+  CompileRun("var instance_mirror = debug.MakeMirror(instance);");
   CHECK(CompileRun(
       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
 
-  CompileRun("named_names = instance_mirror.propertyNames();");
+  CompileRun("var named_names = instance_mirror.propertyNames();");
   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
   CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
   CHECK(CompileRun(
@@ -4493,7 +4477,7 @@
   env->Global()->Set(v8::String::New("instance"), named->NewInstance());
 
   // Get mirror for the object with property getter.
-  CompileRun("instance_mirror = debug.MakeMirror(instance);");
+  CompileRun("var instance_mirror = debug.MakeMirror(instance);");
   CHECK(CompileRun(
       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
   CompileRun("named_names = instance_mirror.propertyNames();");
@@ -5557,10 +5541,8 @@
     v8::HandleScope scope;
 
     // Get the test functions again.
-    v8::Local<v8::Function> foo =
-      v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
-    v8::Local<v8::Function> bar =
-      v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
+    v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast(
+        env->Global()->Get(v8::String::New("foo"))));
 
     foo->Call(env->Global(), 0, NULL);
     CHECK_EQ(0, break_point_hit_count);
@@ -5719,7 +5701,7 @@
   v8::HandleScope scope;
   DebugLocalContext env;
 
-  // Setup message and host dispatch handlers.
+  // Set up message and host dispatch handlers.
   v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
   v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
 
@@ -5807,7 +5789,7 @@
   v8::HandleScope scope;
   DebugLocalContext env;
 
-  // Setup debug message dispatch handler.
+  // Set up debug message dispatch handler.
   v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
 
   CompileRun("var y = 1 + 2;\n");
@@ -5861,7 +5843,7 @@
   bool ok;
 
   // Initialize the socket library.
-  i::Socket::Setup();
+  i::Socket::SetUp();
 
   // Test starting and stopping the agent without any client connection.
   debugger->StartAgent("test", kPort1);
@@ -5959,7 +5941,7 @@
   OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
 
   // Initialize the socket library.
-  i::Socket::Setup();
+  i::Socket::SetUp();
 
   // Create a socket server to receive a debugger agent message.
   DebuggerAgentProtocolServerThread* server =
@@ -6037,7 +6019,9 @@
 
   EmptyExternalStringResource source_ext_str;
   v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str);
-  v8::Handle<v8::Script> evil_script = v8::Script::Compile(source);
+  v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
+  // "use" evil_script to make the compiler happy.
+  (void) evil_script;
   Handle<i::ExternalTwoByteString> i_source(
       i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
   // This situation can happen if source was an external string disposed
@@ -6472,7 +6456,7 @@
 
   // Do garbage collection to ensure that only the script in this test will be
   // collected afterwards.
-  HEAP->CollectAllGarbage(false);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
   script_collected_count = 0;
   v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
@@ -6484,7 +6468,7 @@
 
   // Do garbage collection to collect the script above which is no longer
   // referenced.
-  HEAP->CollectAllGarbage(false);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
   CHECK_EQ(2, script_collected_count);
 
@@ -6520,7 +6504,7 @@
 
     // Do garbage collection to ensure that only the script in this test will be
     // collected afterwards.
-    HEAP->CollectAllGarbage(false);
+    HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
     v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
     {
@@ -6531,7 +6515,7 @@
 
   // Do garbage collection to collect the script above which is no longer
   // referenced.
-  HEAP->CollectAllGarbage(false);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
   CHECK_EQ(2, script_collected_message_count);
 
@@ -6685,7 +6669,7 @@
     break_point_hit_count++;
 
     v8::HandleScope scope;
-    v8::Handle<v8::String> json = message.GetJSON();
+    message.GetJSON();
 
     SendContinueCommand();
   } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
@@ -6696,7 +6680,7 @@
     isolate->stack_guard()->DebugBreak();
 
     // Force serialization to trigger some internal JS execution.
-    v8::Handle<v8::String> json = message.GetJSON();
+    message.GetJSON();
 
     // Restore previous state.
     if (is_debug_break) {
@@ -6879,7 +6863,7 @@
   foo->Call(env->Global(), 0, NULL);
 
   // When keeping the debug break several break will happen.
-  CHECK_EQ(3, break_point_hit_count);
+  CHECK_GT(break_point_hit_count, 1);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -7224,10 +7208,10 @@
   // Receive 100 breaks for each test and then terminate JavaScript execution.
   static const int kBreaksPerTest = 100;
 
-  for (int i = 0; i < 1 && loop_bodies[i] != NULL; i++) {
+  for (int i = 0; loop_bodies[i] != NULL; i++) {
     // Perform a lazy deoptimization after various numbers of breaks
     // have been hit.
-    for (int j = 0; j < 10; j++) {
+    for (int j = 0; j < 11; j++) {
       break_point_hit_count_deoptimize = j;
       if (j == 10) {
         break_point_hit_count_deoptimize = kBreaksPerTest;
@@ -7302,4 +7286,65 @@
 }
 
 
+v8::Local<v8::Script> inline_script;
+
+static void DebugBreakInlineListener(v8::DebugEvent event,
+                                     v8::Handle<v8::Object> exec_state,
+                                     v8::Handle<v8::Object> event_data,
+                                     v8::Handle<v8::Value> data) {
+  if (event != v8::Break) return;
+
+  int expected_frame_count = 4;
+  int expected_line_number[] = {1, 4, 7, 12};
+
+  i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script);
+  i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast(
+      i::JSFunction::cast(*compiled_script)->shared()->script()));
+
+  int break_id = v8::internal::Isolate::Current()->debug()->break_id();
+  char script[128];
+  i::Vector<char> script_vector(script, sizeof(script));
+  OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
+  v8::Local<v8::Value> result = CompileRun(script);
+
+  int frame_count = result->Int32Value();
+  CHECK_EQ(expected_frame_count, frame_count);
+
+  for (int i = 0; i < frame_count; i++) {
+    // The 5. element in the returned array of GetFrameDetails contains the
+    // source position of that frame.
+    OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
+    v8::Local<v8::Value> result = CompileRun(script);
+    CHECK_EQ(expected_line_number[i],
+             i::GetScriptLineNumber(source_script, result->Int32Value()));
+  }
+  v8::Debug::SetDebugEventListener(NULL);
+  v8::V8::TerminateExecution();
+}
+
+
+TEST(DebugBreakInline) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::HandleScope scope;
+  DebugLocalContext env;
+  const char* source =
+      "function debug(b) {             \n"
+      "  if (b) debugger;              \n"
+      "}                               \n"
+      "function f(b) {                 \n"
+      "  debug(b)                      \n"
+      "};                              \n"
+      "function g(b) {                 \n"
+      "  f(b);                         \n"
+      "};                              \n"
+      "g(false);                       \n"
+      "g(false);                       \n"
+      "%OptimizeFunctionOnNextCall(g); \n"
+      "g(true);";
+  v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+  inline_script = v8::Script::Compile(v8::String::New(source));
+  inline_script->Run();
+}
+
+
 #endif  // ENABLE_DEBUGGER_SUPPORT