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