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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 // called. If the executing code has a debug break at the location change | 327 // called. If the executing code has a debug break at the location change |
328 // the call in the original code as it is the code there that will be | 328 // the call in the original code as it is the code there that will be |
329 // executed in place of the debug break call. | 329 // executed in place of the debug break call. |
330 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count()); | 330 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count()); |
331 if (IsDebugBreak()) { | 331 if (IsDebugBreak()) { |
332 original_rinfo()->set_target_address(stub->entry()); | 332 original_rinfo()->set_target_address(stub->entry()); |
333 } else { | 333 } else { |
334 rinfo()->set_target_address(stub->entry()); | 334 rinfo()->set_target_address(stub->entry()); |
335 } | 335 } |
336 } else { | 336 } else { |
337 // Step in through constructs call requires no changes to the running code. | 337 // Step in through construct call requires no changes to the running code. |
338 ASSERT(RelocInfo::IsConstructCall(rmode())); | 338 // Step in through getters/setters should already be prepared as well |
| 339 // because caller of this function (Debug::PrepareStep) is expected to |
| 340 // flood the top frame's function with one shot breakpoints. |
| 341 ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()); |
339 } | 342 } |
340 } | 343 } |
341 | 344 |
342 | 345 |
343 // Check whether the break point is at a position which will exit the function. | 346 // Check whether the break point is at a position which will exit the function. |
344 bool BreakLocationIterator::IsExit() const { | 347 bool BreakLocationIterator::IsExit() const { |
345 return (RelocInfo::IsJSReturn(rmode())); | 348 return (RelocInfo::IsJSReturn(rmode())); |
346 } | 349 } |
347 | 350 |
348 | 351 |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 return; | 1083 return; |
1081 } | 1084 } |
1082 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1085 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1083 | 1086 |
1084 // Find the break location where execution has stopped. | 1087 // Find the break location where execution has stopped. |
1085 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); | 1088 BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); |
1086 it.FindBreakLocationFromAddress(frame->pc()); | 1089 it.FindBreakLocationFromAddress(frame->pc()); |
1087 | 1090 |
1088 // Compute whether or not the target is a call target. | 1091 // Compute whether or not the target is a call target. |
1089 bool is_call_target = false; | 1092 bool is_call_target = false; |
| 1093 bool is_load_or_store = false; |
| 1094 bool is_inline_cache_stub = false; |
1090 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { | 1095 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { |
1091 Address target = it.rinfo()->target_address(); | 1096 Address target = it.rinfo()->target_address(); |
1092 Code* code = Code::GetCodeFromTargetAddress(target); | 1097 Code* code = Code::GetCodeFromTargetAddress(target); |
1093 if (code->is_call_stub()) is_call_target = true; | 1098 if (code->is_call_stub()) { |
| 1099 is_call_target = true; |
| 1100 } |
| 1101 if (code->is_inline_cache_stub()) { |
| 1102 is_inline_cache_stub = true; |
| 1103 is_load_or_store = !is_call_target; |
| 1104 } |
1094 } | 1105 } |
1095 | 1106 |
1096 // If this is the last break code target step out is the only possibility. | 1107 // If this is the last break code target step out is the only possibility. |
1097 if (it.IsExit() || step_action == StepOut) { | 1108 if (it.IsExit() || step_action == StepOut) { |
1098 // Step out: If there is a JavaScript caller frame, we need to | 1109 // Step out: If there is a JavaScript caller frame, we need to |
1099 // flood it with breakpoints. | 1110 // flood it with breakpoints. |
1100 frames_it.Advance(); | 1111 frames_it.Advance(); |
1101 if (!frames_it.done()) { | 1112 if (!frames_it.done()) { |
1102 // Fill the function to return to with one-shot break points. | 1113 // Fill the function to return to with one-shot break points. |
1103 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); | 1114 JSFunction* function = JSFunction::cast(frames_it.frame()->function()); |
1104 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); | 1115 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); |
1105 } | 1116 } |
1106 } else if (!(is_call_target || RelocInfo::IsConstructCall(it.rmode())) || | 1117 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode())) |
1107 step_action == StepNext || step_action == StepMin) { | 1118 || step_action == StepNext || step_action == StepMin) { |
1108 // Step next or step min. | 1119 // Step next or step min. |
1109 | 1120 |
1110 // Fill the current function with one-shot break points. | 1121 // Fill the current function with one-shot break points. |
1111 FloodWithOneShot(shared); | 1122 FloodWithOneShot(shared); |
1112 | 1123 |
1113 // Remember source position and frame to handle step next. | 1124 // Remember source position and frame to handle step next. |
1114 thread_local_.last_statement_position_ = | 1125 thread_local_.last_statement_position_ = |
1115 debug_info->code()->SourceStatementPosition(frame->pc()); | 1126 debug_info->code()->SourceStatementPosition(frame->pc()); |
1116 thread_local_.last_fp_ = frame->fp(); | 1127 thread_local_.last_fp_ = frame->fp(); |
1117 } else { | 1128 } else { |
1118 // Fill the current function with one-shot break points even for step in on | 1129 // Fill the current function with one-shot break points even for step in on |
1119 // a call target as the function called might be a native function for | 1130 // a call target as the function called might be a native function for |
1120 // which step in will not stop. | 1131 // which step in will not stop. It also prepares for stepping in |
| 1132 // getters/setters. |
1121 FloodWithOneShot(shared); | 1133 FloodWithOneShot(shared); |
1122 | 1134 |
| 1135 if (is_load_or_store) { |
| 1136 // Remember source position and frame to handle step in getter/setter. If |
| 1137 // there is a custom getter/setter it will be handled in |
| 1138 // Object::Get/SetPropertyWithCallback, otherwise the step action will be |
| 1139 // propagated on the next Debug::Break. |
| 1140 thread_local_.last_statement_position_ = |
| 1141 debug_info->code()->SourceStatementPosition(frame->pc()); |
| 1142 thread_local_.last_fp_ = frame->fp(); |
| 1143 } |
| 1144 |
1123 // Step in or Step in min | 1145 // Step in or Step in min |
1124 it.PrepareStepIn(); | 1146 it.PrepareStepIn(); |
1125 ActivateStepIn(frame); | 1147 ActivateStepIn(frame); |
1126 } | 1148 } |
1127 } | 1149 } |
1128 | 1150 |
1129 | 1151 |
1130 // Check whether the current debug break should be reported to the debugger. It | 1152 // Check whether the current debug break should be reported to the debugger. It |
1131 // is used to have step next and step in only report break back to the debugger | 1153 // is used to have step next and step in only report break back to the debugger |
1132 // if on a different frame or in a different statement. In some situations | 1154 // if on a different frame or in a different statement. In some situations |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 | 2562 |
2541 | 2563 |
2542 void LockingCommandMessageQueue::Clear() { | 2564 void LockingCommandMessageQueue::Clear() { |
2543 ScopedLock sl(lock_); | 2565 ScopedLock sl(lock_); |
2544 queue_.Clear(); | 2566 queue_.Clear(); |
2545 } | 2567 } |
2546 | 2568 |
2547 #endif // ENABLE_DEBUGGER_SUPPORT | 2569 #endif // ENABLE_DEBUGGER_SUPPORT |
2548 | 2570 |
2549 } } // namespace v8::internal | 2571 } } // namespace v8::internal |
OLD | NEW |