OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 418 |
419 | 419 |
420 // Check that the debugger has been fully unloaded. | 420 // Check that the debugger has been fully unloaded. |
421 void CheckDebuggerUnloaded(bool check_functions) { | 421 void CheckDebuggerUnloaded(bool check_functions) { |
422 // Check that the debugger context is cleared and that there is no debug | 422 // Check that the debugger context is cleared and that there is no debug |
423 // information stored for the debugger. | 423 // information stored for the debugger. |
424 CHECK(Isolate::Current()->debug()->debug_context().is_null()); | 424 CHECK(Isolate::Current()->debug()->debug_context().is_null()); |
425 CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_); | 425 CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_); |
426 | 426 |
427 // Collect garbage to ensure weak handles are cleared. | 427 // Collect garbage to ensure weak handles are cleared. |
428 HEAP->CollectAllGarbage(false); | 428 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
429 HEAP->CollectAllGarbage(false); | 429 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
430 | 430 |
431 // Iterate the head and check that there are no debugger related objects left. | 431 // Iterate the head and check that there are no debugger related objects left. |
432 HeapIterator iterator; | 432 HeapIterator iterator; |
433 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 433 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
434 CHECK(!obj->IsDebugInfo()); | 434 CHECK(!obj->IsDebugInfo()); |
435 CHECK(!obj->IsBreakPointInfo()); | 435 CHECK(!obj->IsBreakPointInfo()); |
436 | 436 |
437 // If deep check of functions is requested check that no debug break code | 437 // If deep check of functions is requested check that no debug break code |
438 // is left in all functions. | 438 // is left in all functions. |
439 if (check_functions) { | 439 if (check_functions) { |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 // Perform a garbage collection when break point is hit and continue. Based | 937 // Perform a garbage collection when break point is hit and continue. Based |
938 // on the number of break points hit either scavenge or mark compact | 938 // on the number of break points hit either scavenge or mark compact |
939 // collector is used. | 939 // collector is used. |
940 if (event == v8::Break) { | 940 if (event == v8::Break) { |
941 break_point_hit_count++; | 941 break_point_hit_count++; |
942 if (break_point_hit_count % 2 == 0) { | 942 if (break_point_hit_count % 2 == 0) { |
943 // Scavenge. | 943 // Scavenge. |
944 HEAP->CollectGarbage(v8::internal::NEW_SPACE); | 944 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
945 } else { | 945 } else { |
946 // Mark sweep compact. | 946 // Mark sweep compact. |
947 HEAP->CollectAllGarbage(true); | 947 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
948 } | 948 } |
949 } | 949 } |
950 } | 950 } |
951 | 951 |
952 | 952 |
953 // Debug event handler which re-issues a debug break and calls the garbage | 953 // Debug event handler which re-issues a debug break and calls the garbage |
954 // collector to have the heap verified. | 954 // collector to have the heap verified. |
955 static void DebugEventBreak(v8::DebugEvent event, | 955 static void DebugEventBreak(v8::DebugEvent event, |
956 v8::Handle<v8::Object> exec_state, | 956 v8::Handle<v8::Object> exec_state, |
957 v8::Handle<v8::Object> event_data, | 957 v8::Handle<v8::Object> event_data, |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 CallWithBreakPoints(env->Global(), foo, 1, 25); | 1410 CallWithBreakPoints(env->Global(), foo, 1, 25); |
1411 | 1411 |
1412 v8::Debug::SetDebugEventListener(NULL); | 1412 v8::Debug::SetDebugEventListener(NULL); |
1413 CheckDebuggerUnloaded(); | 1413 CheckDebuggerUnloaded(); |
1414 } | 1414 } |
1415 | 1415 |
1416 | 1416 |
1417 // Call the function three times with different garbage collections in between | 1417 // Call the function three times with different garbage collections in between |
1418 // and make sure that the break point survives. | 1418 // and make sure that the break point survives. |
1419 static void CallAndGC(v8::Local<v8::Object> recv, | 1419 static void CallAndGC(v8::Local<v8::Object> recv, |
1420 v8::Local<v8::Function> f, | 1420 v8::Local<v8::Function> f) { |
1421 bool force_compaction) { | |
1422 break_point_hit_count = 0; | 1421 break_point_hit_count = 0; |
1423 | 1422 |
1424 for (int i = 0; i < 3; i++) { | 1423 for (int i = 0; i < 3; i++) { |
1425 // Call function. | 1424 // Call function. |
1426 f->Call(recv, 0, NULL); | 1425 f->Call(recv, 0, NULL); |
1427 CHECK_EQ(1 + i * 3, break_point_hit_count); | 1426 CHECK_EQ(1 + i * 3, break_point_hit_count); |
1428 | 1427 |
1429 // Scavenge and call function. | 1428 // Scavenge and call function. |
1430 HEAP->CollectGarbage(v8::internal::NEW_SPACE); | 1429 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
1431 f->Call(recv, 0, NULL); | 1430 f->Call(recv, 0, NULL); |
1432 CHECK_EQ(2 + i * 3, break_point_hit_count); | 1431 CHECK_EQ(2 + i * 3, break_point_hit_count); |
1433 | 1432 |
1434 // Mark sweep (and perhaps compact) and call function. | 1433 // Mark sweep (and perhaps compact) and call function. |
1435 HEAP->CollectAllGarbage(force_compaction); | 1434 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1436 f->Call(recv, 0, NULL); | 1435 f->Call(recv, 0, NULL); |
1437 CHECK_EQ(3 + i * 3, break_point_hit_count); | 1436 CHECK_EQ(3 + i * 3, break_point_hit_count); |
1438 } | 1437 } |
1439 } | 1438 } |
1440 | 1439 |
1441 | 1440 |
1442 static void TestBreakPointSurviveGC(bool force_compaction) { | 1441 // Test that a break point can be set at a return store location. |
| 1442 TEST(BreakPointSurviveGC) { |
1443 break_point_hit_count = 0; | 1443 break_point_hit_count = 0; |
1444 v8::HandleScope scope; | 1444 v8::HandleScope scope; |
1445 DebugLocalContext env; | 1445 DebugLocalContext env; |
1446 | 1446 |
1447 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, | 1447 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, |
1448 v8::Undefined()); | 1448 v8::Undefined()); |
1449 v8::Local<v8::Function> foo; | 1449 v8::Local<v8::Function> foo; |
1450 | 1450 |
1451 // Test IC store break point with garbage collection. | 1451 // Test IC store break point with garbage collection. |
1452 { | 1452 { |
1453 v8::Local<v8::Function> bar = | 1453 v8::Local<v8::Function> bar = |
1454 CompileFunction(&env, "function foo(){}", "foo"); | 1454 CompileFunction(&env, "function foo(){}", "foo"); |
1455 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); | 1455 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); |
1456 SetBreakPoint(foo, 0); | 1456 SetBreakPoint(foo, 0); |
1457 } | 1457 } |
1458 CallAndGC(env->Global(), foo, force_compaction); | 1458 CallAndGC(env->Global(), foo); |
1459 | 1459 |
1460 // Test IC load break point with garbage collection. | 1460 // Test IC load break point with garbage collection. |
1461 { | 1461 { |
1462 v8::Local<v8::Function> bar = | 1462 v8::Local<v8::Function> bar = |
1463 CompileFunction(&env, "function foo(){}", "foo"); | 1463 CompileFunction(&env, "function foo(){}", "foo"); |
1464 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); | 1464 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); |
1465 SetBreakPoint(foo, 0); | 1465 SetBreakPoint(foo, 0); |
1466 } | 1466 } |
1467 CallAndGC(env->Global(), foo, force_compaction); | 1467 CallAndGC(env->Global(), foo); |
1468 | 1468 |
1469 // Test IC call break point with garbage collection. | 1469 // Test IC call break point with garbage collection. |
1470 { | 1470 { |
1471 v8::Local<v8::Function> bar = | 1471 v8::Local<v8::Function> bar = |
1472 CompileFunction(&env, "function foo(){}", "foo"); | 1472 CompileFunction(&env, "function foo(){}", "foo"); |
1473 foo = CompileFunction(&env, | 1473 foo = CompileFunction(&env, |
1474 "function bar(){};function foo(){bar();}", | 1474 "function bar(){};function foo(){bar();}", |
1475 "foo"); | 1475 "foo"); |
1476 SetBreakPoint(foo, 0); | 1476 SetBreakPoint(foo, 0); |
1477 } | 1477 } |
1478 CallAndGC(env->Global(), foo, force_compaction); | 1478 CallAndGC(env->Global(), foo); |
1479 | 1479 |
1480 // Test return break point with garbage collection. | 1480 // Test return break point with garbage collection. |
1481 { | 1481 { |
1482 v8::Local<v8::Function> bar = | 1482 v8::Local<v8::Function> bar = |
1483 CompileFunction(&env, "function foo(){}", "foo"); | 1483 CompileFunction(&env, "function foo(){}", "foo"); |
1484 foo = CompileFunction(&env, "function foo(){}", "foo"); | 1484 foo = CompileFunction(&env, "function foo(){}", "foo"); |
1485 SetBreakPoint(foo, 0); | 1485 SetBreakPoint(foo, 0); |
1486 } | 1486 } |
1487 CallAndGC(env->Global(), foo, force_compaction); | 1487 CallAndGC(env->Global(), foo); |
1488 | 1488 |
1489 // Test non IC break point with garbage collection. | 1489 // Test non IC break point with garbage collection. |
1490 { | 1490 { |
1491 v8::Local<v8::Function> bar = | 1491 v8::Local<v8::Function> bar = |
1492 CompileFunction(&env, "function foo(){}", "foo"); | 1492 CompileFunction(&env, "function foo(){}", "foo"); |
1493 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); | 1493 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); |
1494 SetBreakPoint(foo, 0); | 1494 SetBreakPoint(foo, 0); |
1495 } | 1495 } |
1496 CallAndGC(env->Global(), foo, force_compaction); | 1496 CallAndGC(env->Global(), foo); |
1497 | 1497 |
1498 | 1498 |
1499 v8::Debug::SetDebugEventListener(NULL); | 1499 v8::Debug::SetDebugEventListener(NULL); |
1500 CheckDebuggerUnloaded(); | 1500 CheckDebuggerUnloaded(); |
1501 } | 1501 } |
1502 | 1502 |
1503 | 1503 |
1504 // Test that a break point can be set at a return store location. | |
1505 TEST(BreakPointSurviveGC) { | |
1506 TestBreakPointSurviveGC(false); | |
1507 TestBreakPointSurviveGC(true); | |
1508 } | |
1509 | |
1510 | |
1511 // Test that break points can be set using the global Debug object. | 1504 // Test that break points can be set using the global Debug object. |
1512 TEST(BreakPointThroughJavaScript) { | 1505 TEST(BreakPointThroughJavaScript) { |
1513 break_point_hit_count = 0; | 1506 break_point_hit_count = 0; |
1514 v8::HandleScope scope; | 1507 v8::HandleScope scope; |
1515 DebugLocalContext env; | 1508 DebugLocalContext env; |
1516 env.ExposeDebug(); | 1509 env.ExposeDebug(); |
1517 | 1510 |
1518 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, | 1511 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, |
1519 v8::Undefined()); | 1512 v8::Undefined()); |
1520 v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); | 1513 v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 " a = 1; // line 1\n" | 2245 " a = 1; // line 1\n" |
2253 "}\n" | 2246 "}\n" |
2254 "a = 2; // line 3\n"); | 2247 "a = 2; // line 3\n"); |
2255 v8::Local<v8::Function> f; | 2248 v8::Local<v8::Function> f; |
2256 { | 2249 { |
2257 v8::HandleScope scope; | 2250 v8::HandleScope scope; |
2258 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); | 2251 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); |
2259 } | 2252 } |
2260 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); | 2253 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
2261 | 2254 |
2262 HEAP->CollectAllGarbage(false); | 2255 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2263 | 2256 |
2264 SetScriptBreakPointByNameFromJS("test.html", 3, -1); | 2257 SetScriptBreakPointByNameFromJS("test.html", 3, -1); |
2265 | 2258 |
2266 // Call f and check that there was no break points. | 2259 // Call f and check that there was no break points. |
2267 break_point_hit_count = 0; | 2260 break_point_hit_count = 0; |
2268 f->Call(env->Global(), 0, NULL); | 2261 f->Call(env->Global(), 0, NULL); |
2269 CHECK_EQ(0, break_point_hit_count); | 2262 CHECK_EQ(0, break_point_hit_count); |
2270 | 2263 |
2271 // Recompile and run script and check that break point was hit. | 2264 // Recompile and run script and check that break point was hit. |
2272 break_point_hit_count = 0; | 2265 break_point_hit_count = 0; |
(...skipping 4192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6465 break_point_hit_count = 0; | 6458 break_point_hit_count = 0; |
6466 script_collected_count = 0; | 6459 script_collected_count = 0; |
6467 v8::HandleScope scope; | 6460 v8::HandleScope scope; |
6468 DebugLocalContext env; | 6461 DebugLocalContext env; |
6469 | 6462 |
6470 // Request the loaded scripts to initialize the debugger script cache. | 6463 // Request the loaded scripts to initialize the debugger script cache. |
6471 debug->GetLoadedScripts(); | 6464 debug->GetLoadedScripts(); |
6472 | 6465 |
6473 // Do garbage collection to ensure that only the script in this test will be | 6466 // Do garbage collection to ensure that only the script in this test will be |
6474 // collected afterwards. | 6467 // collected afterwards. |
6475 HEAP->CollectAllGarbage(false); | 6468 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
6476 | 6469 |
6477 script_collected_count = 0; | 6470 script_collected_count = 0; |
6478 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, | 6471 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, |
6479 v8::Undefined()); | 6472 v8::Undefined()); |
6480 { | 6473 { |
6481 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6474 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
6482 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6475 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
6483 } | 6476 } |
6484 | 6477 |
6485 // Do garbage collection to collect the script above which is no longer | 6478 // Do garbage collection to collect the script above which is no longer |
6486 // referenced. | 6479 // referenced. |
6487 HEAP->CollectAllGarbage(false); | 6480 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
6488 | 6481 |
6489 CHECK_EQ(2, script_collected_count); | 6482 CHECK_EQ(2, script_collected_count); |
6490 | 6483 |
6491 v8::Debug::SetDebugEventListener(NULL); | 6484 v8::Debug::SetDebugEventListener(NULL); |
6492 CheckDebuggerUnloaded(); | 6485 CheckDebuggerUnloaded(); |
6493 } | 6486 } |
6494 | 6487 |
6495 | 6488 |
6496 // Debug event listener which counts the script collected events. | 6489 // Debug event listener which counts the script collected events. |
6497 int script_collected_message_count = 0; | 6490 int script_collected_message_count = 0; |
(...skipping 15 matching lines...) Expand all Loading... |
6513 v8::HandleScope scope; | 6506 v8::HandleScope scope; |
6514 | 6507 |
6515 { // Scope for the DebugLocalContext. | 6508 { // Scope for the DebugLocalContext. |
6516 DebugLocalContext env; | 6509 DebugLocalContext env; |
6517 | 6510 |
6518 // Request the loaded scripts to initialize the debugger script cache. | 6511 // Request the loaded scripts to initialize the debugger script cache. |
6519 debug->GetLoadedScripts(); | 6512 debug->GetLoadedScripts(); |
6520 | 6513 |
6521 // Do garbage collection to ensure that only the script in this test will be | 6514 // Do garbage collection to ensure that only the script in this test will be |
6522 // collected afterwards. | 6515 // collected afterwards. |
6523 HEAP->CollectAllGarbage(false); | 6516 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
6524 | 6517 |
6525 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); | 6518 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); |
6526 { | 6519 { |
6527 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6520 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
6528 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6521 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
6529 } | 6522 } |
6530 } | 6523 } |
6531 | 6524 |
6532 // Do garbage collection to collect the script above which is no longer | 6525 // Do garbage collection to collect the script above which is no longer |
6533 // referenced. | 6526 // referenced. |
6534 HEAP->CollectAllGarbage(false); | 6527 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
6535 | 6528 |
6536 CHECK_EQ(2, script_collected_message_count); | 6529 CHECK_EQ(2, script_collected_message_count); |
6537 | 6530 |
6538 v8::Debug::SetMessageHandler2(NULL); | 6531 v8::Debug::SetMessageHandler2(NULL); |
6539 } | 6532 } |
6540 | 6533 |
6541 | 6534 |
6542 // Debug event listener which counts the after compile events. | 6535 // Debug event listener which counts the after compile events. |
6543 int after_compile_message_count = 0; | 6536 int after_compile_message_count = 0; |
6544 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { | 6537 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { |
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7296 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); | 7289 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); |
7297 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); | 7290 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); |
7298 | 7291 |
7299 // Get rid of the debug event listener. | 7292 // Get rid of the debug event listener. |
7300 v8::Debug::SetDebugEventListener(NULL); | 7293 v8::Debug::SetDebugEventListener(NULL); |
7301 CheckDebuggerUnloaded(); | 7294 CheckDebuggerUnloaded(); |
7302 } | 7295 } |
7303 | 7296 |
7304 | 7297 |
7305 #endif // ENABLE_DEBUGGER_SUPPORT | 7298 #endif // ENABLE_DEBUGGER_SUPPORT |
OLD | NEW |