| 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 |