| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 context_->Enter(); | 136 context_->Enter(); |
| 137 } | 137 } |
| 138 inline ~DebugLocalContext() { | 138 inline ~DebugLocalContext() { |
| 139 context_->Exit(); | 139 context_->Exit(); |
| 140 context_.Dispose(); | 140 context_.Dispose(); |
| 141 } | 141 } |
| 142 inline v8::Context* operator->() { return *context_; } | 142 inline v8::Context* operator->() { return *context_; } |
| 143 inline v8::Context* operator*() { return *context_; } | 143 inline v8::Context* operator*() { return *context_; } |
| 144 inline bool IsReady() { return !context_.IsEmpty(); } | 144 inline bool IsReady() { return !context_.IsEmpty(); } |
| 145 void ExposeDebug() { | 145 void ExposeDebug() { |
| 146 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 146 // Expose the debug context global object in the global object for testing. | 147 // Expose the debug context global object in the global object for testing. |
| 147 Debug::Load(); | 148 debug->Load(); |
| 148 Debug::debug_context()->set_security_token( | 149 debug->debug_context()->set_security_token( |
| 149 v8::Utils::OpenHandle(*context_)->security_token()); | 150 v8::Utils::OpenHandle(*context_)->security_token()); |
| 150 | 151 |
| 151 Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast( | 152 Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast( |
| 152 v8::Utils::OpenHandle(*context_->Global()))); | 153 v8::Utils::OpenHandle(*context_->Global()))); |
| 153 Handle<v8::internal::String> debug_string = | 154 Handle<v8::internal::String> debug_string = |
| 154 v8::internal::Factory::LookupAsciiSymbol("debug"); | 155 FACTORY->LookupAsciiSymbol("debug"); |
| 155 SetProperty(global, debug_string, | 156 SetProperty(global, debug_string, |
| 156 Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM, | 157 Handle<Object>(debug->debug_context()->global_proxy()), DONT_ENUM, |
| 157 ::v8::internal::kNonStrictMode); | 158 ::v8::internal::kNonStrictMode); |
| 158 } | 159 } |
| 159 private: | 160 private: |
| 160 v8::Persistent<v8::Context> context_; | 161 v8::Persistent<v8::Context> context_; |
| 161 }; | 162 }; |
| 162 | 163 |
| 163 | 164 |
| 164 // --- H e l p e r F u n c t i o n s | 165 // --- H e l p e r F u n c t i o n s |
| 165 | 166 |
| 166 | 167 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 189 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); | 190 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); |
| 190 return Debug::HasDebugInfo(shared); | 191 return Debug::HasDebugInfo(shared); |
| 191 } | 192 } |
| 192 | 193 |
| 193 | 194 |
| 194 // Set a break point in a function and return the associated break point | 195 // Set a break point in a function and return the associated break point |
| 195 // number. | 196 // number. |
| 196 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { | 197 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { |
| 197 static int break_point = 0; | 198 static int break_point = 0; |
| 198 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); | 199 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); |
| 199 Debug::SetBreakPoint( | 200 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 201 debug->SetBreakPoint( |
| 200 shared, | 202 shared, |
| 201 Handle<Object>(v8::internal::Smi::FromInt(++break_point)), | 203 Handle<Object>(v8::internal::Smi::FromInt(++break_point)), |
| 202 &position); | 204 &position); |
| 203 return break_point; | 205 return break_point; |
| 204 } | 206 } |
| 205 | 207 |
| 206 | 208 |
| 207 // Set a break point in a function and return the associated break point | 209 // Set a break point in a function and return the associated break point |
| 208 // number. | 210 // number. |
| 209 static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { | 211 static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 v8::Handle<v8::String> str = v8::String::New(buffer.start()); | 274 v8::Handle<v8::String> str = v8::String::New(buffer.start()); |
| 273 v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); | 275 v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); |
| 274 CHECK(!try_catch.HasCaught()); | 276 CHECK(!try_catch.HasCaught()); |
| 275 return value->Int32Value(); | 277 return value->Int32Value(); |
| 276 } | 278 } |
| 277 } | 279 } |
| 278 | 280 |
| 279 | 281 |
| 280 // Clear a break point. | 282 // Clear a break point. |
| 281 static void ClearBreakPoint(int break_point) { | 283 static void ClearBreakPoint(int break_point) { |
| 282 Debug::ClearBreakPoint( | 284 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 285 debug->ClearBreakPoint( |
| 283 Handle<Object>(v8::internal::Smi::FromInt(break_point))); | 286 Handle<Object>(v8::internal::Smi::FromInt(break_point))); |
| 284 } | 287 } |
| 285 | 288 |
| 286 | 289 |
| 287 // Clear a break point using the global Debug object. | 290 // Clear a break point using the global Debug object. |
| 288 static void ClearBreakPointFromJS(int break_point_number) { | 291 static void ClearBreakPointFromJS(int break_point_number) { |
| 289 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 292 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 290 OS::SNPrintF(buffer, | 293 OS::SNPrintF(buffer, |
| 291 "debug.Debug.clearBreakPoint(%d)", | 294 "debug.Debug.clearBreakPoint(%d)", |
| 292 break_point_number); | 295 break_point_number); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 OS::SNPrintF(buffer, | 335 OS::SNPrintF(buffer, |
| 333 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", | 336 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", |
| 334 break_point_number, ignoreCount); | 337 break_point_number, ignoreCount); |
| 335 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 338 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 336 v8::Script::Compile(v8::String::New(buffer.start()))->Run(); | 339 v8::Script::Compile(v8::String::New(buffer.start()))->Run(); |
| 337 } | 340 } |
| 338 | 341 |
| 339 | 342 |
| 340 // Change break on exception. | 343 // Change break on exception. |
| 341 static void ChangeBreakOnException(bool caught, bool uncaught) { | 344 static void ChangeBreakOnException(bool caught, bool uncaught) { |
| 342 Debug::ChangeBreakOnException(v8::internal::BreakException, caught); | 345 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 343 Debug::ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); | 346 debug->ChangeBreakOnException(v8::internal::BreakException, caught); |
| 347 debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); |
| 344 } | 348 } |
| 345 | 349 |
| 346 | 350 |
| 347 // Change break on exception using the global Debug object. | 351 // Change break on exception using the global Debug object. |
| 348 static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { | 352 static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { |
| 349 if (caught) { | 353 if (caught) { |
| 350 v8::Script::Compile( | 354 v8::Script::Compile( |
| 351 v8::String::New("debug.Debug.setBreakOnException()"))->Run(); | 355 v8::String::New("debug.Debug.setBreakOnException()"))->Run(); |
| 352 } else { | 356 } else { |
| 353 v8::Script::Compile( | 357 v8::Script::Compile( |
| 354 v8::String::New("debug.Debug.clearBreakOnException()"))->Run(); | 358 v8::String::New("debug.Debug.clearBreakOnException()"))->Run(); |
| 355 } | 359 } |
| 356 if (uncaught) { | 360 if (uncaught) { |
| 357 v8::Script::Compile( | 361 v8::Script::Compile( |
| 358 v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run(); | 362 v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run(); |
| 359 } else { | 363 } else { |
| 360 v8::Script::Compile( | 364 v8::Script::Compile( |
| 361 v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); | 365 v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); |
| 362 } | 366 } |
| 363 } | 367 } |
| 364 | 368 |
| 365 | 369 |
| 366 // Prepare to step to next break location. | 370 // Prepare to step to next break location. |
| 367 static void PrepareStep(StepAction step_action) { | 371 static void PrepareStep(StepAction step_action) { |
| 368 Debug::PrepareStep(step_action, 1); | 372 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 373 debug->PrepareStep(step_action, 1); |
| 369 } | 374 } |
| 370 | 375 |
| 371 | 376 |
| 372 // This function is in namespace v8::internal to be friend with class | 377 // This function is in namespace v8::internal to be friend with class |
| 373 // v8::internal::Debug. | 378 // v8::internal::Debug. |
| 374 namespace v8 { | 379 namespace v8 { |
| 375 namespace internal { | 380 namespace internal { |
| 376 | 381 |
| 377 // Collect the currently debugged functions. | 382 // Collect the currently debugged functions. |
| 378 Handle<FixedArray> GetDebuggedFunctions() { | 383 Handle<FixedArray> GetDebuggedFunctions() { |
| 379 v8::internal::DebugInfoListNode* node = Debug::debug_info_list_; | 384 Debug* debug = Isolate::Current()->debug(); |
| 385 |
| 386 v8::internal::DebugInfoListNode* node = debug->debug_info_list_; |
| 380 | 387 |
| 381 // Find the number of debugged functions. | 388 // Find the number of debugged functions. |
| 382 int count = 0; | 389 int count = 0; |
| 383 while (node) { | 390 while (node) { |
| 384 count++; | 391 count++; |
| 385 node = node->next(); | 392 node = node->next(); |
| 386 } | 393 } |
| 387 | 394 |
| 388 // Allocate array for the debugged functions | 395 // Allocate array for the debugged functions |
| 389 Handle<FixedArray> debugged_functions = | 396 Handle<FixedArray> debugged_functions = |
| 390 v8::internal::Factory::NewFixedArray(count); | 397 FACTORY->NewFixedArray(count); |
| 391 | 398 |
| 392 // Run through the debug info objects and collect all functions. | 399 // Run through the debug info objects and collect all functions. |
| 393 count = 0; | 400 count = 0; |
| 394 while (node) { | 401 while (node) { |
| 395 debugged_functions->set(count++, *node->debug_info()); | 402 debugged_functions->set(count++, *node->debug_info()); |
| 396 node = node->next(); | 403 node = node->next(); |
| 397 } | 404 } |
| 398 | 405 |
| 399 return debugged_functions; | 406 return debugged_functions; |
| 400 } | 407 } |
| 401 | 408 |
| 402 | 409 |
| 403 static Handle<Code> ComputeCallDebugBreak(int argc) { | 410 static Handle<Code> ComputeCallDebugBreak(int argc) { |
| 404 CALL_HEAP_FUNCTION( | 411 CALL_HEAP_FUNCTION( |
| 405 v8::internal::StubCache::ComputeCallDebugBreak(argc, Code::CALL_IC), | 412 v8::internal::Isolate::Current(), |
| 413 v8::internal::Isolate::Current()->stub_cache()->ComputeCallDebugBreak( |
| 414 argc, Code::CALL_IC), |
| 406 Code); | 415 Code); |
| 407 } | 416 } |
| 408 | 417 |
| 409 | 418 |
| 410 // Check that the debugger has been fully unloaded. | 419 // Check that the debugger has been fully unloaded. |
| 411 void CheckDebuggerUnloaded(bool check_functions) { | 420 void CheckDebuggerUnloaded(bool check_functions) { |
| 412 // Check that the debugger context is cleared and that there is no debug | 421 // Check that the debugger context is cleared and that there is no debug |
| 413 // information stored for the debugger. | 422 // information stored for the debugger. |
| 414 CHECK(Debug::debug_context().is_null()); | 423 CHECK(Isolate::Current()->debug()->debug_context().is_null()); |
| 415 CHECK_EQ(NULL, Debug::debug_info_list_); | 424 CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_); |
| 416 | 425 |
| 417 // Collect garbage to ensure weak handles are cleared. | 426 // Collect garbage to ensure weak handles are cleared. |
| 418 Heap::CollectAllGarbage(false); | 427 HEAP->CollectAllGarbage(false); |
| 419 Heap::CollectAllGarbage(false); | 428 HEAP->CollectAllGarbage(false); |
| 420 | 429 |
| 421 // Iterate the head and check that there are no debugger related objects left. | 430 // Iterate the head and check that there are no debugger related objects left. |
| 422 HeapIterator iterator; | 431 HeapIterator iterator; |
| 423 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 432 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 424 CHECK(!obj->IsDebugInfo()); | 433 CHECK(!obj->IsDebugInfo()); |
| 425 CHECK(!obj->IsBreakPointInfo()); | 434 CHECK(!obj->IsBreakPointInfo()); |
| 426 | 435 |
| 427 // If deep check of functions is requested check that no debug break code | 436 // If deep check of functions is requested check that no debug break code |
| 428 // is left in all functions. | 437 // is left in all functions. |
| 429 if (check_functions) { | 438 if (check_functions) { |
| 430 if (obj->IsJSFunction()) { | 439 if (obj->IsJSFunction()) { |
| 431 JSFunction* fun = JSFunction::cast(obj); | 440 JSFunction* fun = JSFunction::cast(obj); |
| 432 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { | 441 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { |
| 433 RelocInfo::Mode rmode = it.rinfo()->rmode(); | 442 RelocInfo::Mode rmode = it.rinfo()->rmode(); |
| 434 if (RelocInfo::IsCodeTarget(rmode)) { | 443 if (RelocInfo::IsCodeTarget(rmode)) { |
| 435 CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address())); | 444 CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address())); |
| 436 } else if (RelocInfo::IsJSReturn(rmode)) { | 445 } else if (RelocInfo::IsJSReturn(rmode)) { |
| 437 CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo())); | 446 CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo())); |
| 438 } | 447 } |
| 439 } | 448 } |
| 440 } | 449 } |
| 441 } | 450 } |
| 442 } | 451 } |
| 443 } | 452 } |
| 444 | 453 |
| 445 | 454 |
| 446 void ForceUnloadDebugger() { | 455 void ForceUnloadDebugger() { |
| 447 Debugger::never_unload_debugger_ = false; | 456 Isolate::Current()->debugger()->never_unload_debugger_ = false; |
| 448 Debugger::UnloadDebugger(); | 457 Isolate::Current()->debugger()->UnloadDebugger(); |
| 449 } | 458 } |
| 450 | 459 |
| 451 | 460 |
| 452 } } // namespace v8::internal | 461 } } // namespace v8::internal |
| 453 | 462 |
| 454 | 463 |
| 455 // Check that the debugger has been fully unloaded. | 464 // Check that the debugger has been fully unloaded. |
| 456 static void CheckDebuggerUnloaded(bool check_functions = false) { | 465 static void CheckDebuggerUnloaded(bool check_functions = false) { |
| 457 // Let debugger to unload itself synchronously | 466 // Let debugger to unload itself synchronously |
| 458 v8::Debug::ProcessDebugMessages(); | 467 v8::Debug::ProcessDebugMessages(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 473 } | 482 } |
| 474 }; | 483 }; |
| 475 | 484 |
| 476 | 485 |
| 477 // Compile a function, set a break point and check that the call at the break | 486 // Compile a function, set a break point and check that the call at the break |
| 478 // location in the code is the expected debug_break function. | 487 // location in the code is the expected debug_break function. |
| 479 void CheckDebugBreakFunction(DebugLocalContext* env, | 488 void CheckDebugBreakFunction(DebugLocalContext* env, |
| 480 const char* source, const char* name, | 489 const char* source, const char* name, |
| 481 int position, v8::internal::RelocInfo::Mode mode, | 490 int position, v8::internal::RelocInfo::Mode mode, |
| 482 Code* debug_break) { | 491 Code* debug_break) { |
| 492 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 493 |
| 483 // Create function and set the break point. | 494 // Create function and set the break point. |
| 484 Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle( | 495 Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle( |
| 485 *CompileFunction(env, source, name)); | 496 *CompileFunction(env, source, name)); |
| 486 int bp = SetBreakPoint(fun, position); | 497 int bp = SetBreakPoint(fun, position); |
| 487 | 498 |
| 488 // Check that the debug break function is as expected. | 499 // Check that the debug break function is as expected. |
| 489 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); | 500 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); |
| 490 CHECK(Debug::HasDebugInfo(shared)); | 501 CHECK(Debug::HasDebugInfo(shared)); |
| 491 TestBreakLocationIterator it1(Debug::GetDebugInfo(shared)); | 502 TestBreakLocationIterator it1(Debug::GetDebugInfo(shared)); |
| 492 it1.FindBreakLocationFromPosition(position); | 503 it1.FindBreakLocationFromPosition(position); |
| 493 CHECK_EQ(mode, it1.it()->rinfo()->rmode()); | 504 CHECK_EQ(mode, it1.it()->rinfo()->rmode()); |
| 494 if (mode != v8::internal::RelocInfo::JS_RETURN) { | 505 if (mode != v8::internal::RelocInfo::JS_RETURN) { |
| 495 CHECK_EQ(debug_break, | 506 CHECK_EQ(debug_break, |
| 496 Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address())); | 507 Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address())); |
| 497 } else { | 508 } else { |
| 498 CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo())); | 509 CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo())); |
| 499 } | 510 } |
| 500 | 511 |
| 501 // Clear the break point and check that the debug break function is no longer | 512 // Clear the break point and check that the debug break function is no longer |
| 502 // there | 513 // there |
| 503 ClearBreakPoint(bp); | 514 ClearBreakPoint(bp); |
| 504 CHECK(!Debug::HasDebugInfo(shared)); | 515 CHECK(!debug->HasDebugInfo(shared)); |
| 505 CHECK(Debug::EnsureDebugInfo(shared)); | 516 CHECK(debug->EnsureDebugInfo(shared)); |
| 506 TestBreakLocationIterator it2(Debug::GetDebugInfo(shared)); | 517 TestBreakLocationIterator it2(Debug::GetDebugInfo(shared)); |
| 507 it2.FindBreakLocationFromPosition(position); | 518 it2.FindBreakLocationFromPosition(position); |
| 508 CHECK_EQ(mode, it2.it()->rinfo()->rmode()); | 519 CHECK_EQ(mode, it2.it()->rinfo()->rmode()); |
| 509 if (mode == v8::internal::RelocInfo::JS_RETURN) { | 520 if (mode == v8::internal::RelocInfo::JS_RETURN) { |
| 510 CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo())); | 521 CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo())); |
| 511 } | 522 } |
| 512 } | 523 } |
| 513 | 524 |
| 514 | 525 |
| 515 // --- D e b u g E v e n t H a n d l e r s | 526 // --- D e b u g E v e n t H a n d l e r s |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 // Global variables to store the last source position - used by some tests. | 638 // Global variables to store the last source position - used by some tests. |
| 628 int last_source_line = -1; | 639 int last_source_line = -1; |
| 629 int last_source_column = -1; | 640 int last_source_column = -1; |
| 630 | 641 |
| 631 // Debug event handler which counts the break points which have been hit. | 642 // Debug event handler which counts the break points which have been hit. |
| 632 int break_point_hit_count = 0; | 643 int break_point_hit_count = 0; |
| 633 static void DebugEventBreakPointHitCount(v8::DebugEvent event, | 644 static void DebugEventBreakPointHitCount(v8::DebugEvent event, |
| 634 v8::Handle<v8::Object> exec_state, | 645 v8::Handle<v8::Object> exec_state, |
| 635 v8::Handle<v8::Object> event_data, | 646 v8::Handle<v8::Object> event_data, |
| 636 v8::Handle<v8::Value> data) { | 647 v8::Handle<v8::Value> data) { |
| 648 Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 637 // When hitting a debug event listener there must be a break set. | 649 // When hitting a debug event listener there must be a break set. |
| 638 CHECK_NE(v8::internal::Debug::break_id(), 0); | 650 CHECK_NE(debug->break_id(), 0); |
| 639 | 651 |
| 640 // Count the number of breaks. | 652 // Count the number of breaks. |
| 641 if (event == v8::Break) { | 653 if (event == v8::Break) { |
| 642 break_point_hit_count++; | 654 break_point_hit_count++; |
| 643 if (!frame_function_name.IsEmpty()) { | 655 if (!frame_function_name.IsEmpty()) { |
| 644 // Get the name of the function. | 656 // Get the name of the function. |
| 645 const int argc = 2; | 657 const int argc = 2; |
| 646 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; | 658 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 647 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 659 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 648 argc, argv); | 660 argc, argv); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 static void DebugEventCounterClear() { | 743 static void DebugEventCounterClear() { |
| 732 break_point_hit_count = 0; | 744 break_point_hit_count = 0; |
| 733 exception_hit_count = 0; | 745 exception_hit_count = 0; |
| 734 uncaught_exception_hit_count = 0; | 746 uncaught_exception_hit_count = 0; |
| 735 } | 747 } |
| 736 | 748 |
| 737 static void DebugEventCounter(v8::DebugEvent event, | 749 static void DebugEventCounter(v8::DebugEvent event, |
| 738 v8::Handle<v8::Object> exec_state, | 750 v8::Handle<v8::Object> exec_state, |
| 739 v8::Handle<v8::Object> event_data, | 751 v8::Handle<v8::Object> event_data, |
| 740 v8::Handle<v8::Value> data) { | 752 v8::Handle<v8::Value> data) { |
| 753 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 754 |
| 741 // When hitting a debug event listener there must be a break set. | 755 // When hitting a debug event listener there must be a break set. |
| 742 CHECK_NE(v8::internal::Debug::break_id(), 0); | 756 CHECK_NE(debug->break_id(), 0); |
| 743 | 757 |
| 744 // Count the number of breaks. | 758 // Count the number of breaks. |
| 745 if (event == v8::Break) { | 759 if (event == v8::Break) { |
| 746 break_point_hit_count++; | 760 break_point_hit_count++; |
| 747 } else if (event == v8::Exception) { | 761 } else if (event == v8::Exception) { |
| 748 exception_hit_count++; | 762 exception_hit_count++; |
| 749 | 763 |
| 750 // Check whether the exception was uncaught. | 764 // Check whether the exception was uncaught. |
| 751 v8::Local<v8::String> fun_name = v8::String::New("uncaught"); | 765 v8::Local<v8::String> fun_name = v8::String::New("uncaught"); |
| 752 v8::Local<v8::Function> fun = | 766 v8::Local<v8::Function> fun = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 "function evaluate_check(exec_state, expr, expected) {" | 803 "function evaluate_check(exec_state, expr, expected) {" |
| 790 " return exec_state.frame(0).evaluate(expr).value() === expected;" | 804 " return exec_state.frame(0).evaluate(expr).value() === expected;" |
| 791 "}"; | 805 "}"; |
| 792 v8::Local<v8::Function> evaluate_check_function; | 806 v8::Local<v8::Function> evaluate_check_function; |
| 793 | 807 |
| 794 // The actual debug event described by the longer comment above. | 808 // The actual debug event described by the longer comment above. |
| 795 static void DebugEventEvaluate(v8::DebugEvent event, | 809 static void DebugEventEvaluate(v8::DebugEvent event, |
| 796 v8::Handle<v8::Object> exec_state, | 810 v8::Handle<v8::Object> exec_state, |
| 797 v8::Handle<v8::Object> event_data, | 811 v8::Handle<v8::Object> event_data, |
| 798 v8::Handle<v8::Value> data) { | 812 v8::Handle<v8::Value> data) { |
| 813 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 799 // When hitting a debug event listener there must be a break set. | 814 // When hitting a debug event listener there must be a break set. |
| 800 CHECK_NE(v8::internal::Debug::break_id(), 0); | 815 CHECK_NE(debug->break_id(), 0); |
| 801 | 816 |
| 802 if (event == v8::Break) { | 817 if (event == v8::Break) { |
| 803 for (int i = 0; checks[i].expr != NULL; i++) { | 818 for (int i = 0; checks[i].expr != NULL; i++) { |
| 804 const int argc = 3; | 819 const int argc = 3; |
| 805 v8::Handle<v8::Value> argv[argc] = { exec_state, | 820 v8::Handle<v8::Value> argv[argc] = { exec_state, |
| 806 v8::String::New(checks[i].expr), | 821 v8::String::New(checks[i].expr), |
| 807 checks[i].expected }; | 822 checks[i].expected }; |
| 808 v8::Handle<v8::Value> result = | 823 v8::Handle<v8::Value> result = |
| 809 evaluate_check_function->Call(exec_state, argc, argv); | 824 evaluate_check_function->Call(exec_state, argc, argv); |
| 810 if (!result->IsTrue()) { | 825 if (!result->IsTrue()) { |
| 811 v8::String::AsciiValue ascii(checks[i].expected->ToString()); | 826 v8::String::AsciiValue ascii(checks[i].expected->ToString()); |
| 812 V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *ascii); | 827 V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *ascii); |
| 813 } | 828 } |
| 814 } | 829 } |
| 815 } | 830 } |
| 816 } | 831 } |
| 817 | 832 |
| 818 | 833 |
| 819 // This debug event listener removes a breakpoint in a function | 834 // This debug event listener removes a breakpoint in a function |
| 820 int debug_event_remove_break_point = 0; | 835 int debug_event_remove_break_point = 0; |
| 821 static void DebugEventRemoveBreakPoint(v8::DebugEvent event, | 836 static void DebugEventRemoveBreakPoint(v8::DebugEvent event, |
| 822 v8::Handle<v8::Object> exec_state, | 837 v8::Handle<v8::Object> exec_state, |
| 823 v8::Handle<v8::Object> event_data, | 838 v8::Handle<v8::Object> event_data, |
| 824 v8::Handle<v8::Value> data) { | 839 v8::Handle<v8::Value> data) { |
| 840 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 825 // When hitting a debug event listener there must be a break set. | 841 // When hitting a debug event listener there must be a break set. |
| 826 CHECK_NE(v8::internal::Debug::break_id(), 0); | 842 CHECK_NE(debug->break_id(), 0); |
| 827 | 843 |
| 828 if (event == v8::Break) { | 844 if (event == v8::Break) { |
| 829 break_point_hit_count++; | 845 break_point_hit_count++; |
| 830 v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(data); | 846 v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(data); |
| 831 ClearBreakPoint(debug_event_remove_break_point); | 847 ClearBreakPoint(debug_event_remove_break_point); |
| 832 } | 848 } |
| 833 } | 849 } |
| 834 | 850 |
| 835 | 851 |
| 836 // Debug event handler which counts break points hit and performs a step | 852 // Debug event handler which counts break points hit and performs a step |
| 837 // afterwards. | 853 // afterwards. |
| 838 StepAction step_action = StepIn; // Step action to perform when stepping. | 854 StepAction step_action = StepIn; // Step action to perform when stepping. |
| 839 static void DebugEventStep(v8::DebugEvent event, | 855 static void DebugEventStep(v8::DebugEvent event, |
| 840 v8::Handle<v8::Object> exec_state, | 856 v8::Handle<v8::Object> exec_state, |
| 841 v8::Handle<v8::Object> event_data, | 857 v8::Handle<v8::Object> event_data, |
| 842 v8::Handle<v8::Value> data) { | 858 v8::Handle<v8::Value> data) { |
| 859 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 843 // When hitting a debug event listener there must be a break set. | 860 // When hitting a debug event listener there must be a break set. |
| 844 CHECK_NE(v8::internal::Debug::break_id(), 0); | 861 CHECK_NE(debug->break_id(), 0); |
| 845 | 862 |
| 846 if (event == v8::Break) { | 863 if (event == v8::Break) { |
| 847 break_point_hit_count++; | 864 break_point_hit_count++; |
| 848 PrepareStep(step_action); | 865 PrepareStep(step_action); |
| 849 } | 866 } |
| 850 } | 867 } |
| 851 | 868 |
| 852 | 869 |
| 853 // Debug event handler which counts break points hit and performs a step | 870 // Debug event handler which counts break points hit and performs a step |
| 854 // afterwards. For each call the expected function is checked. | 871 // afterwards. For each call the expected function is checked. |
| 855 // For this debug event handler to work the following two global varaibles | 872 // For this debug event handler to work the following two global varaibles |
| 856 // must be initialized. | 873 // must be initialized. |
| 857 // expected_step_sequence: An array of the expected function call sequence. | 874 // expected_step_sequence: An array of the expected function call sequence. |
| 858 // frame_function_name: A JavaScript function (see below). | 875 // frame_function_name: A JavaScript function (see below). |
| 859 | 876 |
| 860 // String containing the expected function call sequence. Note: this only works | 877 // String containing the expected function call sequence. Note: this only works |
| 861 // if functions have name length of one. | 878 // if functions have name length of one. |
| 862 const char* expected_step_sequence = NULL; | 879 const char* expected_step_sequence = NULL; |
| 863 | 880 |
| 864 // The actual debug event described by the longer comment above. | 881 // The actual debug event described by the longer comment above. |
| 865 static void DebugEventStepSequence(v8::DebugEvent event, | 882 static void DebugEventStepSequence(v8::DebugEvent event, |
| 866 v8::Handle<v8::Object> exec_state, | 883 v8::Handle<v8::Object> exec_state, |
| 867 v8::Handle<v8::Object> event_data, | 884 v8::Handle<v8::Object> event_data, |
| 868 v8::Handle<v8::Value> data) { | 885 v8::Handle<v8::Value> data) { |
| 886 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 869 // When hitting a debug event listener there must be a break set. | 887 // When hitting a debug event listener there must be a break set. |
| 870 CHECK_NE(v8::internal::Debug::break_id(), 0); | 888 CHECK_NE(debug->break_id(), 0); |
| 871 | 889 |
| 872 if (event == v8::Break || event == v8::Exception) { | 890 if (event == v8::Break || event == v8::Exception) { |
| 873 // Check that the current function is the expected. | 891 // Check that the current function is the expected. |
| 874 CHECK(break_point_hit_count < | 892 CHECK(break_point_hit_count < |
| 875 StrLength(expected_step_sequence)); | 893 StrLength(expected_step_sequence)); |
| 876 const int argc = 2; | 894 const int argc = 2; |
| 877 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; | 895 v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; |
| 878 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 896 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 879 argc, argv); | 897 argc, argv); |
| 880 CHECK(result->IsString()); | 898 CHECK(result->IsString()); |
| 881 v8::String::AsciiValue function_name(result->ToString()); | 899 v8::String::AsciiValue function_name(result->ToString()); |
| 882 CHECK_EQ(1, StrLength(*function_name)); | 900 CHECK_EQ(1, StrLength(*function_name)); |
| 883 CHECK_EQ((*function_name)[0], | 901 CHECK_EQ((*function_name)[0], |
| 884 expected_step_sequence[break_point_hit_count]); | 902 expected_step_sequence[break_point_hit_count]); |
| 885 | 903 |
| 886 // Perform step. | 904 // Perform step. |
| 887 break_point_hit_count++; | 905 break_point_hit_count++; |
| 888 PrepareStep(step_action); | 906 PrepareStep(step_action); |
| 889 } | 907 } |
| 890 } | 908 } |
| 891 | 909 |
| 892 | 910 |
| 893 // Debug event handler which performs a garbage collection. | 911 // Debug event handler which performs a garbage collection. |
| 894 static void DebugEventBreakPointCollectGarbage( | 912 static void DebugEventBreakPointCollectGarbage( |
| 895 v8::DebugEvent event, | 913 v8::DebugEvent event, |
| 896 v8::Handle<v8::Object> exec_state, | 914 v8::Handle<v8::Object> exec_state, |
| 897 v8::Handle<v8::Object> event_data, | 915 v8::Handle<v8::Object> event_data, |
| 898 v8::Handle<v8::Value> data) { | 916 v8::Handle<v8::Value> data) { |
| 917 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 899 // When hitting a debug event listener there must be a break set. | 918 // When hitting a debug event listener there must be a break set. |
| 900 CHECK_NE(v8::internal::Debug::break_id(), 0); | 919 CHECK_NE(debug->break_id(), 0); |
| 901 | 920 |
| 902 // Perform a garbage collection when break point is hit and continue. Based | 921 // 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 | 922 // on the number of break points hit either scavenge or mark compact |
| 904 // collector is used. | 923 // collector is used. |
| 905 if (event == v8::Break) { | 924 if (event == v8::Break) { |
| 906 break_point_hit_count++; | 925 break_point_hit_count++; |
| 907 if (break_point_hit_count % 2 == 0) { | 926 if (break_point_hit_count % 2 == 0) { |
| 908 // Scavenge. | 927 // Scavenge. |
| 909 Heap::CollectGarbage(v8::internal::NEW_SPACE); | 928 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
| 910 } else { | 929 } else { |
| 911 // Mark sweep compact. | 930 // Mark sweep compact. |
| 912 Heap::CollectAllGarbage(true); | 931 HEAP->CollectAllGarbage(true); |
| 913 } | 932 } |
| 914 } | 933 } |
| 915 } | 934 } |
| 916 | 935 |
| 917 | 936 |
| 918 // Debug event handler which re-issues a debug break and calls the garbage | 937 // Debug event handler which re-issues a debug break and calls the garbage |
| 919 // collector to have the heap verified. | 938 // collector to have the heap verified. |
| 920 static void DebugEventBreak(v8::DebugEvent event, | 939 static void DebugEventBreak(v8::DebugEvent event, |
| 921 v8::Handle<v8::Object> exec_state, | 940 v8::Handle<v8::Object> exec_state, |
| 922 v8::Handle<v8::Object> event_data, | 941 v8::Handle<v8::Object> event_data, |
| 923 v8::Handle<v8::Value> data) { | 942 v8::Handle<v8::Value> data) { |
| 943 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 924 // When hitting a debug event listener there must be a break set. | 944 // When hitting a debug event listener there must be a break set. |
| 925 CHECK_NE(v8::internal::Debug::break_id(), 0); | 945 CHECK_NE(debug->break_id(), 0); |
| 926 | 946 |
| 927 if (event == v8::Break) { | 947 if (event == v8::Break) { |
| 928 // Count the number of breaks. | 948 // Count the number of breaks. |
| 929 break_point_hit_count++; | 949 break_point_hit_count++; |
| 930 | 950 |
| 931 // Run the garbage collector to enforce heap verification if option | 951 // Run the garbage collector to enforce heap verification if option |
| 932 // --verify-heap is set. | 952 // --verify-heap is set. |
| 933 Heap::CollectGarbage(v8::internal::NEW_SPACE); | 953 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
| 934 | 954 |
| 935 // Set the break flag again to come back here as soon as possible. | 955 // Set the break flag again to come back here as soon as possible. |
| 936 v8::Debug::DebugBreak(); | 956 v8::Debug::DebugBreak(); |
| 937 } | 957 } |
| 938 } | 958 } |
| 939 | 959 |
| 940 | 960 |
| 941 // Debug event handler which re-issues a debug break until a limit has been | 961 // Debug event handler which re-issues a debug break until a limit has been |
| 942 // reached. | 962 // reached. |
| 943 int max_break_point_hit_count = 0; | 963 int max_break_point_hit_count = 0; |
| 944 bool terminate_after_max_break_point_hit = false; | 964 bool terminate_after_max_break_point_hit = false; |
| 945 static void DebugEventBreakMax(v8::DebugEvent event, | 965 static void DebugEventBreakMax(v8::DebugEvent event, |
| 946 v8::Handle<v8::Object> exec_state, | 966 v8::Handle<v8::Object> exec_state, |
| 947 v8::Handle<v8::Object> event_data, | 967 v8::Handle<v8::Object> event_data, |
| 948 v8::Handle<v8::Value> data) { | 968 v8::Handle<v8::Value> data) { |
| 969 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 949 // When hitting a debug event listener there must be a break set. | 970 // When hitting a debug event listener there must be a break set. |
| 950 CHECK_NE(v8::internal::Debug::break_id(), 0); | 971 CHECK_NE(debug->break_id(), 0); |
| 951 | 972 |
| 952 if (event == v8::Break) { | 973 if (event == v8::Break) { |
| 953 if (break_point_hit_count < max_break_point_hit_count) { | 974 if (break_point_hit_count < max_break_point_hit_count) { |
| 954 // Count the number of breaks. | 975 // Count the number of breaks. |
| 955 break_point_hit_count++; | 976 break_point_hit_count++; |
| 956 | 977 |
| 957 // Set the break flag again to come back here as soon as possible. | 978 // Set the break flag again to come back here as soon as possible. |
| 958 v8::Debug::DebugBreak(); | 979 v8::Debug::DebugBreak(); |
| 959 } else if (terminate_after_max_break_point_hit) { | 980 } else if (terminate_after_max_break_point_hit) { |
| 960 // Terminate execution after the last break if requested. | 981 // Terminate execution after the last break if requested. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 980 } | 1001 } |
| 981 | 1002 |
| 982 | 1003 |
| 983 // --- T h e A c t u a l T e s t s | 1004 // --- T h e A c t u a l T e s t s |
| 984 | 1005 |
| 985 | 1006 |
| 986 // Test that the debug break function is the expected one for different kinds | 1007 // Test that the debug break function is the expected one for different kinds |
| 987 // of break locations. | 1008 // of break locations. |
| 988 TEST(DebugStub) { | 1009 TEST(DebugStub) { |
| 989 using ::v8::internal::Builtins; | 1010 using ::v8::internal::Builtins; |
| 1011 using ::v8::internal::Isolate; |
| 990 v8::HandleScope scope; | 1012 v8::HandleScope scope; |
| 991 DebugLocalContext env; | 1013 DebugLocalContext env; |
| 992 | 1014 |
| 993 CheckDebugBreakFunction(&env, | 1015 CheckDebugBreakFunction(&env, |
| 994 "function f1(){}", "f1", | 1016 "function f1(){}", "f1", |
| 995 0, | 1017 0, |
| 996 v8::internal::RelocInfo::JS_RETURN, | 1018 v8::internal::RelocInfo::JS_RETURN, |
| 997 NULL); | 1019 NULL); |
| 998 CheckDebugBreakFunction(&env, | 1020 CheckDebugBreakFunction(&env, |
| 999 "function f2(){x=1;}", "f2", | 1021 "function f2(){x=1;}", "f2", |
| 1000 0, | 1022 0, |
| 1001 v8::internal::RelocInfo::CODE_TARGET_CONTEXT, | 1023 v8::internal::RelocInfo::CODE_TARGET_CONTEXT, |
| 1002 Builtins::builtin(Builtins::StoreIC_DebugBreak)); | 1024 Isolate::Current()->builtins()->builtin( |
| 1025 Builtins::StoreIC_DebugBreak)); |
| 1003 CheckDebugBreakFunction(&env, | 1026 CheckDebugBreakFunction(&env, |
| 1004 "function f3(){var a=x;}", "f3", | 1027 "function f3(){var a=x;}", "f3", |
| 1005 0, | 1028 0, |
| 1006 v8::internal::RelocInfo::CODE_TARGET_CONTEXT, | 1029 v8::internal::RelocInfo::CODE_TARGET_CONTEXT, |
| 1007 Builtins::builtin(Builtins::LoadIC_DebugBreak)); | 1030 Isolate::Current()->builtins()->builtin( |
| 1031 Builtins::LoadIC_DebugBreak)); |
| 1008 | 1032 |
| 1009 // TODO(1240753): Make the test architecture independent or split | 1033 // TODO(1240753): Make the test architecture independent or split |
| 1010 // parts of the debugger into architecture dependent files. This | 1034 // parts of the debugger into architecture dependent files. This |
| 1011 // part currently disabled as it is not portable between IA32/ARM. | 1035 // part currently disabled as it is not portable between IA32/ARM. |
| 1012 // Currently on ICs for keyed store/load on ARM. | 1036 // Currently on ICs for keyed store/load on ARM. |
| 1013 #if !defined (__arm__) && !defined(__thumb__) | 1037 #if !defined (__arm__) && !defined(__thumb__) |
| 1014 CheckDebugBreakFunction( | 1038 CheckDebugBreakFunction( |
| 1015 &env, | 1039 &env, |
| 1016 "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}", | 1040 "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}", |
| 1017 "f4", | 1041 "f4", |
| 1018 0, | 1042 0, |
| 1019 v8::internal::RelocInfo::CODE_TARGET, | 1043 v8::internal::RelocInfo::CODE_TARGET, |
| 1020 Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak)); | 1044 Isolate::Current()->builtins()->builtin( |
| 1045 Builtins::KeyedStoreIC_DebugBreak)); |
| 1021 CheckDebugBreakFunction( | 1046 CheckDebugBreakFunction( |
| 1022 &env, | 1047 &env, |
| 1023 "function f5(){var index='propertyName'; var a={}; return a[index];}", | 1048 "function f5(){var index='propertyName'; var a={}; return a[index];}", |
| 1024 "f5", | 1049 "f5", |
| 1025 0, | 1050 0, |
| 1026 v8::internal::RelocInfo::CODE_TARGET, | 1051 v8::internal::RelocInfo::CODE_TARGET, |
| 1027 Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak)); | 1052 Isolate::Current()->builtins()->builtin( |
| 1053 Builtins::KeyedLoadIC_DebugBreak)); |
| 1028 #endif | 1054 #endif |
| 1029 | 1055 |
| 1030 // Check the debug break code stubs for call ICs with different number of | 1056 // Check the debug break code stubs for call ICs with different number of |
| 1031 // parameters. | 1057 // parameters. |
| 1032 Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); | 1058 Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); |
| 1033 Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); | 1059 Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); |
| 1034 Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); | 1060 Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); |
| 1035 | 1061 |
| 1036 CheckDebugBreakFunction(&env, | 1062 CheckDebugBreakFunction(&env, |
| 1037 "function f4_0(){x();}", "f4_0", | 1063 "function f4_0(){x();}", "f4_0", |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 v8::Undefined()); | 1158 v8::Undefined()); |
| 1133 v8::Script::Compile(v8::String::New("bar=1"))->Run(); | 1159 v8::Script::Compile(v8::String::New("bar=1"))->Run(); |
| 1134 v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run(); | 1160 v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run(); |
| 1135 v8::Local<v8::Function> foo = | 1161 v8::Local<v8::Function> foo = |
| 1136 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); | 1162 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); |
| 1137 | 1163 |
| 1138 // Run without breakpoints. | 1164 // Run without breakpoints. |
| 1139 foo->Call(env->Global(), 0, NULL); | 1165 foo->Call(env->Global(), 0, NULL); |
| 1140 CHECK_EQ(0, break_point_hit_count); | 1166 CHECK_EQ(0, break_point_hit_count); |
| 1141 | 1167 |
| 1142 // Run with breakpoint | 1168 // Run with breakpoint. |
| 1143 int bp = SetBreakPoint(foo, 0); | 1169 int bp = SetBreakPoint(foo, 0); |
| 1144 foo->Call(env->Global(), 0, NULL); | 1170 foo->Call(env->Global(), 0, NULL); |
| 1145 CHECK_EQ(1, break_point_hit_count); | 1171 CHECK_EQ(1, break_point_hit_count); |
| 1146 foo->Call(env->Global(), 0, NULL); | 1172 foo->Call(env->Global(), 0, NULL); |
| 1147 CHECK_EQ(2, break_point_hit_count); | 1173 CHECK_EQ(2, break_point_hit_count); |
| 1148 | 1174 |
| 1149 // Run without breakpoints. | 1175 // Run without breakpoints. |
| 1150 ClearBreakPoint(bp); | 1176 ClearBreakPoint(bp); |
| 1151 foo->Call(env->Global(), 0, NULL); | 1177 foo->Call(env->Global(), 0, NULL); |
| 1152 CHECK_EQ(2, break_point_hit_count); | 1178 CHECK_EQ(2, break_point_hit_count); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1165 v8::Undefined()); | 1191 v8::Undefined()); |
| 1166 v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); | 1192 v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); |
| 1167 v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run(); | 1193 v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run(); |
| 1168 v8::Local<v8::Function> foo = | 1194 v8::Local<v8::Function> foo = |
| 1169 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); | 1195 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); |
| 1170 | 1196 |
| 1171 // Run without breakpoints. | 1197 // Run without breakpoints. |
| 1172 foo->Call(env->Global(), 0, NULL); | 1198 foo->Call(env->Global(), 0, NULL); |
| 1173 CHECK_EQ(0, break_point_hit_count); | 1199 CHECK_EQ(0, break_point_hit_count); |
| 1174 | 1200 |
| 1175 // Run with breakpoint. | 1201 // Run with breakpoint |
| 1176 int bp = SetBreakPoint(foo, 0); | 1202 int bp = SetBreakPoint(foo, 0); |
| 1177 foo->Call(env->Global(), 0, NULL); | 1203 foo->Call(env->Global(), 0, NULL); |
| 1178 CHECK_EQ(1, break_point_hit_count); | 1204 CHECK_EQ(1, break_point_hit_count); |
| 1179 foo->Call(env->Global(), 0, NULL); | 1205 foo->Call(env->Global(), 0, NULL); |
| 1180 CHECK_EQ(2, break_point_hit_count); | 1206 CHECK_EQ(2, break_point_hit_count); |
| 1181 | 1207 |
| 1182 // Run without breakpoints. | 1208 // Run without breakpoints. |
| 1183 ClearBreakPoint(bp); | 1209 ClearBreakPoint(bp); |
| 1184 foo->Call(env->Global(), 0, NULL); | 1210 foo->Call(env->Global(), 0, NULL); |
| 1185 CHECK_EQ(2, break_point_hit_count); | 1211 CHECK_EQ(2, break_point_hit_count); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 v8::Local<v8::Function> f, | 1386 v8::Local<v8::Function> f, |
| 1361 bool force_compaction) { | 1387 bool force_compaction) { |
| 1362 break_point_hit_count = 0; | 1388 break_point_hit_count = 0; |
| 1363 | 1389 |
| 1364 for (int i = 0; i < 3; i++) { | 1390 for (int i = 0; i < 3; i++) { |
| 1365 // Call function. | 1391 // Call function. |
| 1366 f->Call(recv, 0, NULL); | 1392 f->Call(recv, 0, NULL); |
| 1367 CHECK_EQ(1 + i * 3, break_point_hit_count); | 1393 CHECK_EQ(1 + i * 3, break_point_hit_count); |
| 1368 | 1394 |
| 1369 // Scavenge and call function. | 1395 // Scavenge and call function. |
| 1370 Heap::CollectGarbage(v8::internal::NEW_SPACE); | 1396 HEAP->CollectGarbage(v8::internal::NEW_SPACE); |
| 1371 f->Call(recv, 0, NULL); | 1397 f->Call(recv, 0, NULL); |
| 1372 CHECK_EQ(2 + i * 3, break_point_hit_count); | 1398 CHECK_EQ(2 + i * 3, break_point_hit_count); |
| 1373 | 1399 |
| 1374 // Mark sweep (and perhaps compact) and call function. | 1400 // Mark sweep (and perhaps compact) and call function. |
| 1375 Heap::CollectAllGarbage(force_compaction); | 1401 HEAP->CollectAllGarbage(force_compaction); |
| 1376 f->Call(recv, 0, NULL); | 1402 f->Call(recv, 0, NULL); |
| 1377 CHECK_EQ(3 + i * 3, break_point_hit_count); | 1403 CHECK_EQ(3 + i * 3, break_point_hit_count); |
| 1378 } | 1404 } |
| 1379 } | 1405 } |
| 1380 | 1406 |
| 1381 | 1407 |
| 1382 static void TestBreakPointSurviveGC(bool force_compaction) { | 1408 static void TestBreakPointSurviveGC(bool force_compaction) { |
| 1383 break_point_hit_count = 0; | 1409 break_point_hit_count = 0; |
| 1384 v8::HandleScope scope; | 1410 v8::HandleScope scope; |
| 1385 DebugLocalContext env; | 1411 DebugLocalContext env; |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2192 " a = 1; // line 1\n" | 2218 " a = 1; // line 1\n" |
| 2193 "}\n" | 2219 "}\n" |
| 2194 "a = 2; // line 3\n"); | 2220 "a = 2; // line 3\n"); |
| 2195 v8::Local<v8::Function> f; | 2221 v8::Local<v8::Function> f; |
| 2196 { | 2222 { |
| 2197 v8::HandleScope scope; | 2223 v8::HandleScope scope; |
| 2198 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); | 2224 v8::Script::Compile(script, v8::String::New("test.html"))->Run(); |
| 2199 } | 2225 } |
| 2200 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); | 2226 f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
| 2201 | 2227 |
| 2202 Heap::CollectAllGarbage(false); | 2228 HEAP->CollectAllGarbage(false); |
| 2203 | 2229 |
| 2204 SetScriptBreakPointByNameFromJS("test.html", 3, -1); | 2230 SetScriptBreakPointByNameFromJS("test.html", 3, -1); |
| 2205 | 2231 |
| 2206 // Call f and check that there was no break points. | 2232 // Call f and check that there was no break points. |
| 2207 break_point_hit_count = 0; | 2233 break_point_hit_count = 0; |
| 2208 f->Call(env->Global(), 0, NULL); | 2234 f->Call(env->Global(), 0, NULL); |
| 2209 CHECK_EQ(0, break_point_hit_count); | 2235 CHECK_EQ(0, break_point_hit_count); |
| 2210 | 2236 |
| 2211 // Recompile and run script and check that break point was hit. | 2237 // Recompile and run script and check that break point was hit. |
| 2212 break_point_hit_count = 0; | 2238 break_point_hit_count = 0; |
| (...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3691 // of debug event exception callbacks and message callbacks are collected. The | 3717 // of debug event exception callbacks and message callbacks are collected. The |
| 3692 // number of debug event exception callbacks are used to check that the | 3718 // number of debug event exception callbacks are used to check that the |
| 3693 // debugger is called correctly and the number of message callbacks is used to | 3719 // debugger is called correctly and the number of message callbacks is used to |
| 3694 // check that uncaught exceptions are still returned even if there is a break | 3720 // check that uncaught exceptions are still returned even if there is a break |
| 3695 // for them. | 3721 // for them. |
| 3696 TEST(BreakOnException) { | 3722 TEST(BreakOnException) { |
| 3697 v8::HandleScope scope; | 3723 v8::HandleScope scope; |
| 3698 DebugLocalContext env; | 3724 DebugLocalContext env; |
| 3699 env.ExposeDebug(); | 3725 env.ExposeDebug(); |
| 3700 | 3726 |
| 3701 v8::internal::Top::TraceException(false); | 3727 v8::internal::Isolate::Current()->TraceException(false); |
| 3702 | 3728 |
| 3703 // Create functions for testing break on exception. | 3729 // Create functions for testing break on exception. |
| 3704 v8::Local<v8::Function> throws = | 3730 v8::Local<v8::Function> throws = |
| 3705 CompileFunction(&env, "function throws(){throw 1;}", "throws"); | 3731 CompileFunction(&env, "function throws(){throw 1;}", "throws"); |
| 3706 v8::Local<v8::Function> caught = | 3732 v8::Local<v8::Function> caught = |
| 3707 CompileFunction(&env, | 3733 CompileFunction(&env, |
| 3708 "function caught(){try {throws();} catch(e) {};}", | 3734 "function caught(){try {throws();} catch(e) {};}", |
| 3709 "caught"); | 3735 "caught"); |
| 3710 v8::Local<v8::Function> notCaught = | 3736 v8::Local<v8::Function> notCaught = |
| 3711 CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); | 3737 CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3838 // Test break on exception from compiler errors. When compiling using | 3864 // Test break on exception from compiler errors. When compiling using |
| 3839 // v8::Script::Compile there is no JavaScript stack whereas when compiling using | 3865 // v8::Script::Compile there is no JavaScript stack whereas when compiling using |
| 3840 // eval there are JavaScript frames. | 3866 // eval there are JavaScript frames. |
| 3841 TEST(BreakOnCompileException) { | 3867 TEST(BreakOnCompileException) { |
| 3842 v8::HandleScope scope; | 3868 v8::HandleScope scope; |
| 3843 DebugLocalContext env; | 3869 DebugLocalContext env; |
| 3844 | 3870 |
| 3845 // For this test, we want to break on uncaught exceptions: | 3871 // For this test, we want to break on uncaught exceptions: |
| 3846 ChangeBreakOnException(false, true); | 3872 ChangeBreakOnException(false, true); |
| 3847 | 3873 |
| 3848 v8::internal::Top::TraceException(false); | 3874 v8::internal::Isolate::Current()->TraceException(false); |
| 3849 | 3875 |
| 3850 // Create a function for checking the function when hitting a break point. | 3876 // Create a function for checking the function when hitting a break point. |
| 3851 frame_count = CompileFunction(&env, frame_count_source, "frame_count"); | 3877 frame_count = CompileFunction(&env, frame_count_source, "frame_count"); |
| 3852 | 3878 |
| 3853 v8::V8::AddMessageListener(MessageCallbackCount); | 3879 v8::V8::AddMessageListener(MessageCallbackCount); |
| 3854 v8::Debug::SetDebugEventListener(DebugEventCounter); | 3880 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 3855 | 3881 |
| 3856 DebugEventCounterClear(); | 3882 DebugEventCounterClear(); |
| 3857 MessageCallbackCountClear(); | 3883 MessageCallbackCountClear(); |
| 3858 | 3884 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4687 /* Tests the message queues that hold debugger commands and | 4713 /* Tests the message queues that hold debugger commands and |
| 4688 * response messages to the debugger. Fills queues and makes | 4714 * response messages to the debugger. Fills queues and makes |
| 4689 * them grow. | 4715 * them grow. |
| 4690 */ | 4716 */ |
| 4691 Barriers message_queue_barriers; | 4717 Barriers message_queue_barriers; |
| 4692 | 4718 |
| 4693 // This is the debugger thread, that executes no v8 calls except | 4719 // This is the debugger thread, that executes no v8 calls except |
| 4694 // placing JSON debugger commands in the queue. | 4720 // placing JSON debugger commands in the queue. |
| 4695 class MessageQueueDebuggerThread : public v8::internal::Thread { | 4721 class MessageQueueDebuggerThread : public v8::internal::Thread { |
| 4696 public: | 4722 public: |
| 4723 explicit MessageQueueDebuggerThread(v8::internal::Isolate* isolate) |
| 4724 : Thread(isolate) { } |
| 4697 void Run(); | 4725 void Run(); |
| 4698 }; | 4726 }; |
| 4699 | 4727 |
| 4700 static void MessageHandler(const uint16_t* message, int length, | 4728 static void MessageHandler(const uint16_t* message, int length, |
| 4701 v8::Debug::ClientData* client_data) { | 4729 v8::Debug::ClientData* client_data) { |
| 4702 static char print_buffer[1000]; | 4730 static char print_buffer[1000]; |
| 4703 Utf16ToAscii(message, length, print_buffer); | 4731 Utf16ToAscii(message, length, print_buffer); |
| 4704 if (IsBreakEventMessage(print_buffer)) { | 4732 if (IsBreakEventMessage(print_buffer)) { |
| 4705 // Lets test script wait until break occurs to send commands. | 4733 // Lets test script wait until break occurs to send commands. |
| 4706 // Signals when a break is reported. | 4734 // Signals when a break is reported. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4786 message_queue_barriers.semaphore_2->Wait(); | 4814 message_queue_barriers.semaphore_2->Wait(); |
| 4787 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); | 4815 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); |
| 4788 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); | 4816 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); |
| 4789 // Run after 2 responses. | 4817 // Run after 2 responses. |
| 4790 for (int i = 0; i < 2 ; ++i) { | 4818 for (int i = 0; i < 2 ; ++i) { |
| 4791 message_queue_barriers.semaphore_1->Signal(); | 4819 message_queue_barriers.semaphore_1->Signal(); |
| 4792 } | 4820 } |
| 4793 // Main thread continues running source_3 to end, waits for this thread. | 4821 // Main thread continues running source_3 to end, waits for this thread. |
| 4794 } | 4822 } |
| 4795 | 4823 |
| 4796 MessageQueueDebuggerThread message_queue_debugger_thread; | |
| 4797 | 4824 |
| 4798 // This thread runs the v8 engine. | 4825 // This thread runs the v8 engine. |
| 4799 TEST(MessageQueues) { | 4826 TEST(MessageQueues) { |
| 4827 MessageQueueDebuggerThread message_queue_debugger_thread( |
| 4828 i::Isolate::Current()); |
| 4829 |
| 4800 // Create a V8 environment | 4830 // Create a V8 environment |
| 4801 v8::HandleScope scope; | 4831 v8::HandleScope scope; |
| 4802 DebugLocalContext env; | 4832 DebugLocalContext env; |
| 4803 message_queue_barriers.Initialize(); | 4833 message_queue_barriers.Initialize(); |
| 4804 v8::Debug::SetMessageHandler(MessageHandler); | 4834 v8::Debug::SetMessageHandler(MessageHandler); |
| 4805 message_queue_debugger_thread.Start(); | 4835 message_queue_debugger_thread.Start(); |
| 4806 | 4836 |
| 4807 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; | 4837 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; |
| 4808 const char* source_2 = "e = 17;"; | 4838 const char* source_2 = "e = 17;"; |
| 4809 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; | 4839 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4935 /* This test interrupts a running infinite loop that is | 4965 /* This test interrupts a running infinite loop that is |
| 4936 * occupying the v8 thread by a break command from the | 4966 * occupying the v8 thread by a break command from the |
| 4937 * debugger thread. It then changes the value of a | 4967 * debugger thread. It then changes the value of a |
| 4938 * global object, to make the loop terminate. | 4968 * global object, to make the loop terminate. |
| 4939 */ | 4969 */ |
| 4940 | 4970 |
| 4941 Barriers threaded_debugging_barriers; | 4971 Barriers threaded_debugging_barriers; |
| 4942 | 4972 |
| 4943 class V8Thread : public v8::internal::Thread { | 4973 class V8Thread : public v8::internal::Thread { |
| 4944 public: | 4974 public: |
| 4975 explicit V8Thread(v8::internal::Isolate* isolate) : Thread(isolate) { } |
| 4945 void Run(); | 4976 void Run(); |
| 4946 }; | 4977 }; |
| 4947 | 4978 |
| 4948 class DebuggerThread : public v8::internal::Thread { | 4979 class DebuggerThread : public v8::internal::Thread { |
| 4949 public: | 4980 public: |
| 4981 explicit DebuggerThread(v8::internal::Isolate* isolate) : Thread(isolate) { } |
| 4950 void Run(); | 4982 void Run(); |
| 4951 }; | 4983 }; |
| 4952 | 4984 |
| 4953 | 4985 |
| 4954 static v8::Handle<v8::Value> ThreadedAtBarrier1(const v8::Arguments& args) { | 4986 static v8::Handle<v8::Value> ThreadedAtBarrier1(const v8::Arguments& args) { |
| 4955 threaded_debugging_barriers.barrier_1.Wait(); | 4987 threaded_debugging_barriers.barrier_1.Wait(); |
| 4956 return v8::Undefined(); | 4988 return v8::Undefined(); |
| 4957 } | 4989 } |
| 4958 | 4990 |
| 4959 | 4991 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5014 "\"type\":\"request\"," | 5046 "\"type\":\"request\"," |
| 5015 "\"command\":\"continue\"}"; | 5047 "\"command\":\"continue\"}"; |
| 5016 | 5048 |
| 5017 threaded_debugging_barriers.barrier_1.Wait(); | 5049 threaded_debugging_barriers.barrier_1.Wait(); |
| 5018 v8::Debug::DebugBreak(); | 5050 v8::Debug::DebugBreak(); |
| 5019 threaded_debugging_barriers.barrier_2.Wait(); | 5051 threaded_debugging_barriers.barrier_2.Wait(); |
| 5020 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5052 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
| 5021 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5053 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
| 5022 } | 5054 } |
| 5023 | 5055 |
| 5024 DebuggerThread debugger_thread; | |
| 5025 V8Thread v8_thread; | |
| 5026 | 5056 |
| 5027 TEST(ThreadedDebugging) { | 5057 TEST(ThreadedDebugging) { |
| 5058 DebuggerThread debugger_thread(i::Isolate::Current()); |
| 5059 V8Thread v8_thread(i::Isolate::Current()); |
| 5060 |
| 5028 // Create a V8 environment | 5061 // Create a V8 environment |
| 5029 threaded_debugging_barriers.Initialize(); | 5062 threaded_debugging_barriers.Initialize(); |
| 5030 | 5063 |
| 5031 v8_thread.Start(); | 5064 v8_thread.Start(); |
| 5032 debugger_thread.Start(); | 5065 debugger_thread.Start(); |
| 5033 | 5066 |
| 5034 v8_thread.Join(); | 5067 v8_thread.Join(); |
| 5035 debugger_thread.Join(); | 5068 debugger_thread.Join(); |
| 5036 } | 5069 } |
| 5037 | 5070 |
| 5038 /* Test RecursiveBreakpoints */ | 5071 /* Test RecursiveBreakpoints */ |
| 5039 /* In this test, the debugger evaluates a function with a breakpoint, after | 5072 /* In this test, the debugger evaluates a function with a breakpoint, after |
| 5040 * hitting a breakpoint in another function. We do this with both values | 5073 * hitting a breakpoint in another function. We do this with both values |
| 5041 * of the flag enabling recursive breakpoints, and verify that the second | 5074 * of the flag enabling recursive breakpoints, and verify that the second |
| 5042 * breakpoint is hit when enabled, and missed when disabled. | 5075 * breakpoint is hit when enabled, and missed when disabled. |
| 5043 */ | 5076 */ |
| 5044 | 5077 |
| 5045 class BreakpointsV8Thread : public v8::internal::Thread { | 5078 class BreakpointsV8Thread : public v8::internal::Thread { |
| 5046 public: | 5079 public: |
| 5080 explicit BreakpointsV8Thread(v8::internal::Isolate* isolate) |
| 5081 : Thread(isolate) { } |
| 5047 void Run(); | 5082 void Run(); |
| 5048 }; | 5083 }; |
| 5049 | 5084 |
| 5050 class BreakpointsDebuggerThread : public v8::internal::Thread { | 5085 class BreakpointsDebuggerThread : public v8::internal::Thread { |
| 5051 public: | 5086 public: |
| 5052 explicit BreakpointsDebuggerThread(bool global_evaluate) | 5087 explicit BreakpointsDebuggerThread(v8::internal::Isolate* isolate, |
| 5053 : global_evaluate_(global_evaluate) {} | 5088 bool global_evaluate) |
| 5089 : Thread(isolate), global_evaluate_(global_evaluate) {} |
| 5054 void Run(); | 5090 void Run(); |
| 5055 | 5091 |
| 5056 private: | 5092 private: |
| 5057 bool global_evaluate_; | 5093 bool global_evaluate_; |
| 5058 }; | 5094 }; |
| 5059 | 5095 |
| 5060 | 5096 |
| 5061 Barriers* breakpoints_barriers; | 5097 Barriers* breakpoints_barriers; |
| 5062 int break_event_breakpoint_id; | 5098 int break_event_breakpoint_id; |
| 5063 int evaluate_int_result; | 5099 int evaluate_int_result; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5219 breakpoints_barriers->semaphore_1->Wait(); | 5255 breakpoints_barriers->semaphore_1->Wait(); |
| 5220 // Must have result 116. | 5256 // Must have result 116. |
| 5221 CHECK_EQ(116, evaluate_int_result); | 5257 CHECK_EQ(116, evaluate_int_result); |
| 5222 // 9: Continue evaluation of source2, reach end. | 5258 // 9: Continue evaluation of source2, reach end. |
| 5223 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); | 5259 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); |
| 5224 } | 5260 } |
| 5225 | 5261 |
| 5226 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { | 5262 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { |
| 5227 i::FLAG_debugger_auto_break = true; | 5263 i::FLAG_debugger_auto_break = true; |
| 5228 | 5264 |
| 5229 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); | 5265 BreakpointsDebuggerThread breakpoints_debugger_thread(i::Isolate::Current(), |
| 5230 BreakpointsV8Thread breakpoints_v8_thread; | 5266 global_evaluate); |
| 5267 BreakpointsV8Thread breakpoints_v8_thread(i::Isolate::Current()); |
| 5231 | 5268 |
| 5232 // Create a V8 environment | 5269 // Create a V8 environment |
| 5233 Barriers stack_allocated_breakpoints_barriers; | 5270 Barriers stack_allocated_breakpoints_barriers; |
| 5234 stack_allocated_breakpoints_barriers.Initialize(); | 5271 stack_allocated_breakpoints_barriers.Initialize(); |
| 5235 breakpoints_barriers = &stack_allocated_breakpoints_barriers; | 5272 breakpoints_barriers = &stack_allocated_breakpoints_barriers; |
| 5236 | 5273 |
| 5237 breakpoints_v8_thread.Start(); | 5274 breakpoints_v8_thread.Start(); |
| 5238 breakpoints_debugger_thread.Start(); | 5275 breakpoints_debugger_thread.Start(); |
| 5239 | 5276 |
| 5240 breakpoints_v8_thread.Join(); | 5277 breakpoints_v8_thread.Join(); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5602 } | 5639 } |
| 5603 | 5640 |
| 5604 | 5641 |
| 5605 /* Test DebuggerHostDispatch */ | 5642 /* Test DebuggerHostDispatch */ |
| 5606 /* In this test, the debugger waits for a command on a breakpoint | 5643 /* In this test, the debugger waits for a command on a breakpoint |
| 5607 * and is dispatching host commands while in the infinite loop. | 5644 * and is dispatching host commands while in the infinite loop. |
| 5608 */ | 5645 */ |
| 5609 | 5646 |
| 5610 class HostDispatchV8Thread : public v8::internal::Thread { | 5647 class HostDispatchV8Thread : public v8::internal::Thread { |
| 5611 public: | 5648 public: |
| 5649 explicit HostDispatchV8Thread(v8::internal::Isolate* isolate) |
| 5650 : Thread(isolate) { } |
| 5612 void Run(); | 5651 void Run(); |
| 5613 }; | 5652 }; |
| 5614 | 5653 |
| 5615 class HostDispatchDebuggerThread : public v8::internal::Thread { | 5654 class HostDispatchDebuggerThread : public v8::internal::Thread { |
| 5616 public: | 5655 public: |
| 5656 explicit HostDispatchDebuggerThread(v8::internal::Isolate* isolate) |
| 5657 : Thread(isolate) { } |
| 5617 void Run(); | 5658 void Run(); |
| 5618 }; | 5659 }; |
| 5619 | 5660 |
| 5620 Barriers* host_dispatch_barriers; | 5661 Barriers* host_dispatch_barriers; |
| 5621 | 5662 |
| 5622 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { | 5663 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { |
| 5623 static char print_buffer[1000]; | 5664 static char print_buffer[1000]; |
| 5624 v8::String::Value json(message.GetJSON()); | 5665 v8::String::Value json(message.GetJSON()); |
| 5625 Utf16ToAscii(*json, json.length(), print_buffer); | 5666 Utf16ToAscii(*json, json.length(), print_buffer); |
| 5626 } | 5667 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5676 | 5717 |
| 5677 host_dispatch_barriers->barrier_2.Wait(); | 5718 host_dispatch_barriers->barrier_2.Wait(); |
| 5678 // v8 thread starts compiling source_2. | 5719 // v8 thread starts compiling source_2. |
| 5679 // Break happens, to run queued commands and host dispatches. | 5720 // Break happens, to run queued commands and host dispatches. |
| 5680 // Wait for host dispatch to be processed. | 5721 // Wait for host dispatch to be processed. |
| 5681 host_dispatch_barriers->semaphore_1->Wait(); | 5722 host_dispatch_barriers->semaphore_1->Wait(); |
| 5682 // 2: Continue evaluation | 5723 // 2: Continue evaluation |
| 5683 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5724 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
| 5684 } | 5725 } |
| 5685 | 5726 |
| 5686 HostDispatchDebuggerThread host_dispatch_debugger_thread; | |
| 5687 HostDispatchV8Thread host_dispatch_v8_thread; | |
| 5688 | |
| 5689 | 5727 |
| 5690 TEST(DebuggerHostDispatch) { | 5728 TEST(DebuggerHostDispatch) { |
| 5729 HostDispatchDebuggerThread host_dispatch_debugger_thread( |
| 5730 i::Isolate::Current()); |
| 5731 HostDispatchV8Thread host_dispatch_v8_thread(i::Isolate::Current()); |
| 5691 i::FLAG_debugger_auto_break = true; | 5732 i::FLAG_debugger_auto_break = true; |
| 5692 | 5733 |
| 5693 // Create a V8 environment | 5734 // Create a V8 environment |
| 5694 Barriers stack_allocated_host_dispatch_barriers; | 5735 Barriers stack_allocated_host_dispatch_barriers; |
| 5695 stack_allocated_host_dispatch_barriers.Initialize(); | 5736 stack_allocated_host_dispatch_barriers.Initialize(); |
| 5696 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; | 5737 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; |
| 5697 | 5738 |
| 5698 host_dispatch_v8_thread.Start(); | 5739 host_dispatch_v8_thread.Start(); |
| 5699 host_dispatch_debugger_thread.Start(); | 5740 host_dispatch_debugger_thread.Start(); |
| 5700 | 5741 |
| 5701 host_dispatch_v8_thread.Join(); | 5742 host_dispatch_v8_thread.Join(); |
| 5702 host_dispatch_debugger_thread.Join(); | 5743 host_dispatch_debugger_thread.Join(); |
| 5703 } | 5744 } |
| 5704 | 5745 |
| 5705 | 5746 |
| 5706 /* Test DebugMessageDispatch */ | 5747 /* Test DebugMessageDispatch */ |
| 5707 /* In this test, the V8 thread waits for a message from the debug thread. | 5748 /* In this test, the V8 thread waits for a message from the debug thread. |
| 5708 * The DebugMessageDispatchHandler is executed from the debugger thread | 5749 * The DebugMessageDispatchHandler is executed from the debugger thread |
| 5709 * which signals the V8 thread to wake up. | 5750 * which signals the V8 thread to wake up. |
| 5710 */ | 5751 */ |
| 5711 | 5752 |
| 5712 class DebugMessageDispatchV8Thread : public v8::internal::Thread { | 5753 class DebugMessageDispatchV8Thread : public v8::internal::Thread { |
| 5713 public: | 5754 public: |
| 5755 explicit DebugMessageDispatchV8Thread(v8::internal::Isolate* isolate) |
| 5756 : Thread(isolate) { } |
| 5714 void Run(); | 5757 void Run(); |
| 5715 }; | 5758 }; |
| 5716 | 5759 |
| 5717 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread { | 5760 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread { |
| 5718 public: | 5761 public: |
| 5762 explicit DebugMessageDispatchDebuggerThread(v8::internal::Isolate* isolate) |
| 5763 : Thread(isolate) { } |
| 5719 void Run(); | 5764 void Run(); |
| 5720 }; | 5765 }; |
| 5721 | 5766 |
| 5722 Barriers* debug_message_dispatch_barriers; | 5767 Barriers* debug_message_dispatch_barriers; |
| 5723 | 5768 |
| 5724 | 5769 |
| 5725 static void DebugMessageHandler() { | 5770 static void DebugMessageHandler() { |
| 5726 debug_message_dispatch_barriers->semaphore_1->Signal(); | 5771 debug_message_dispatch_barriers->semaphore_1->Signal(); |
| 5727 } | 5772 } |
| 5728 | 5773 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5740 debug_message_dispatch_barriers->barrier_2.Wait(); | 5785 debug_message_dispatch_barriers->barrier_2.Wait(); |
| 5741 } | 5786 } |
| 5742 | 5787 |
| 5743 | 5788 |
| 5744 void DebugMessageDispatchDebuggerThread::Run() { | 5789 void DebugMessageDispatchDebuggerThread::Run() { |
| 5745 debug_message_dispatch_barriers->barrier_1.Wait(); | 5790 debug_message_dispatch_barriers->barrier_1.Wait(); |
| 5746 SendContinueCommand(); | 5791 SendContinueCommand(); |
| 5747 debug_message_dispatch_barriers->barrier_2.Wait(); | 5792 debug_message_dispatch_barriers->barrier_2.Wait(); |
| 5748 } | 5793 } |
| 5749 | 5794 |
| 5750 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; | |
| 5751 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; | |
| 5752 | |
| 5753 | 5795 |
| 5754 TEST(DebuggerDebugMessageDispatch) { | 5796 TEST(DebuggerDebugMessageDispatch) { |
| 5797 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread( |
| 5798 i::Isolate::Current()); |
| 5799 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread( |
| 5800 i::Isolate::Current()); |
| 5801 |
| 5755 i::FLAG_debugger_auto_break = true; | 5802 i::FLAG_debugger_auto_break = true; |
| 5756 | 5803 |
| 5757 // Create a V8 environment | 5804 // Create a V8 environment |
| 5758 Barriers stack_allocated_debug_message_dispatch_barriers; | 5805 Barriers stack_allocated_debug_message_dispatch_barriers; |
| 5759 stack_allocated_debug_message_dispatch_barriers.Initialize(); | 5806 stack_allocated_debug_message_dispatch_barriers.Initialize(); |
| 5760 debug_message_dispatch_barriers = | 5807 debug_message_dispatch_barriers = |
| 5761 &stack_allocated_debug_message_dispatch_barriers; | 5808 &stack_allocated_debug_message_dispatch_barriers; |
| 5762 | 5809 |
| 5763 debug_message_dispatch_v8_thread.Start(); | 5810 debug_message_dispatch_v8_thread.Start(); |
| 5764 debug_message_dispatch_debugger_thread.Start(); | 5811 debug_message_dispatch_debugger_thread.Start(); |
| 5765 | 5812 |
| 5766 debug_message_dispatch_v8_thread.Join(); | 5813 debug_message_dispatch_v8_thread.Join(); |
| 5767 debug_message_dispatch_debugger_thread.Join(); | 5814 debug_message_dispatch_debugger_thread.Join(); |
| 5768 } | 5815 } |
| 5769 | 5816 |
| 5770 | 5817 |
| 5771 TEST(DebuggerAgent) { | 5818 TEST(DebuggerAgent) { |
| 5819 i::Debugger* debugger = i::Isolate::Current()->debugger(); |
| 5772 // Make sure these ports is not used by other tests to allow tests to run in | 5820 // Make sure these ports is not used by other tests to allow tests to run in |
| 5773 // parallel. | 5821 // parallel. |
| 5774 const int kPort1 = 5858; | 5822 const int kPort1 = 5858; |
| 5775 const int kPort2 = 5857; | 5823 const int kPort2 = 5857; |
| 5776 const int kPort3 = 5856; | 5824 const int kPort3 = 5856; |
| 5777 | 5825 |
| 5778 // Make a string with the port2 number. | 5826 // Make a string with the port2 number. |
| 5779 const int kPortBufferLen = 6; | 5827 const int kPortBufferLen = 6; |
| 5780 char port2_str[kPortBufferLen]; | 5828 char port2_str[kPortBufferLen]; |
| 5781 OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); | 5829 OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); |
| 5782 | 5830 |
| 5783 bool ok; | 5831 bool ok; |
| 5784 | 5832 |
| 5785 // Initialize the socket library. | 5833 // Initialize the socket library. |
| 5786 i::Socket::Setup(); | 5834 i::Socket::Setup(); |
| 5787 | 5835 |
| 5788 // Test starting and stopping the agent without any client connection. | 5836 // Test starting and stopping the agent without any client connection. |
| 5789 i::Debugger::StartAgent("test", kPort1); | 5837 debugger->StartAgent("test", kPort1); |
| 5790 i::Debugger::StopAgent(); | 5838 debugger->StopAgent(); |
| 5791 | 5839 |
| 5792 // Test starting the agent, connecting a client and shutting down the agent | 5840 // Test starting the agent, connecting a client and shutting down the agent |
| 5793 // with the client connected. | 5841 // with the client connected. |
| 5794 ok = i::Debugger::StartAgent("test", kPort2); | 5842 ok = debugger->StartAgent("test", kPort2); |
| 5795 CHECK(ok); | 5843 CHECK(ok); |
| 5796 i::Debugger::WaitForAgent(); | 5844 debugger->WaitForAgent(); |
| 5797 i::Socket* client = i::OS::CreateSocket(); | 5845 i::Socket* client = i::OS::CreateSocket(); |
| 5798 ok = client->Connect("localhost", port2_str); | 5846 ok = client->Connect("localhost", port2_str); |
| 5799 CHECK(ok); | 5847 CHECK(ok); |
| 5800 i::Debugger::StopAgent(); | 5848 debugger->StopAgent(); |
| 5801 delete client; | 5849 delete client; |
| 5802 | 5850 |
| 5803 // Test starting and stopping the agent with the required port already | 5851 // Test starting and stopping the agent with the required port already |
| 5804 // occoupied. | 5852 // occoupied. |
| 5805 i::Socket* server = i::OS::CreateSocket(); | 5853 i::Socket* server = i::OS::CreateSocket(); |
| 5806 server->Bind(kPort3); | 5854 server->Bind(kPort3); |
| 5807 | 5855 |
| 5808 i::Debugger::StartAgent("test", kPort3); | 5856 debugger->StartAgent("test", kPort3); |
| 5809 i::Debugger::StopAgent(); | 5857 debugger->StopAgent(); |
| 5810 | 5858 |
| 5811 delete server; | 5859 delete server; |
| 5812 } | 5860 } |
| 5813 | 5861 |
| 5814 | 5862 |
| 5815 class DebuggerAgentProtocolServerThread : public i::Thread { | 5863 class DebuggerAgentProtocolServerThread : public i::Thread { |
| 5816 public: | 5864 public: |
| 5817 explicit DebuggerAgentProtocolServerThread(int port) | 5865 explicit DebuggerAgentProtocolServerThread(i::Isolate* isolate, int port) |
| 5818 : port_(port), server_(NULL), client_(NULL), | 5866 : Thread(isolate), port_(port), server_(NULL), client_(NULL), |
| 5819 listening_(OS::CreateSemaphore(0)) { | 5867 listening_(OS::CreateSemaphore(0)) { |
| 5820 } | 5868 } |
| 5821 ~DebuggerAgentProtocolServerThread() { | 5869 ~DebuggerAgentProtocolServerThread() { |
| 5822 // Close both sockets. | 5870 // Close both sockets. |
| 5823 delete client_; | 5871 delete client_; |
| 5824 delete server_; | 5872 delete server_; |
| 5825 delete listening_; | 5873 delete listening_; |
| 5826 } | 5874 } |
| 5827 | 5875 |
| 5828 void Run(); | 5876 void Run(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5870 // Make a string with the port number. | 5918 // Make a string with the port number. |
| 5871 const int kPortBufferLen = 6; | 5919 const int kPortBufferLen = 6; |
| 5872 char port_str[kPortBufferLen]; | 5920 char port_str[kPortBufferLen]; |
| 5873 OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); | 5921 OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); |
| 5874 | 5922 |
| 5875 // Initialize the socket library. | 5923 // Initialize the socket library. |
| 5876 i::Socket::Setup(); | 5924 i::Socket::Setup(); |
| 5877 | 5925 |
| 5878 // Create a socket server to receive a debugger agent message. | 5926 // Create a socket server to receive a debugger agent message. |
| 5879 DebuggerAgentProtocolServerThread* server = | 5927 DebuggerAgentProtocolServerThread* server = |
| 5880 new DebuggerAgentProtocolServerThread(kPort); | 5928 new DebuggerAgentProtocolServerThread(i::Isolate::Current(), kPort); |
| 5881 server->Start(); | 5929 server->Start(); |
| 5882 server->WaitForListening(); | 5930 server->WaitForListening(); |
| 5883 | 5931 |
| 5884 // Connect. | 5932 // Connect. |
| 5885 i::Socket* client = i::OS::CreateSocket(); | 5933 i::Socket* client = i::OS::CreateSocket(); |
| 5886 CHECK(client != NULL); | 5934 CHECK(client != NULL); |
| 5887 bool ok = client->Connect(kLocalhost, port_str); | 5935 bool ok = client->Connect(kLocalhost, port_str); |
| 5888 CHECK(ok); | 5936 CHECK(ok); |
| 5889 | 5937 |
| 5890 // Send headers which overflow the receive buffer. | 5938 // Send headers which overflow the receive buffer. |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6369 v8::Handle<v8::Value> data) { | 6417 v8::Handle<v8::Value> data) { |
| 6370 // Count the number of breaks. | 6418 // Count the number of breaks. |
| 6371 if (event == v8::ScriptCollected) { | 6419 if (event == v8::ScriptCollected) { |
| 6372 script_collected_count++; | 6420 script_collected_count++; |
| 6373 } | 6421 } |
| 6374 } | 6422 } |
| 6375 | 6423 |
| 6376 | 6424 |
| 6377 // Test that scripts collected are reported through the debug event listener. | 6425 // Test that scripts collected are reported through the debug event listener. |
| 6378 TEST(ScriptCollectedEvent) { | 6426 TEST(ScriptCollectedEvent) { |
| 6427 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 6379 break_point_hit_count = 0; | 6428 break_point_hit_count = 0; |
| 6380 script_collected_count = 0; | 6429 script_collected_count = 0; |
| 6381 v8::HandleScope scope; | 6430 v8::HandleScope scope; |
| 6382 DebugLocalContext env; | 6431 DebugLocalContext env; |
| 6383 | 6432 |
| 6384 // Request the loaded scripts to initialize the debugger script cache. | 6433 // Request the loaded scripts to initialize the debugger script cache. |
| 6385 Debug::GetLoadedScripts(); | 6434 debug->GetLoadedScripts(); |
| 6386 | 6435 |
| 6387 // Do garbage collection to ensure that only the script in this test will be | 6436 // Do garbage collection to ensure that only the script in this test will be |
| 6388 // collected afterwards. | 6437 // collected afterwards. |
| 6389 Heap::CollectAllGarbage(false); | 6438 HEAP->CollectAllGarbage(false); |
| 6390 | 6439 |
| 6391 script_collected_count = 0; | 6440 script_collected_count = 0; |
| 6392 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, | 6441 v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, |
| 6393 v8::Undefined()); | 6442 v8::Undefined()); |
| 6394 { | 6443 { |
| 6395 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6444 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
| 6396 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6445 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
| 6397 } | 6446 } |
| 6398 | 6447 |
| 6399 // Do garbage collection to collect the script above which is no longer | 6448 // Do garbage collection to collect the script above which is no longer |
| 6400 // referenced. | 6449 // referenced. |
| 6401 Heap::CollectAllGarbage(false); | 6450 HEAP->CollectAllGarbage(false); |
| 6402 | 6451 |
| 6403 CHECK_EQ(2, script_collected_count); | 6452 CHECK_EQ(2, script_collected_count); |
| 6404 | 6453 |
| 6405 v8::Debug::SetDebugEventListener(NULL); | 6454 v8::Debug::SetDebugEventListener(NULL); |
| 6406 CheckDebuggerUnloaded(); | 6455 CheckDebuggerUnloaded(); |
| 6407 } | 6456 } |
| 6408 | 6457 |
| 6409 | 6458 |
| 6410 // Debug event listener which counts the script collected events. | 6459 // Debug event listener which counts the script collected events. |
| 6411 int script_collected_message_count = 0; | 6460 int script_collected_message_count = 0; |
| 6412 static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) { | 6461 static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) { |
| 6413 // Count the number of scripts collected. | 6462 // Count the number of scripts collected. |
| 6414 if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) { | 6463 if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) { |
| 6415 script_collected_message_count++; | 6464 script_collected_message_count++; |
| 6416 v8::Handle<v8::Context> context = message.GetEventContext(); | 6465 v8::Handle<v8::Context> context = message.GetEventContext(); |
| 6417 CHECK(context.IsEmpty()); | 6466 CHECK(context.IsEmpty()); |
| 6418 } | 6467 } |
| 6419 } | 6468 } |
| 6420 | 6469 |
| 6421 | 6470 |
| 6422 // Test that GetEventContext doesn't fail and return empty handle for | 6471 // Test that GetEventContext doesn't fail and return empty handle for |
| 6423 // ScriptCollected events. | 6472 // ScriptCollected events. |
| 6424 TEST(ScriptCollectedEventContext) { | 6473 TEST(ScriptCollectedEventContext) { |
| 6474 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 6425 script_collected_message_count = 0; | 6475 script_collected_message_count = 0; |
| 6426 v8::HandleScope scope; | 6476 v8::HandleScope scope; |
| 6427 | 6477 |
| 6428 { // Scope for the DebugLocalContext. | 6478 { // Scope for the DebugLocalContext. |
| 6429 DebugLocalContext env; | 6479 DebugLocalContext env; |
| 6430 | 6480 |
| 6431 // Request the loaded scripts to initialize the debugger script cache. | 6481 // Request the loaded scripts to initialize the debugger script cache. |
| 6432 Debug::GetLoadedScripts(); | 6482 debug->GetLoadedScripts(); |
| 6433 | 6483 |
| 6434 // Do garbage collection to ensure that only the script in this test will be | 6484 // Do garbage collection to ensure that only the script in this test will be |
| 6435 // collected afterwards. | 6485 // collected afterwards. |
| 6436 Heap::CollectAllGarbage(false); | 6486 HEAP->CollectAllGarbage(false); |
| 6437 | 6487 |
| 6438 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); | 6488 v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); |
| 6439 { | 6489 { |
| 6440 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6490 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
| 6441 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6491 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
| 6442 } | 6492 } |
| 6443 } | 6493 } |
| 6444 | 6494 |
| 6445 // Do garbage collection to collect the script above which is no longer | 6495 // Do garbage collection to collect the script above which is no longer |
| 6446 // referenced. | 6496 // referenced. |
| 6447 Heap::CollectAllGarbage(false); | 6497 HEAP->CollectAllGarbage(false); |
| 6448 | 6498 |
| 6449 CHECK_EQ(2, script_collected_message_count); | 6499 CHECK_EQ(2, script_collected_message_count); |
| 6450 | 6500 |
| 6451 v8::Debug::SetMessageHandler2(NULL); | 6501 v8::Debug::SetMessageHandler2(NULL); |
| 6452 } | 6502 } |
| 6453 | 6503 |
| 6454 | 6504 |
| 6455 // Debug event listener which counts the after compile events. | 6505 // Debug event listener which counts the after compile events. |
| 6456 int after_compile_message_count = 0; | 6506 int after_compile_message_count = 0; |
| 6457 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { | 6507 static void AfterCompileMessageHandler(const v8::Debug::Message& message) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6585 // sent. | 6635 // sent. |
| 6586 CHECK_EQ(1, after_compile_message_count); | 6636 CHECK_EQ(1, after_compile_message_count); |
| 6587 | 6637 |
| 6588 ClearBreakPointFromJS(sbp1); | 6638 ClearBreakPointFromJS(sbp1); |
| 6589 ClearBreakPointFromJS(sbp2); | 6639 ClearBreakPointFromJS(sbp2); |
| 6590 v8::Debug::SetMessageHandler2(NULL); | 6640 v8::Debug::SetMessageHandler2(NULL); |
| 6591 } | 6641 } |
| 6592 | 6642 |
| 6593 | 6643 |
| 6594 static void BreakMessageHandler(const v8::Debug::Message& message) { | 6644 static void BreakMessageHandler(const v8::Debug::Message& message) { |
| 6645 i::Isolate* isolate = i::Isolate::Current(); |
| 6595 if (message.IsEvent() && message.GetEvent() == v8::Break) { | 6646 if (message.IsEvent() && message.GetEvent() == v8::Break) { |
| 6596 // Count the number of breaks. | 6647 // Count the number of breaks. |
| 6597 break_point_hit_count++; | 6648 break_point_hit_count++; |
| 6598 | 6649 |
| 6599 v8::HandleScope scope; | 6650 v8::HandleScope scope; |
| 6600 v8::Handle<v8::String> json = message.GetJSON(); | 6651 v8::Handle<v8::String> json = message.GetJSON(); |
| 6601 | 6652 |
| 6602 SendContinueCommand(); | 6653 SendContinueCommand(); |
| 6603 } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { | 6654 } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { |
| 6604 v8::HandleScope scope; | 6655 v8::HandleScope scope; |
| 6605 | 6656 |
| 6606 bool is_debug_break = i::StackGuard::IsDebugBreak(); | 6657 bool is_debug_break = isolate->stack_guard()->IsDebugBreak(); |
| 6607 // Force DebugBreak flag while serializer is working. | 6658 // Force DebugBreak flag while serializer is working. |
| 6608 i::StackGuard::DebugBreak(); | 6659 isolate->stack_guard()->DebugBreak(); |
| 6609 | 6660 |
| 6610 // Force serialization to trigger some internal JS execution. | 6661 // Force serialization to trigger some internal JS execution. |
| 6611 v8::Handle<v8::String> json = message.GetJSON(); | 6662 v8::Handle<v8::String> json = message.GetJSON(); |
| 6612 | 6663 |
| 6613 // Restore previous state. | 6664 // Restore previous state. |
| 6614 if (is_debug_break) { | 6665 if (is_debug_break) { |
| 6615 i::StackGuard::DebugBreak(); | 6666 isolate->stack_guard()->DebugBreak(); |
| 6616 } else { | 6667 } else { |
| 6617 i::StackGuard::Continue(i::DEBUGBREAK); | 6668 isolate->stack_guard()->Continue(i::DEBUGBREAK); |
| 6618 } | 6669 } |
| 6619 } | 6670 } |
| 6620 } | 6671 } |
| 6621 | 6672 |
| 6622 | 6673 |
| 6623 // Test that if DebugBreak is forced it is ignored when code from | 6674 // Test that if DebugBreak is forced it is ignored when code from |
| 6624 // debug-delay.js is executed. | 6675 // debug-delay.js is executed. |
| 6625 TEST(NoDebugBreakInAfterCompileMessageHandler) { | 6676 TEST(NoDebugBreakInAfterCompileMessageHandler) { |
| 6626 v8::HandleScope scope; | 6677 v8::HandleScope scope; |
| 6627 DebugLocalContext env; | 6678 DebugLocalContext env; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6836 "})"))); | 6887 "})"))); |
| 6837 const int argc = 1; | 6888 const int argc = 1; |
| 6838 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 6889 v8::Handle<v8::Value> argv[argc] = { exec_state }; |
| 6839 v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); | 6890 v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); |
| 6840 CHECK(result->IsTrue()); | 6891 CHECK(result->IsTrue()); |
| 6841 } | 6892 } |
| 6842 } | 6893 } |
| 6843 | 6894 |
| 6844 | 6895 |
| 6845 TEST(CallingContextIsNotDebugContext) { | 6896 TEST(CallingContextIsNotDebugContext) { |
| 6897 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 6846 // Create and enter a debugee context. | 6898 // Create and enter a debugee context. |
| 6847 v8::HandleScope scope; | 6899 v8::HandleScope scope; |
| 6848 DebugLocalContext env; | 6900 DebugLocalContext env; |
| 6849 env.ExposeDebug(); | 6901 env.ExposeDebug(); |
| 6850 | 6902 |
| 6851 // Save handles to the debugger and debugee contexts to be used in | 6903 // Save handles to the debugger and debugee contexts to be used in |
| 6852 // NamedGetterWithCallingContextCheck. | 6904 // NamedGetterWithCallingContextCheck. |
| 6853 debugee_context = v8::Local<v8::Context>(*env); | 6905 debugee_context = v8::Local<v8::Context>(*env); |
| 6854 debugger_context = v8::Utils::ToLocal(Debug::debug_context()); | 6906 debugger_context = v8::Utils::ToLocal(debug->debug_context()); |
| 6855 | 6907 |
| 6856 // Create object with 'a' property accessor. | 6908 // Create object with 'a' property accessor. |
| 6857 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); | 6909 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); |
| 6858 named->SetAccessor(v8::String::New("a"), | 6910 named->SetAccessor(v8::String::New("a"), |
| 6859 NamedGetterWithCallingContextCheck); | 6911 NamedGetterWithCallingContextCheck); |
| 6860 env->Global()->Set(v8::String::New("obj"), | 6912 env->Global()->Set(v8::String::New("obj"), |
| 6861 named->NewInstance()); | 6913 named->NewInstance()); |
| 6862 | 6914 |
| 6863 // Register the debug event listener | 6915 // Register the debug event listener |
| 6864 v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); | 6916 v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7195 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); | 7247 TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); |
| 7196 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); | 7248 TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); |
| 7197 | 7249 |
| 7198 // Get rid of the debug event listener. | 7250 // Get rid of the debug event listener. |
| 7199 v8::Debug::SetDebugEventListener(NULL); | 7251 v8::Debug::SetDebugEventListener(NULL); |
| 7200 CheckDebuggerUnloaded(); | 7252 CheckDebuggerUnloaded(); |
| 7201 } | 7253 } |
| 7202 | 7254 |
| 7203 | 7255 |
| 7204 #endif // ENABLE_DEBUGGER_SUPPORT | 7256 #endif // ENABLE_DEBUGGER_SUPPORT |
| OLD | NEW |