| 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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   310     // Patch the IC call. |   310     // Patch the IC call. | 
|   311     ClearDebugBreakAtIC(); |   311     ClearDebugBreakAtIC(); | 
|   312   } |   312   } | 
|   313   ASSERT(!IsDebugBreak()); |   313   ASSERT(!IsDebugBreak()); | 
|   314 } |   314 } | 
|   315  |   315  | 
|   316  |   316  | 
|   317 void BreakLocationIterator::PrepareStepIn() { |   317 void BreakLocationIterator::PrepareStepIn() { | 
|   318   HandleScope scope; |   318   HandleScope scope; | 
|   319  |   319  | 
|   320   // Step in can only be prepared if currently positioned on an IC call or |   320   // Step in can only be prepared if currently positioned on an IC call, | 
|   321   // construct call. |   321   // construct call or CallFunction stub call. | 
|   322   Address target = rinfo()->target_address(); |   322   Address target = rinfo()->target_address(); | 
|   323   Code* code = Code::GetCodeFromTargetAddress(target); |   323   Handle<Code> code(Code::GetCodeFromTargetAddress(target)); | 
|   324   if (code->is_call_stub()) { |   324   if (code->is_call_stub()) { | 
|   325     // Step in through IC call is handled by the runtime system. Therefore make |   325     // Step in through IC call is handled by the runtime system. Therefore make | 
|   326     // sure that the any current IC is cleared and the runtime system is |   326     // sure that the any current IC is cleared and the runtime system is | 
|   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 #ifdef DEBUG | 
 |   338     Handle<Code> maybe_call_function_stub = code; | 
 |   339     if (IsDebugBreak()) { | 
 |   340       Address original_target = original_rinfo()->target_address(); | 
 |   341       maybe_call_function_stub = | 
 |   342           Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); | 
 |   343     } | 
 |   344     bool is_call_function_stub = | 
 |   345         (maybe_call_function_stub->kind() == Code::STUB && | 
 |   346          maybe_call_function_stub->major_key() == CodeStub::CallFunction); | 
 |   347  | 
|   337     // Step in through construct call requires no changes to the running code. |   348     // Step in through construct call requires no changes to the running code. | 
|   338     // Step in through getters/setters should already be prepared as well |   349     // Step in through getters/setters should already be prepared as well | 
|   339     // because caller of this function (Debug::PrepareStep) is expected to |   350     // because caller of this function (Debug::PrepareStep) is expected to | 
|   340     // flood the top frame's function with one shot breakpoints. |   351     // flood the top frame's function with one shot breakpoints. | 
|   341     ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()); |   352     // Step in through CallFunction stub should also be prepared by caller of | 
 |   353     // this function (Debug::PrepareStep) which should flood target function | 
 |   354     // with breakpoints. | 
 |   355     ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub() | 
 |   356            || is_call_function_stub); | 
 |   357 #endif | 
|   342   } |   358   } | 
|   343 } |   359 } | 
|   344  |   360  | 
|   345  |   361  | 
|   346 // Check whether the break point is at a position which will exit the function. |   362 // Check whether the break point is at a position which will exit the function. | 
|   347 bool BreakLocationIterator::IsExit() const { |   363 bool BreakLocationIterator::IsExit() const { | 
|   348   return (RelocInfo::IsJSReturn(rmode())); |   364   return (RelocInfo::IsJSReturn(rmode())); | 
|   349 } |   365 } | 
|   350  |   366  | 
|   351  |   367  | 
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1085   Handle<DebugInfo> debug_info = GetDebugInfo(shared); |  1101   Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 
|  1086  |  1102  | 
|  1087   // Find the break location where execution has stopped. |  1103   // Find the break location where execution has stopped. | 
|  1088   BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); |  1104   BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); | 
|  1089   it.FindBreakLocationFromAddress(frame->pc()); |  1105   it.FindBreakLocationFromAddress(frame->pc()); | 
|  1090  |  1106  | 
|  1091   // Compute whether or not the target is a call target. |  1107   // Compute whether or not the target is a call target. | 
|  1092   bool is_call_target = false; |  1108   bool is_call_target = false; | 
|  1093   bool is_load_or_store = false; |  1109   bool is_load_or_store = false; | 
|  1094   bool is_inline_cache_stub = false; |  1110   bool is_inline_cache_stub = false; | 
 |  1111   Handle<Code> call_function_stub; | 
