Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 ASSERT(!IsDebugBreak()); | 366 ASSERT(!IsDebugBreak()); |
| 367 } | 367 } |
| 368 | 368 |
| 369 | 369 |
| 370 void BreakLocationIterator::PrepareStepIn() { | 370 void BreakLocationIterator::PrepareStepIn() { |
| 371 HandleScope scope; | 371 HandleScope scope; |
| 372 | 372 |
| 373 // Step in can only be prepared if currently positioned on an IC call, | 373 // Step in can only be prepared if currently positioned on an IC call, |
| 374 // construct call or CallFunction stub call. | 374 // construct call or CallFunction stub call. |
| 375 Address target = rinfo()->target_address(); | 375 Address target = rinfo()->target_address(); |
| 376 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); | 376 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); |
|
Erik Corry
2011/02/22 12:27:19
Perhaps rename this variable to something more mea
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
| 377 if (code->is_call_stub() || code->is_keyed_call_stub()) { | 377 if (code->is_call_stub() || code->is_keyed_call_stub()) { |
| 378 // Step in through IC call is handled by the runtime system. Therefore make | 378 // Step in through IC call is handled by the runtime system. Therefore make |
| 379 // sure that the any current IC is cleared and the runtime system is | 379 // sure that the any current IC is cleared and the runtime system is |
| 380 // called. If the executing code has a debug break at the location change | 380 // called. If the executing code has a debug break at the location change |
| 381 // the call in the original code as it is the code there that will be | 381 // the call in the original code as it is the code there that will be |
| 382 // executed in place of the debug break call. | 382 // executed in place of the debug break call. |
| 383 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(), | 383 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(), |
| 384 code->kind()); | 384 code->kind()); |
| 385 if (IsDebugBreak()) { | 385 if (IsDebugBreak()) { |
| 386 original_rinfo()->set_target_address(stub->entry()); | 386 original_rinfo()->set_target_address(stub->entry(), this->code()); |
| 387 } else { | 387 } else { |
| 388 rinfo()->set_target_address(stub->entry()); | 388 rinfo()->set_target_address(stub->entry(), this->code()); |
| 389 } | 389 } |
| 390 } else { | 390 } else { |
| 391 #ifdef DEBUG | 391 #ifdef DEBUG |
| 392 // All the following stuff is needed only for assertion checks so the code | 392 // All the following stuff is needed only for assertion checks so the code |
| 393 // is wrapped in ifdef. | 393 // is wrapped in ifdef. |
| 394 Handle<Code> maybe_call_function_stub = code; | 394 Handle<Code> maybe_call_function_stub = code; |
| 395 if (IsDebugBreak()) { | 395 if (IsDebugBreak()) { |
| 396 Address original_target = original_rinfo()->target_address(); | 396 Address original_target = original_rinfo()->target_address(); |
| 397 maybe_call_function_stub = | 397 maybe_call_function_stub = |
| 398 Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); | 398 Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 return IsDebugBreakAtSlot(); | 434 return IsDebugBreakAtSlot(); |
| 435 } else { | 435 } else { |
| 436 return Debug::IsDebugBreak(rinfo()->target_address()); | 436 return Debug::IsDebugBreak(rinfo()->target_address()); |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 | 439 |
| 440 | 440 |
| 441 void BreakLocationIterator::SetDebugBreakAtIC() { | 441 void BreakLocationIterator::SetDebugBreakAtIC() { |
| 442 // Patch the original code with the current address as the current address | 442 // Patch the original code with the current address as the current address |
| 443 // might have changed by the inline caching since the code was copied. | 443 // might have changed by the inline caching since the code was copied. |
| 444 original_rinfo()->set_target_address(rinfo()->target_address()); | 444 original_rinfo()->set_target_address(rinfo()->target_address(), this->code()); |
| 445 | 445 |
| 446 RelocInfo::Mode mode = rmode(); | 446 RelocInfo::Mode mode = rmode(); |
| 447 if (RelocInfo::IsCodeTarget(mode)) { | 447 if (RelocInfo::IsCodeTarget(mode)) { |
| 448 Address target = rinfo()->target_address(); | 448 Address target = rinfo()->target_address(); |
| 449 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); | 449 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); |
| 450 | 450 |
| 451 // Patch the code to invoke the builtin debug break function matching the | 451 // Patch the code to invoke the builtin debug break function matching the |
| 452 // calling convention used by the call site. | 452 // calling convention used by the call site. |
| 453 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode)); | 453 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode)); |
| 454 rinfo()->set_target_address(dbgbrk_code->entry()); | 454 rinfo()->set_target_address(dbgbrk_code->entry(), this->code()); |
| 455 | 455 |
| 456 // For stubs that refer back to an inlined version clear the cached map for | 456 // For stubs that refer back to an inlined version clear the cached map for |
| 457 // the inlined case to always go through the IC. As long as the break point | 457 // the inlined case to always go through the IC. As long as the break point |
| 458 // is set the patching performed by the runtime system will take place in | 458 // is set the patching performed by the runtime system will take place in |
| 459 // the code copy and will therefore have no effect on the running code | 459 // the code copy and will therefore have no effect on the running code |
| 460 // keeping it from using the inlined code. | 460 // keeping it from using the inlined code. |
| 461 if (code->is_keyed_load_stub()) { | 461 if (code->is_keyed_load_stub()) { |
| 462 KeyedLoadIC::ClearInlinedVersion(pc()); | 462 KeyedLoadIC::ClearInlinedVersion(pc()); |
| 463 } else if (code->is_keyed_store_stub()) { | 463 } else if (code->is_keyed_store_stub()) { |
| 464 KeyedStoreIC::ClearInlinedVersion(pc()); | 464 KeyedStoreIC::ClearInlinedVersion(pc()); |
| 465 } else if (code->is_load_stub()) { | 465 } else if (code->is_load_stub()) { |
| 466 LoadIC::ClearInlinedVersion(pc()); | 466 LoadIC::ClearInlinedVersion(pc()); |
| 467 } else if (code->is_store_stub()) { | 467 } else if (code->is_store_stub()) { |
| 468 StoreIC::ClearInlinedVersion(pc()); | 468 StoreIC::ClearInlinedVersion(pc()); |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 } | 471 } |
| 472 | 472 |
| 473 | 473 |
| 474 void BreakLocationIterator::ClearDebugBreakAtIC() { | 474 void BreakLocationIterator::ClearDebugBreakAtIC() { |
| 475 // Patch the code to the original invoke. | 475 // Patch the code to the original invoke. |
| 476 rinfo()->set_target_address(original_rinfo()->target_address()); | 476 rinfo()->set_target_address(original_rinfo()->target_address(), code()); |
| 477 | 477 |
| 478 RelocInfo::Mode mode = rmode(); | 478 RelocInfo::Mode mode = rmode(); |
| 479 if (RelocInfo::IsCodeTarget(mode)) { | 479 if (RelocInfo::IsCodeTarget(mode)) { |
| 480 AssertNoAllocation nogc; | 480 AssertNoAllocation nogc; |
| 481 Address target = original_rinfo()->target_address(); | 481 Address target = original_rinfo()->target_address(); |
| 482 Code* code = Code::GetCodeFromTargetAddress(target); | 482 Code* code = Code::GetCodeFromTargetAddress(target); |
| 483 | 483 |
| 484 // Restore the inlined version of keyed stores to get back to the | 484 // Restore the inlined version of keyed stores to get back to the |
| 485 // fast case. We need to patch back the keyed store because no | 485 // fast case. We need to patch back the keyed store because no |
| 486 // patching happens when running normally. For keyed loads, the | 486 // patching happens when running normally. For keyed loads, the |
| (...skipping 2588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3075 { | 3075 { |
| 3076 Locker locker; | 3076 Locker locker; |
| 3077 Debugger::CallMessageDispatchHandler(); | 3077 Debugger::CallMessageDispatchHandler(); |
| 3078 } | 3078 } |
| 3079 } | 3079 } |
| 3080 } | 3080 } |
| 3081 | 3081 |
| 3082 #endif // ENABLE_DEBUGGER_SUPPORT | 3082 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3083 | 3083 |
| 3084 } } // namespace v8::internal | 3084 } } // namespace v8::internal |
| OLD | NEW |