OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 | 408 |
409 | 409 |
410 // Check that the debugger has been fully unloaded. | 410 // Check that the debugger has been fully unloaded. |
411 void CheckDebuggerUnloaded(bool check_functions) { | 411 void CheckDebuggerUnloaded(bool check_functions) { |
412 // Check that the debugger context is cleared and that there is no debug | 412 // Check that the debugger context is cleared and that there is no debug |
413 // information stored for the debugger. | 413 // information stored for the debugger. |
414 CHECK(Debug::debug_context().is_null()); | 414 CHECK(Debug::debug_context().is_null()); |
415 CHECK_EQ(NULL, Debug::debug_info_list_); | 415 CHECK_EQ(NULL, Debug::debug_info_list_); |
416 | 416 |
417 // Collect garbage to ensure weak handles are cleared. | 417 // Collect garbage to ensure weak handles are cleared. |
418 Heap::CollectAllGarbage(false); | 418 Heap::CollectAllGarbage(i::Heap::kNoGCFlags); |
419 Heap::CollectAllGarbage(false); | 419 Heap::CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
420 | 420 |
421 // Iterate the head and check that there are no debugger related objects left. | 421 // Iterate the head and check that there are no debugger related objects left. |
422 HeapIterator iterator; | 422 HeapIterator iterator; |
423 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 423 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) { |
424 CHECK(!obj->IsDebugInfo()); | 424 CHECK(!obj->IsDebugInfo()); |
425 CHECK(!obj->IsBreakPointInfo()); | 425 CHECK(!obj->IsBreakPointInfo()); |
426 | 426 |
427 // If deep check of functions is requested check that no debug break code | 427 // If deep check of functions is requested check that no debug break code |
428 // is left in all functions. | 428 // is left in all functions. |
429 if (check_functions) { | 429 if (check_functions) { |
430 if (obj->IsJSFunction()) { | 430 if (obj->IsJSFunction()) { |
431 JSFunction* fun = JSFunction::cast(obj); | 431 JSFunction* fun = JSFunction::cast(obj); |
432 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { | 432 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { |
433 RelocInfo::Mode rmode = it.rinfo()->rmode(); | 433 RelocInfo::Mode rmode = it.rinfo()->rmode(); |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 // Perform a garbage collection when break point is hit and continue. Based | 902 // Perform a garbage collection when break point is hit and continue. Based |
903 // on the number of break points hit either scavenge or mark compact | 903 // on the number of break points hit either scavenge or mark compact |
904 // collector is used. | 904 // collector is used. |
905 if (event == v8::Break) { | 905 if (event == v8::Break) { |
906 break_point_hit_count++; | 906 break_point_hit_count++; |
907 if (break_point_hit_count % 2 == 0) { | 907 if (break_point_hit_count % 2 == 0) { |
908 // Scavenge. | 908 // Scavenge. |
909 Heap::CollectGarbage(v8::internal::NEW_SPACE); | 909 Heap::CollectGarbage(v8::internal::NEW_SPACE); |
910 } else { | 910 } else { |
911 // Mark sweep compact. | 911 // Mark sweep compact. |
912 Heap::CollectAllGarbage(true); | 912 Heap::CollectAllGarbage(Heap::kForceCompactionMask); |
913 } | 913 } |
914 } | 914 } |
915 } | 915 } |
916 | 916 |
917 | 917 |
918 // Debug event handler which re-issues a debug break and calls the garbage | 918 // Debug event handler which re-issues a debug break and calls the garbage |
919 // collector to have the heap verified. | 919 // collector to have the heap verified. |
920 static void DebugEventBreak(v8::DebugEvent event, | 920 static void DebugEventBreak(v8::DebugEvent event, |
921 v8::Handle<v8::Object> exec_state, | 921 v8::Handle<v8::Object> exec_state, |
922 v8::Handle<v8::Object> event_data, | 922 v8::Handle<v8::Object> event_data, |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 | 1351 |
1352 v8::Debug::SetDebugEventListener(NULL); | 1352 v8::Debug::SetDebugEventListener(NULL); |
1353 CheckDebuggerUnloaded(); | 1353 CheckDebuggerUnloaded(); |
1354 } | 1354 } |
1355 | 1355 |
1356 | 1356 |
1357 // Call the function three times with different garbage collections in between | 1357 // Call the function three times with different garbage collections in between |
1358 // and make sure that the break point survives. | 1358 // and make sure that the break point survives. |
1359 static void CallAndGC(v8::Local<v8::Object> recv, | 1359 static void CallAndGC(v8::Local<v8::Object> recv, |
1360 v8::Local<v8::Function> f, | 1360 v8::Local<v8::Function> f, |
1361 bool force_compaction) { | 1361 int gc_flags) { |
1362 break_point_hit_count = 0; | 1362 break_point_hit_count = 0; |
1363 | 1363 |
1364 for (int i = 0; i < 3; i++) { | 1364 for (int i = 0; i < 3; i++) { |
1365 // Call function. | 1365 // Call function. |
1366 f->Call(recv, 0, NULL); | 1366 f->Call(recv, 0, NULL); |
1367 CHECK_EQ(1 + i * 3, break_point_hit_count); | 1367 CHECK_EQ(1 + i * 3, break_point_hit_count); |
1368 | 1368 |
1369 // Scavenge and call function. | 1369 // Scavenge and call function. |
1370 Heap::CollectGarbage(v8::internal::NEW_SPACE); | 1370 Heap::CollectGarbage(v8::internal::NEW_SPACE); |
1371 f->Call(recv, 0, NULL); | 1371 f->Call(recv, 0, NULL); |
1372 CHECK_EQ(2 + i * 3, break_point_hit_count); | 1372 CHECK_EQ(2 + i * 3, break_point_hit_count); |
1373 | 1373 |
1374 // Mark sweep (and perhaps compact) and call function. | 1374 // Mark sweep (and perhaps compact) and call function. |
1375 Heap::CollectAllGarbage(force_compaction); | 1375 Heap::CollectAllGarbage(gc_flags); |
1376 f->Call(recv, 0, NULL); | 1376 f->Call(recv, 0, NULL); |
1377 CHECK_EQ(3 + i * 3, break_point_hit_count); | 1377 CHECK_EQ(3 + i * 3, break_point_hit_count); |
1378 } | 1378 } |
1379 } | 1379 } |
1380 | 1380 |
1381 | 1381 |
1382 static void TestBreakPointSurviveGC(bool force_compaction) { | 1382 static void TestBreakPointSurviveGC(int gc_flags) { |
1383 break_point_hit_count = 0; | 1383 break_point_hit_count = 0; |
1384 v8::HandleScope scope; | 1384 v8::HandleScope scope; |
1385 DebugLocalContext env; | 1385 DebugLocalContext env; |
1386 | 1386 |
1387 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, | 1387 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, |
1388 v8::Undefined()); | 1388 v8::Undefined()); |
1389 v8::Local<v8::Function> foo; | 1389 v8::Local<v8::Function> foo; |
1390 | 1390 |
1391 // Test IC store break point with garbage collection. | 1391 // Test IC store break point with garbage collection. |
1392 { | 1392 { |
1393 v8::Local<v8::Function> bar = | 1393 v8::Local<v8::Function> bar = |
1394 CompileFunction(&env, "function foo(){}", "foo"); | 1394 CompileFunction(&env, "function foo(){}", "foo"); |
1395 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); | 1395 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); |
1396 SetBreakPoint(foo, 0); | 1396 SetBreakPoint(foo, 0); |
1397 } | 1397 } |
1398 CallAndGC(env->Global(), foo, force_compaction); | 1398 CallAndGC(env->Global(), foo, gc_flags); |
1399 | 1399 |
1400 // Test IC load break point with garbage collection. | 1400 // Test IC load break point with garbage collection. |
1401 { | 1401 { |
1402 v8::Local<v8::Function> bar = | 1402 v8::Local<v8::Function> bar = |
1403 CompileFunction(&env, "function foo(){}", "foo"); | 1403 CompileFunction(&env, "function foo(){}", "foo"); |
1404 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); | 1404 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); |
1405 SetBreakPoint(foo, 0); | 1405 SetBreakPoint(foo, 0); |
1406 } | 1406 } |
1407 CallAndGC(env->Global(), foo, force_compaction); | 1407 CallAndGC(env->Global(), foo, gc_flags); |
1408 | 1408 |
1409 // Test IC call break point with garbage collection. | 1409 // Test IC call break point with garbage collection. |
1410 { | 1410 { |
1411 v8::Local<v8::Function> bar = | 1411 v8::Local<v8::Function> bar = |
1412 CompileFunction(&env, "function foo(){}", "foo"); | 1412 CompileFunction(&env, "function foo(){}", "foo"); |
1413 foo = CompileFunction(&env, | 1413 foo = CompileFunction(&env, |
1414 "function bar(){};function foo(){bar();}", | 1414 "function bar(){};function foo(){bar();}", |
1415 "foo"); | 1415 "foo"); |
1416 SetBreakPoint(foo, 0); | 1416 SetBreakPoint(foo, 0); |
1417 } | 1417 } |
1418 CallAndGC(env->Global(), foo, force_compaction); | 1418 CallAndGC(env->Global(), foo, gc_flags); |
1419 | 1419 |
1420 // Test return break point with garbage collection. | 1420 // Test return break point with garbage collection. |
1421 { | 1421 { |
1422 v8::Local<v8::Function> bar = | 1422 v8::Local<v8::Function> bar = |
1423 CompileFunction(&env, "function foo(){}", "foo"); | 1423 CompileFunction(&env, "function foo(){}", "foo"); |
1424 foo = CompileFunction(&env, "function foo(){}", "foo"); | 1424 foo = CompileFunction(&env, "function foo(){}", "foo"); |
1425 SetBreakPoint(foo, 0); | 1425 SetBreakPoint(foo, 0); |
1426 } | 1426 } |
1427 CallAndGC(env->Global(), foo, force_compaction); | 1427 CallAndGC(env->Global(), foo, gc_flags); |
1428 | 1428 |
1429 // Test non IC break point with garbage collection. | 1429 // Test non IC break point with garbage collection. |
1430 { | 1430 { |
1431 v8::Local<v8::Function> bar = | 1431 v8::Local<v8::Function> bar = |
1432 CompileFunction(&env, "function foo(){}", "foo"); | 1432 CompileFunction(&env, "function foo(){}", "foo"); |
1433 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); | 1433 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); |
1434 SetBreakPoint(foo, 0); | 1434 SetBreakPoint(foo, 0); |
1435 } | 1435 } |
1436 CallAndGC(env->Global(), foo, force_compaction); | 1436 CallAndGC(env->Global(), foo, gc_flags); |
1437 | 1437 |
1438 | 1438 |
1439 v8::Debug::SetDebugEventListener(NULL); | 1439 v8::Debug::SetDebugEventListener(NULL); |
1440 CheckDebuggerUnloaded(); | 1440 CheckDebuggerUnloaded(); |
1441 } | 1441 } |
1442 | 1442 |
1443 | 1443 |
1444 // Test that a break point can be set at a return store location. | 1444 // Test that a break point can be set at a return store location. |
1445 TEST(BreakPointSurviveGC) { | 1445 TEST(BreakPointSurviveGC) { |
1446 TestBreakPointSurviveGC(false); | 1446 TestBreakPointSurviveGC(Heap::kNoGCFlags); |
1447 TestBreakPointSurviveGC(true); | 1447 TestBreakPointSurviveGC(Heap::kForceCompactionMask); |
1448 } | 1448 } |
1449 | 1449 |
1450 | 1450 |
1451 // Test that break points can be set using the global Debug object. | 1451 // Test that break points can be set using the global Debug object. |
1452 TEST(BreakPointThroughJavaScript) { | 1452 TEST(BreakPointThroughJavaScript) { |
1453 break_point_hit_count = 0; | 1453 break_point_hit_count = 0; |
1454 v8::HandleScope scope; | 1454 v8::HandleScope scope; |
1455 DebugLocalContext env; | 1455 DebugLocalContext env; |
1456 env.ExposeDebug(); | 1456 env.ExposeDebug(); |
1457 | 1457 |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2192 " a = 1; // line 1\n" | 2192 " a = 1; // line 1\n" |
2193 "}\n" | 2193 "}\n" |
2194 "a = 2; // line 3\n"); | 2194 "a = 2; // line 3\n"); |
2195 v8::Local<v8::Function> f; | 2195 v8::Local<v8::Function> f; |
2196 { | 2196 { |
2197 v8::HandleScope scope; | 2197 v8::HandleScope scope; |
2198 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); | 2198 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); |
2199 } | 2199 } |
2200 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); | 2200 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
2201 | 2201 |
2202 Heap::CollectAllGarbage(false); | 2202 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
2203 | 2203 |
2204 SetScriptBreakPointByNameFromJS("test.html", 3, -1); | 2204 SetScriptBreakPointByNameFromJS("test.html", 3, -1); |
2205 | 2205 |
2206 // Call f and check that there was no break points. | 2206 // Call f and check that there was no break points. |
2207 break_point_hit_count = 0; | 2207 break_point_hit_count = 0; |
2208 f->Call(env->Global(), 0, NULL); | 2208 f->Call(env->Global(), 0, NULL); |
2209 CHECK_EQ(0, break_point_hit_count); | 2209 CHECK_EQ(0, break_point_hit_count); |
2210 | 2210 |
2211 // Recompile and run script and check that break point was hit. | 2211 // Recompile and run script and check that break point was hit. |
2212 break_point_hit_count = 0; | 2212 break_point_hit_count = 0; |
(...skipping 4166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6379 break_point_hit_count = 0; | 6379 break_point_hit_count = 0; |
6380 script_collected_count = 0; | 6380 script_collected_count = 0; |
6381 v8::HandleScope scope; | 6381 v8::HandleScope scope; |
6382 DebugLocalContext env; | 6382 DebugLocalContext env; |
6383 | 6383 |
6384 // Request the loaded scripts to initialize the debugger script cache. | 6384 // Request the loaded scripts to initialize the debugger script cache. |
6385 Debug::GetLoadedScripts(); | 6385 Debug::GetLoadedScripts(); |
6386 | 6386 |
6387 // Do garbage collection to ensure that only the script in this test will be | 6387 // Do garbage collection to ensure that only the script in this test will be |
6388 // collected afterwards. | 6388 // collected afterwards. |
6389 Heap::CollectAllGarbage(false); | 6389 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
6390 | 6390 |
6391 script_collected_count = 0; | 6391 script_collected_count = 0; |
6392 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, | 6392 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, |
6393 v8::Undefined()); | 6393 v8::Undefined()); |
6394 { | 6394 { |
6395 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6395 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
6396 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6396 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
6397 } | 6397 } |
6398 | 6398 |
6399 // Do garbage collection to collect the script above which is no longer | 6399 // Do garbage collection to collect the script above which is no longer |
6400 // referenced. | 6400 // referenced. |
6401 Heap::CollectAllGarbage(false); | 6401 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
6402 | 6402 |
6403 CHECK_EQ(2, script_collected_count); | 6403 CHECK_EQ(2, script_collected_count); |
6404 | 6404 |
6405 v8::Debug::SetDebugEventListener(NULL); | 6405 v8::Debug::SetDebugEventListener(NULL); |
6406 CheckDebuggerUnloaded(); | 6406 CheckDebuggerUnloaded(); |
6407 } | 6407 } |
6408 | 6408 |
6409 | 6409 |
6410 // Debug event listener which counts the script collected events. | 6410 // Debug event listener which counts the script collected events. |
6411 int script_collected_message_count = 0; | 6411 int script_collected_message_count = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
6426 v8::HandleScope scope; | 6426 v8::HandleScope scope; |
6427 | 6427 |
6428 { // Scope for the DebugLocalContext. | 6428 { // Scope for the DebugLocalContext. |
6429 DebugLocalContext env; | 6429 DebugLocalContext env; |
6430 | 6430 |
6431 // Request the loaded scripts to initialize the debugger script cache. | 6431 // Request the loaded scripts to initialize the debugger script cache. |
6432 Debug::GetLoadedScripts(); | 6432 Debug::GetLoadedScripts(); |
6433 | 6433 |
6434 // Do garbage collection to ensure that only the script in this test will be | 6434 // Do garbage collection to ensure that only the script in this test will be |
6435 // collected afterwards. | 6435 // collected afterwards. |
6436 Heap::CollectAllGarbage(false); | 6436 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
6437 | 6437 |
6438 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); | 6438 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); |
6439 { | 6439 { |
6440 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6440 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
6441 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6441 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
6442 } | 6442 } |
6443 } | 6443 } |
6444 | 6444 |
6445 // Do garbage collection to collect the script above which is no longer | 6445 // Do garbage collection to collect the script above which is no longer |
6446 // referenced. | 6446 // referenced. |
6447 Heap::CollectAllGarbage(false); | 6447 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
6448 | 6448 |
6449 CHECK_EQ(2, script_collected_message_count); | 6449 CHECK_EQ(2, script_collected_message_count); |
6450 | 6450 |
6451 v8::Debug::SetMessageHandler2(NULL); | 6451 v8::Debug::SetMessageHandler2(NULL); |
6452 } | 6452 } |
6453 | 6453 |
6454 | 6454 |
6455 // Debug event listener which counts the after compile events. | 6455 // Debug event listener which counts the after compile events. |
6456 int after_compile_message_count = 0; | 6456 int after_compile_message_count = 0; |
6457 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { | 6457 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7195 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); | 7195 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); |
7196 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); | 7196 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); |
7197 | 7197 |
7198 // Get rid of the debug event listener. | 7198 // Get rid of the debug event listener. |
7199 v8::Debug::SetDebugEventListener(NULL); | 7199 v8::Debug::SetDebugEventListener(NULL); |
7200 CheckDebuggerUnloaded(); | 7200 CheckDebuggerUnloaded(); |
7201 } | 7201 } |
7202 | 7202 |
7203 | 7203 |
7204 #endif // ENABLE_DEBUGGER_SUPPORT | 7204 #endif // ENABLE_DEBUGGER_SUPPORT |
OLD | NEW |