|  1095   if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { |  1112   if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { | 
|  1096     Address target = it.rinfo()->target_address(); |  1113     Address target = it.rinfo()->target_address(); | 
|  1097     Code* code = Code::GetCodeFromTargetAddress(target); |  1114     Code* code = Code::GetCodeFromTargetAddress(target); | 
|  1098     if (code->is_call_stub()) { |  1115     if (code->is_call_stub()) { | 
|  1099       is_call_target = true; |  1116       is_call_target = true; | 
|  1100     } |  1117     } | 
|  1101     if (code->is_inline_cache_stub()) { |  1118     if (code->is_inline_cache_stub()) { | 
|  1102       is_inline_cache_stub = true; |  1119       is_inline_cache_stub = true; | 
|  1103       is_load_or_store = !is_call_target; |  1120       is_load_or_store = !is_call_target; | 
|  1104     } |  1121     } | 
 |  1122  | 
 |  1123     // Check if target code is CallFunction stub. | 
 |  1124     Code* maybe_call_function_stub = code; | 
 |  1125     // If there is a breakpoint at this line look at the original code to | 
 |  1126     // check if it is a CallFunction stub. | 
 |  1127     if (it.IsDebugBreak()) { | 
 |  1128       Address original_target = it.original_rinfo()->target_address(); | 
 |  1129       maybe_call_function_stub = | 
 |  1130           Code::GetCodeFromTargetAddress(original_target); | 
 |  1131     } | 
 |  1132     if (maybe_call_function_stub->kind() == Code::STUB && | 
 |  1133         maybe_call_function_stub->major_key() == CodeStub::CallFunction) { | 
 |  1134       // Save reference to the code as we may need it to find out arguments | 
 |  1135       // count for 'step in' later. | 
 |  1136       call_function_stub = Handle<Code>(maybe_call_function_stub); | 
 |  1137     } | 
|  1105   } |  1138   } | 
|  1106  |  1139  | 
|  1107   // If this is the last break code target step out is the only possibility. |  1140   // If this is the last break code target step out is the only possibility. | 
|  1108   if (it.IsExit() || step_action == StepOut) { |  1141   if (it.IsExit() || step_action == StepOut) { | 
|  1109     // Step out: If there is a JavaScript caller frame, we need to |  1142     // Step out: If there is a JavaScript caller frame, we need to | 
|  1110     // flood it with breakpoints. |  1143     // flood it with breakpoints. | 
|  1111     frames_it.Advance(); |  1144     frames_it.Advance(); | 
|  1112     if (!frames_it.done()) { |  1145     if (!frames_it.done()) { | 
|  1113       // Fill the function to return to with one-shot break points. |  1146       // Fill the function to return to with one-shot break points. | 
|  1114       JSFunction* function = JSFunction::cast(frames_it.frame()->function()); |  1147       JSFunction* function = JSFunction::cast(frames_it.frame()->function()); | 
|  1115       FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); |  1148       FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); | 
|  1116     } |  1149     } | 
|  1117   } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode())) |  1150   } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || | 
 |  1151                !call_function_stub.is_null()) | 
