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 |