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