|  1118              || step_action == StepNext || step_action == StepMin) { |  1152              || step_action == StepNext || step_action == StepMin) { | 
|  1119     // Step next or step min. |  1153     // Step next or step min. | 
|  1120  |  1154  | 
|  1121     // Fill the current function with one-shot break points. |  1155     // Fill the current function with one-shot break points. | 
|  1122     FloodWithOneShot(shared); |  1156     FloodWithOneShot(shared); | 
|  1123  |  1157  | 
|  1124     // Remember source position and frame to handle step next. |  1158     // Remember source position and frame to handle step next. | 
|  1125     thread_local_.last_statement_position_ = |  1159     thread_local_.last_statement_position_ = | 
|  1126         debug_info->code()->SourceStatementPosition(frame->pc()); |  1160         debug_info->code()->SourceStatementPosition(frame->pc()); | 
|  1127     thread_local_.last_fp_ = frame->fp(); |  1161     thread_local_.last_fp_ = frame->fp(); | 
|  1128   } else { |  1162   } else { | 
 |  1163     // If it's CallFunction stub ensure target function is compiled and flood | 
 |  1164     // it with one shot breakpoints. | 
 |  1165     if (!call_function_stub.is_null()) { | 
 |  1166       // Find out number of arguments from the stub minor key. | 
 |  1167       // Reverse lookup required as the minor key cannot be retrieved | 
 |  1168       // from the code object. | 
 |  1169       Handle<Object> obj( | 
 |  1170           Heap::code_stubs()->SlowReverseLookup(*call_function_stub)); | 
 |  1171       ASSERT(*obj != Heap::undefined_value()); | 
 |  1172       ASSERT(obj->IsSmi()); | 
 |  1173       // Get the STUB key and extract major and minor key. | 
 |  1174       uint32_t key = Smi::cast(*obj)->value(); | 
 |  1175       int call_function_arg_count = CodeStub::MinorKeyFromKey(key); | 
 |  1176       ASSERT(call_function_stub->major_key() == | 
 |  1177              CodeStub::MajorKeyFromKey(key)); | 
 |  1178  | 
 |  1179       // Find target function on the expression stack. | 
 |  1180       // Expression stack lools like this (top to bottom): | 
 |  1181       // argN | 
 |  1182       // ... | 
 |  1183       // arg0 | 
 |  1184       // Receiver | 
 |  1185       // Function to call | 
 |  1186       int expressions_count = frame->ComputeExpressionsCount(); | 
 |  1187       ASSERT(expressions_count - 2 - call_function_arg_count >= 0); | 
 |  1188       Object* fun = frame->GetExpression( | 
 |  1189           expressions_count - 2 - call_function_arg_count); | 
 |  1190       if (fun->IsJSFunction()) { | 
 |  1191         Handle<JSFunction> js_function(JSFunction::cast(fun)); | 
 |  1192         // Don't step into builtins. | 
 |  1193         if (!js_function->IsBuiltin()) { | 
 |  1194           // It will also compile target function if it's not compiled yet. | 
 |  1195           FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared())); | 
 |  1196         } | 
 |  1197       } | 
 |  1198     } | 
 |  1199  | 
|  1129     // Fill the current function with one-shot break points even for step in on |  1200     // 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 |  1201     // 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 |  1202     // which step in will not stop. It also prepares for stepping in | 
|  1132     // getters/setters. |  1203     // getters/setters. | 
|  1133     FloodWithOneShot(shared); |  1204     FloodWithOneShot(shared); | 
|  1134  |  1205  | 
|  1135     if (is_load_or_store) { |  1206     if (is_load_or_store) { | 
|  1136       // Remember source position and frame to handle step in getter/setter. If |  1207       // Remember source position and frame to handle step in getter/setter. If | 
|  1137       // there is a custom getter/setter it will be handled in |  1208       // there is a custom getter/setter it will be handled in | 
|  1138       // Object::Get/SetPropertyWithCallback, otherwise the step action will be |  1209       // Object::Get/SetPropertyWithCallback, otherwise the step action will be | 
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2565  |  2636  | 
|  2566  |  2637  | 
|  2567 void LockingCommandMessageQueue::Clear() { |  2638 void LockingCommandMessageQueue::Clear() { | 
|  2568   ScopedLock sl(lock_); |  2639   ScopedLock sl(lock_); | 
|  2569   queue_.Clear(); |  2640   queue_.Clear(); | 
|  2570 } |  2641 } | 
|  2571  |  2642  | 
|  2572 #endif  // ENABLE_DEBUGGER_SUPPORT |  2643 #endif  // ENABLE_DEBUGGER_SUPPORT | 
|  2573  |  2644  | 
|  2574 } }  // namespace v8::internal |  2645 } }  // namespace v8::internal | 
| OLD | NEW |