| 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 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 ASSERT(!IsDebugBreak()); | 394 ASSERT(!IsDebugBreak()); |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 void BreakLocationIterator::PrepareStepIn() { | 398 void BreakLocationIterator::PrepareStepIn() { |
| 399 HandleScope scope; | 399 HandleScope scope; |
| 400 | 400 |
| 401 // Step in can only be prepared if currently positioned on an IC call, | 401 // Step in can only be prepared if currently positioned on an IC call, |
| 402 // construct call or CallFunction stub call. | 402 // construct call or CallFunction stub call. |
| 403 Address target = rinfo()->target_address(); | 403 Address target = rinfo()->target_address(); |
| 404 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); | 404 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); |
| 405 if (code->is_call_stub() || code->is_keyed_call_stub()) { | 405 if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) { |
| 406 // Step in through IC call is handled by the runtime system. Therefore make | 406 // Step in through IC call is handled by the runtime system. Therefore make |
| 407 // sure that the any current IC is cleared and the runtime system is | 407 // sure that the any current IC is cleared and the runtime system is |
| 408 // called. If the executing code has a debug break at the location change | 408 // called. If the executing code has a debug break at the location change |
| 409 // the call in the original code as it is the code there that will be | 409 // the call in the original code as it is the code there that will be |
| 410 // executed in place of the debug break call. | 410 // executed in place of the debug break call. |
| 411 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(), | 411 Handle<Code> stub = ComputeCallDebugPrepareStepIn( |
| 412 code->kind()); | 412 target_code->arguments_count(), target_code->kind()); |
| 413 if (IsDebugBreak()) { | 413 if (IsDebugBreak()) { |
| 414 original_rinfo()->set_target_address(stub->entry()); | 414 original_rinfo()->set_target_address(stub->entry()); |
| 415 } else { | 415 } else { |
| 416 rinfo()->set_target_address(stub->entry()); | 416 rinfo()->set_target_address(stub->entry()); |
| 417 } | 417 } |
| 418 } else { | 418 } else { |
| 419 #ifdef DEBUG | 419 #ifdef DEBUG |
| 420 // All the following stuff is needed only for assertion checks so the code | 420 // All the following stuff is needed only for assertion checks so the code |
| 421 // is wrapped in ifdef. | 421 // is wrapped in ifdef. |
| 422 Handle<Code> maybe_call_function_stub = code; | 422 Handle<Code> maybe_call_function_stub = target_code; |
| 423 if (IsDebugBreak()) { | 423 if (IsDebugBreak()) { |
| 424 Address original_target = original_rinfo()->target_address(); | 424 Address original_target = original_rinfo()->target_address(); |
| 425 maybe_call_function_stub = | 425 maybe_call_function_stub = |
| 426 Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); | 426 Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); |
| 427 } | 427 } |
| 428 bool is_call_function_stub = | 428 bool is_call_function_stub = |
| 429 (maybe_call_function_stub->kind() == Code::STUB && | 429 (maybe_call_function_stub->kind() == Code::STUB && |
| 430 maybe_call_function_stub->major_key() == CodeStub::CallFunction); | 430 maybe_call_function_stub->major_key() == CodeStub::CallFunction); |
| 431 | 431 |
| 432 // Step in through construct call requires no changes to the running code. | 432 // Step in through construct call requires no changes to the running code. |
| 433 // Step in through getters/setters should already be prepared as well | 433 // Step in through getters/setters should already be prepared as well |
| 434 // because caller of this function (Debug::PrepareStep) is expected to | 434 // because caller of this function (Debug::PrepareStep) is expected to |
| 435 // flood the top frame's function with one shot breakpoints. | 435 // flood the top frame's function with one shot breakpoints. |
| 436 // Step in through CallFunction stub should also be prepared by caller of | 436 // Step in through CallFunction stub should also be prepared by caller of |
| 437 // this function (Debug::PrepareStep) which should flood target function | 437 // this function (Debug::PrepareStep) which should flood target function |
| 438 // with breakpoints. | 438 // with breakpoints. |
| 439 ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub() | 439 ASSERT(RelocInfo::IsConstructCall(rmode()) || |
| 440 || is_call_function_stub); | 440 target_code->is_inline_cache_stub() || |
| 441 is_call_function_stub); |
| 441 #endif | 442 #endif |
| 442 } | 443 } |
| 443 } | 444 } |
| 444 | 445 |
| 445 | 446 |
| 446 // Check whether the break point is at a position which will exit the function. | 447 // Check whether the break point is at a position which will exit the function. |
| 447 bool BreakLocationIterator::IsExit() const { | 448 bool BreakLocationIterator::IsExit() const { |
| 448 return (RelocInfo::IsJSReturn(rmode())); | 449 return (RelocInfo::IsJSReturn(rmode())); |
| 449 } | 450 } |
| 450 | 451 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 467 | 468 |
| 468 | 469 |
| 469 void BreakLocationIterator::SetDebugBreakAtIC() { | 470 void BreakLocationIterator::SetDebugBreakAtIC() { |
| 470 // Patch the original code with the current address as the current address | 471 // Patch the original code with the current address as the current address |
| 471 // might have changed by the inline caching since the code was copied. | 472 // might have changed by the inline caching since the code was copied. |
| 472 original_rinfo()->set_target_address(rinfo()->target_address()); | 473 original_rinfo()->set_target_address(rinfo()->target_address()); |
| 473 | 474 |
| 474 RelocInfo::Mode mode = rmode(); | 475 RelocInfo::Mode mode = rmode(); |
| 475 if (RelocInfo::IsCodeTarget(mode)) { | 476 if (RelocInfo::IsCodeTarget(mode)) { |
| 476 Address target = rinfo()->target_address(); | 477 Address target = rinfo()->target_address(); |
| 477 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); | 478 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); |
| 478 | 479 |
| 479 // Patch the code to invoke the builtin debug break function matching the | 480 // Patch the code to invoke the builtin debug break function matching the |
| 480 // calling convention used by the call site. | 481 // calling convention used by the call site. |
| 481 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode)); | 482 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode)); |
| 482 rinfo()->set_target_address(dbgbrk_code->entry()); | 483 rinfo()->set_target_address(dbgbrk_code->entry()); |
| 483 } | 484 } |
| 484 } | 485 } |
| 485 | 486 |
| 486 | 487 |
| 487 void BreakLocationIterator::ClearDebugBreakAtIC() { | 488 void BreakLocationIterator::ClearDebugBreakAtIC() { |
| 488 // Patch the code to the original invoke. | 489 // Patch the code to the original invoke. |
| 489 rinfo()->set_target_address(original_rinfo()->target_address()); | 490 rinfo()->set_target_address(original_rinfo()->target_address()); |
| 490 } | 491 } |
| 491 | 492 |
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 0, NULL, &caught_exception); | 1991 0, NULL, &caught_exception); |
| 1991 } | 1992 } |
| 1992 | 1993 |
| 1993 | 1994 |
| 1994 void Debug::CreateScriptCache() { | 1995 void Debug::CreateScriptCache() { |
| 1995 Heap* heap = isolate_->heap(); | 1996 Heap* heap = isolate_->heap(); |
| 1996 HandleScope scope(isolate_); | 1997 HandleScope scope(isolate_); |
| 1997 | 1998 |
| 1998 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 1999 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
| 1999 // rid of all the cached script wrappers and the second gets rid of the | 2000 // rid of all the cached script wrappers and the second gets rid of the |
| 2000 // scripts which are no longer referenced. | 2001 // scripts which are no longer referenced. The second also sweeps precisely, |
| 2001 heap->CollectAllGarbage(false); | 2002 // which saves us doing yet another GC to make the heap iterable. |
| 2002 heap->CollectAllGarbage(false); | 2003 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 2004 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask); |
| 2003 | 2005 |
| 2004 ASSERT(script_cache_ == NULL); | 2006 ASSERT(script_cache_ == NULL); |
| 2005 script_cache_ = new ScriptCache(); | 2007 script_cache_ = new ScriptCache(); |
| 2006 | 2008 |
| 2007 // Scan heap for Script objects. | 2009 // Scan heap for Script objects. |
| 2008 int count = 0; | 2010 int count = 0; |
| 2009 HeapIterator iterator; | 2011 HeapIterator iterator; |
| 2012 AssertNoAllocation no_allocation; |
| 2013 |
| 2010 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 2014 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 2011 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { | 2015 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { |
| 2012 script_cache_->Add(Handle<Script>(Script::cast(obj))); | 2016 script_cache_->Add(Handle<Script>(Script::cast(obj))); |
| 2013 count++; | 2017 count++; |
| 2014 } | 2018 } |
| 2015 } | 2019 } |
| 2016 } | 2020 } |
| 2017 | 2021 |
| 2018 | 2022 |
| 2019 void Debug::DestroyScriptCache() { | 2023 void Debug::DestroyScriptCache() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2040 } | 2044 } |
| 2041 | 2045 |
| 2042 // If the script cache is not active just return an empty array. | 2046 // If the script cache is not active just return an empty array. |
| 2043 ASSERT(script_cache_ != NULL); | 2047 ASSERT(script_cache_ != NULL); |
| 2044 if (script_cache_ == NULL) { | 2048 if (script_cache_ == NULL) { |
| 2045 isolate_->factory()->NewFixedArray(0); | 2049 isolate_->factory()->NewFixedArray(0); |
| 2046 } | 2050 } |
| 2047 | 2051 |
| 2048 // Perform GC to get unreferenced scripts evicted from the cache before | 2052 // Perform GC to get unreferenced scripts evicted from the cache before |
| 2049 // returning the content. | 2053 // returning the content. |
| 2050 isolate_->heap()->CollectAllGarbage(false); | 2054 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 2051 | 2055 |
| 2052 // Get the scripts from the cache. | 2056 // Get the scripts from the cache. |
| 2053 return script_cache_->GetScripts(); | 2057 return script_cache_->GetScripts(); |
| 2054 } | 2058 } |
| 2055 | 2059 |
| 2056 | 2060 |
| 2057 void Debug::AfterGarbageCollection() { | 2061 void Debug::AfterGarbageCollection() { |
| 2058 // Generate events for collected scripts. | 2062 // Generate events for collected scripts. |
| 2059 if (script_cache_ != NULL) { | 2063 if (script_cache_ != NULL) { |
| 2060 script_cache_->ProcessCollectedScripts(); | 2064 script_cache_->ProcessCollectedScripts(); |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3224 { | 3228 { |
| 3225 Locker locker; | 3229 Locker locker; |
| 3226 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3230 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
| 3227 } | 3231 } |
| 3228 } | 3232 } |
| 3229 } | 3233 } |
| 3230 | 3234 |
| 3231 #endif // ENABLE_DEBUGGER_SUPPORT | 3235 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3232 | 3236 |
| 3233 } } // namespace v8::internal | 3237 } } // namespace v8::internal |
| OLD | NEW |