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