OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 rinfo()->data() - debug_info_->shared()->start_position()); | 113 rinfo()->data() - debug_info_->shared()->start_position()); |
114 } | 114 } |
115 // Always update the position as we don't want that to be before the | 115 // Always update the position as we don't want that to be before the |
116 // statement position. | 116 // statement position. |
117 position_ = static_cast<int>( | 117 position_ = static_cast<int>( |
118 rinfo()->data() - debug_info_->shared()->start_position()); | 118 rinfo()->data() - debug_info_->shared()->start_position()); |
119 DCHECK(position_ >= 0); | 119 DCHECK(position_ >= 0); |
120 DCHECK(statement_position_ >= 0); | 120 DCHECK(statement_position_ >= 0); |
121 } | 121 } |
122 | 122 |
123 if (IsDebugBreakSlot()) { | 123 // Check for break at return. |
124 // There is always a possible break point at a debug break slot. | 124 if (RelocInfo::IsJSReturn(rmode())) { |
| 125 // Set the positions to the end of the function. |
| 126 if (debug_info_->shared()->HasSourceCode()) { |
| 127 position_ = debug_info_->shared()->end_position() - |
| 128 debug_info_->shared()->start_position() - 1; |
| 129 } else { |
| 130 position_ = 0; |
| 131 } |
| 132 statement_position_ = position_; |
125 break_point_++; | 133 break_point_++; |
126 return; | 134 return; |
127 } else if (RelocInfo::IsCodeTarget(rmode())) { | 135 } |
| 136 |
| 137 if (RelocInfo::IsCodeTarget(rmode())) { |
128 // Check for breakable code target. Look in the original code as setting | 138 // Check for breakable code target. Look in the original code as setting |
129 // break points can cause the code targets in the running (debugged) code | 139 // break points can cause the code targets in the running (debugged) code |
130 // to be of a different kind than in the original code. | 140 // to be of a different kind than in the original code. |
131 Address target = original_rinfo()->target_address(); | 141 Address target = original_rinfo()->target_address(); |
132 Code* code = Code::GetCodeFromTargetAddress(target); | 142 Code* code = Code::GetCodeFromTargetAddress(target); |
133 if ((code->is_inline_cache_stub() && | 143 |
134 !code->is_binary_op_stub() && | 144 if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { |
135 !code->is_compare_ic_stub() && | |
136 !code->is_to_boolean_ic_stub()) || | |
137 RelocInfo::IsConstructCall(rmode())) { | |
138 break_point_++; | 145 break_point_++; |
139 return; | 146 return; |
140 } | 147 } |
| 148 |
| 149 // Skip below if we only want locations for calls and returns. |
| 150 if (type_ == CALLS_AND_RETURNS) continue; |
| 151 |
| 152 if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && |
| 153 !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { |
| 154 break_point_++; |
| 155 return; |
| 156 } |
141 if (code->kind() == Code::STUB) { | 157 if (code->kind() == Code::STUB) { |
142 if (IsDebuggerStatement()) { | 158 if (IsDebuggerStatement()) { |
143 break_point_++; | 159 break_point_++; |
144 return; | 160 return; |
145 } else if (type_ == ALL_BREAK_LOCATIONS) { | 161 } else if (type_ == ALL_BREAK_LOCATIONS) { |
146 if (IsBreakStub(code)) { | 162 if (IsBreakStub(code)) { |
147 break_point_++; | 163 break_point_++; |
148 return; | 164 return; |
149 } | 165 } |
150 } else { | 166 } else { |
151 DCHECK(type_ == SOURCE_BREAK_LOCATIONS); | 167 DCHECK(type_ == SOURCE_BREAK_LOCATIONS); |
152 if (IsSourceBreakStub(code)) { | 168 if (IsSourceBreakStub(code)) { |
153 break_point_++; | 169 break_point_++; |
154 return; | 170 return; |
155 } | 171 } |
156 } | 172 } |
157 } | 173 } |
158 } | 174 } |
159 | 175 |
160 // Check for break at return. | 176 if (IsDebugBreakSlot() && type_ != CALLS_AND_RETURNS) { |
161 if (RelocInfo::IsJSReturn(rmode())) { | 177 // There is always a possible break point at a debug break slot. |
162 // Set the positions to the end of the function. | |
163 if (debug_info_->shared()->HasSourceCode()) { | |
164 position_ = debug_info_->shared()->end_position() - | |
165 debug_info_->shared()->start_position() - 1; | |
166 } else { | |
167 position_ = 0; | |
168 } | |
169 statement_position_ = position_; | |
170 break_point_++; | 178 break_point_++; |
171 return; | 179 return; |
172 } | 180 } |
173 } | 181 } |
174 } | 182 } |
175 | 183 |
176 | 184 |
177 void BreakLocationIterator::Next(int count) { | 185 void BreakLocationIterator::Next(int count) { |
178 while (count > 0) { | 186 while (count > 0) { |
179 Next(); | 187 Next(); |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 node = node->next(); | 1190 node = node->next(); |
1183 } | 1191 } |
1184 | 1192 |
1185 // Remove all debug info. | 1193 // Remove all debug info. |
1186 while (debug_info_list_ != NULL) { | 1194 while (debug_info_list_ != NULL) { |
1187 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); | 1195 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); |
1188 } | 1196 } |
1189 } | 1197 } |
1190 | 1198 |
1191 | 1199 |
1192 void Debug::FloodWithOneShot(Handle<JSFunction> function) { | 1200 void Debug::FloodWithOneShot(Handle<JSFunction> function, |
| 1201 BreakLocatorType type) { |
1193 PrepareForBreakPoints(); | 1202 PrepareForBreakPoints(); |
1194 | 1203 |
1195 // Make sure the function is compiled and has set up the debug info. | 1204 // Make sure the function is compiled and has set up the debug info. |
1196 Handle<SharedFunctionInfo> shared(function->shared()); | 1205 Handle<SharedFunctionInfo> shared(function->shared()); |
1197 if (!EnsureDebugInfo(shared, function)) { | 1206 if (!EnsureDebugInfo(shared, function)) { |
1198 // Return if we failed to retrieve the debug info. | 1207 // Return if we failed to retrieve the debug info. |
1199 return; | 1208 return; |
1200 } | 1209 } |
1201 | 1210 |
1202 // Flood the function with break points. | 1211 // Flood the function with break points. |
1203 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); | 1212 BreakLocationIterator it(GetDebugInfo(shared), type); |
1204 while (!it.Done()) { | 1213 while (!it.Done()) { |
1205 it.SetOneShot(); | 1214 it.SetOneShot(); |
1206 it.Next(); | 1215 it.Next(); |
1207 } | 1216 } |
1208 } | 1217 } |
1209 | 1218 |
1210 | 1219 |
1211 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { | 1220 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { |
1212 Handle<FixedArray> new_bindings(function->function_bindings()); | 1221 Handle<FixedArray> new_bindings(function->function_bindings()); |
1213 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex), | 1222 Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex), |
1214 isolate_); | 1223 isolate_); |
1215 | 1224 |
1216 if (!bindee.is_null() && bindee->IsJSFunction() && | 1225 if (!bindee.is_null() && bindee->IsJSFunction() && |
1217 !JSFunction::cast(*bindee)->IsFromNativeScript()) { | 1226 !JSFunction::cast(*bindee)->IsFromNativeScript()) { |
1218 Handle<JSFunction> bindee_function(JSFunction::cast(*bindee)); | 1227 Handle<JSFunction> bindee_function(JSFunction::cast(*bindee)); |
1219 Debug::FloodWithOneShot(bindee_function); | 1228 FloodWithOneShot(bindee_function); |
1220 } | 1229 } |
1221 } | 1230 } |
1222 | 1231 |
1223 | 1232 |
1224 void Debug::FloodHandlerWithOneShot() { | 1233 void Debug::FloodHandlerWithOneShot() { |
1225 // Iterate through the JavaScript stack looking for handlers. | 1234 // Iterate through the JavaScript stack looking for handlers. |
1226 StackFrame::Id id = break_frame_id(); | 1235 StackFrame::Id id = break_frame_id(); |
1227 if (id == StackFrame::NO_ID) { | 1236 if (id == StackFrame::NO_ID) { |
1228 // If there is no JavaScript stack don't do anything. | 1237 // If there is no JavaScript stack don't do anything. |
1229 return; | 1238 return; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 id = frame_id; | 1298 id = frame_id; |
1290 } | 1299 } |
1291 JavaScriptFrameIterator frames_it(isolate_, id); | 1300 JavaScriptFrameIterator frames_it(isolate_, id); |
1292 JavaScriptFrame* frame = frames_it.frame(); | 1301 JavaScriptFrame* frame = frames_it.frame(); |
1293 | 1302 |
1294 // First of all ensure there is one-shot break points in the top handler | 1303 // First of all ensure there is one-shot break points in the top handler |
1295 // if any. | 1304 // if any. |
1296 FloodHandlerWithOneShot(); | 1305 FloodHandlerWithOneShot(); |
1297 | 1306 |
1298 // If the function on the top frame is unresolved perform step out. This will | 1307 // If the function on the top frame is unresolved perform step out. This will |
1299 // be the case when calling unknown functions and having the debugger stopped | 1308 // be the case when calling unknown function and having the debugger stopped |
1300 // in an unhandled exception. | 1309 // in an unhandled exception. |
1301 if (!frame->function()->IsJSFunction()) { | 1310 if (!frame->function()->IsJSFunction()) { |
1302 // Step out: Find the calling JavaScript frame and flood it with | 1311 // Step out: Find the calling JavaScript frame and flood it with |
1303 // breakpoints. | 1312 // breakpoints. |
1304 frames_it.Advance(); | 1313 frames_it.Advance(); |
1305 // Fill the function to return to with one-shot break points. | 1314 // Fill the function to return to with one-shot break points. |
1306 JSFunction* function = frames_it.frame()->function(); | 1315 JSFunction* function = frames_it.frame()->function(); |
1307 FloodWithOneShot(Handle<JSFunction>(function)); | 1316 FloodWithOneShot(Handle<JSFunction>(function)); |
1308 return; | 1317 return; |
1309 } | 1318 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 // If there is a breakpoint at this line look at the original code to | 1356 // If there is a breakpoint at this line look at the original code to |
1348 // check if it is a CallFunction stub. | 1357 // check if it is a CallFunction stub. |
1349 if (it.IsDebugBreak()) { | 1358 if (it.IsDebugBreak()) { |
1350 Address original_target = it.original_rinfo()->target_address(); | 1359 Address original_target = it.original_rinfo()->target_address(); |
1351 maybe_call_function_stub = | 1360 maybe_call_function_stub = |
1352 Code::GetCodeFromTargetAddress(original_target); | 1361 Code::GetCodeFromTargetAddress(original_target); |
1353 } | 1362 } |
1354 if ((maybe_call_function_stub->kind() == Code::STUB && | 1363 if ((maybe_call_function_stub->kind() == Code::STUB && |
1355 CodeStub::GetMajorKey(maybe_call_function_stub) == | 1364 CodeStub::GetMajorKey(maybe_call_function_stub) == |
1356 CodeStub::CallFunction) || | 1365 CodeStub::CallFunction) || |
1357 maybe_call_function_stub->kind() == Code::CALL_IC) { | 1366 maybe_call_function_stub->is_call_stub()) { |
1358 // Save reference to the code as we may need it to find out arguments | 1367 // Save reference to the code as we may need it to find out arguments |
1359 // count for 'step in' later. | 1368 // count for 'step in' later. |
1360 call_function_stub = Handle<Code>(maybe_call_function_stub); | 1369 call_function_stub = Handle<Code>(maybe_call_function_stub); |
1361 } | 1370 } |
1362 } | 1371 } |
1363 } else { | 1372 } else { |
1364 is_at_restarted_function = true; | 1373 is_at_restarted_function = true; |
1365 } | 1374 } |
1366 | 1375 |
1367 // If this is the last break code target step out is the only possibility. | 1376 // If this is the last break code target step out is the only possibility. |
(...skipping 20 matching lines...) Expand all Loading... |
1388 FloodWithOneShot(Handle<JSFunction>(function)); | 1397 FloodWithOneShot(Handle<JSFunction>(function)); |
1389 // Set target frame pointer. | 1398 // Set target frame pointer. |
1390 ActivateStepOut(frames_it.frame()); | 1399 ActivateStepOut(frames_it.frame()); |
1391 } | 1400 } |
1392 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || | 1401 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || |
1393 !call_function_stub.is_null() || is_at_restarted_function) | 1402 !call_function_stub.is_null() || is_at_restarted_function) |
1394 || step_action == StepNext || step_action == StepMin) { | 1403 || step_action == StepNext || step_action == StepMin) { |
1395 // Step next or step min. | 1404 // Step next or step min. |
1396 | 1405 |
1397 // Fill the current function with one-shot break points. | 1406 // Fill the current function with one-shot break points. |
1398 FloodWithOneShot(function); | 1407 // If we are stepping into another frame, only fill calls and returns. |
| 1408 FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS |
| 1409 : ALL_BREAK_LOCATIONS); |
1399 | 1410 |
1400 // Remember source position and frame to handle step next. | 1411 // Remember source position and frame to handle step next. |
1401 thread_local_.last_statement_position_ = | 1412 thread_local_.last_statement_position_ = |
1402 debug_info->code()->SourceStatementPosition(frame->pc()); | 1413 debug_info->code()->SourceStatementPosition(frame->pc()); |
1403 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1414 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1404 } else { | 1415 } else { |
1405 // If there's restarter frame on top of the stack, just get the pointer | 1416 // If there's restarter frame on top of the stack, just get the pointer |
1406 // to function which is going to be restarted. | 1417 // to function which is going to be restarted. |
1407 if (is_at_restarted_function) { | 1418 if (is_at_restarted_function) { |
1408 Handle<JSFunction> restarted_function( | 1419 Handle<JSFunction> restarted_function( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 Code* code = JSFunction::cast(fun)->shared()->code(); | 1458 Code* code = JSFunction::cast(fun)->shared()->code(); |
1448 if (code != apply && code != call) break; | 1459 if (code != apply && code != call) break; |
1449 fun = frame->GetExpression( | 1460 fun = frame->GetExpression( |
1450 expressions_count - 1 - call_function_arg_count); | 1461 expressions_count - 1 - call_function_arg_count); |
1451 } | 1462 } |
1452 } | 1463 } |
1453 | 1464 |
1454 if (fun->IsJSFunction()) { | 1465 if (fun->IsJSFunction()) { |
1455 Handle<JSFunction> js_function(JSFunction::cast(fun)); | 1466 Handle<JSFunction> js_function(JSFunction::cast(fun)); |
1456 if (js_function->shared()->bound()) { | 1467 if (js_function->shared()->bound()) { |
1457 Debug::FloodBoundFunctionWithOneShot(js_function); | 1468 FloodBoundFunctionWithOneShot(js_function); |
1458 } else if (!js_function->IsFromNativeScript()) { | 1469 } else if (!js_function->IsFromNativeScript()) { |
1459 // Don't step into builtins. | 1470 // Don't step into builtins. |
1460 // It will also compile target function if it's not compiled yet. | 1471 // It will also compile target function if it's not compiled yet. |
1461 FloodWithOneShot(js_function); | 1472 FloodWithOneShot(js_function); |
1462 } | 1473 } |
1463 } | 1474 } |
1464 } | 1475 } |
1465 | 1476 |
1466 // Fill the current function with one-shot break points even for step in on | 1477 // Fill the current function with one-shot break points even for step in on |
1467 // a call target as the function called might be a native function for | 1478 // a call target as the function called might be a native function for |
1468 // which step in will not stop. It also prepares for stepping in | 1479 // which step in will not stop. It also prepares for stepping in |
1469 // getters/setters. | 1480 // getters/setters. |
1470 FloodWithOneShot(function); | 1481 // If we are stepping into another frame, only fill calls and returns. |
| 1482 FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS |
| 1483 : ALL_BREAK_LOCATIONS); |
1471 | 1484 |
1472 if (is_load_or_store) { | 1485 if (is_load_or_store) { |
1473 // Remember source position and frame to handle step in getter/setter. If | 1486 // Remember source position and frame to handle step in getter/setter. If |
1474 // there is a custom getter/setter it will be handled in | 1487 // there is a custom getter/setter it will be handled in |
1475 // Object::Get/SetPropertyWithAccessor, otherwise the step action will be | 1488 // Object::Get/SetPropertyWithAccessor, otherwise the step action will be |
1476 // propagated on the next Debug::Break. | 1489 // propagated on the next Debug::Break. |
1477 thread_local_.last_statement_position_ = | 1490 thread_local_.last_statement_position_ = |
1478 debug_info->code()->SourceStatementPosition(frame->pc()); | 1491 debug_info->code()->SourceStatementPosition(frame->pc()); |
1479 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1492 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1480 } | 1493 } |
1481 | 1494 |
1482 // Step in or Step in min | 1495 // Step in or Step in min |
1483 it.PrepareStepIn(isolate_); | 1496 it.PrepareStepIn(isolate_); |
1484 ActivateStepIn(frame); | 1497 ActivateStepIn(frame); |
1485 } | 1498 } |
1486 } | 1499 } |
1487 | 1500 |
1488 | 1501 |
1489 // Check whether the current debug break should be reported to the debugger. It | 1502 // Check whether the current debug break should be reported to the debugger. It |
1490 // is used to have step next and step in only report break back to the debugger | 1503 // is used to have step next and step in only report break back to the debugger |
1491 // if on a different frame or in a different statement. In some situations | 1504 // if on a different frame or in a different statement. In some situations |
1492 // there will be several break points in the same statement when the code is | 1505 // there will be several break points in the same statement when the code is |
1493 // flooded with one-shot break points. This function helps to perform several | 1506 // flooded with one-shot break points. This function helps to perform several |
1494 // steps before reporting break back to the debugger. | 1507 // steps before reporting break back to the debugger. |
1495 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, | 1508 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, |
1496 JavaScriptFrame* frame) { | 1509 JavaScriptFrame* frame) { |
1497 // StepNext and StepOut shouldn't bring us deeper in code, so last frame | 1510 // StepNext and StepOut shouldn't bring us deeper in code, so last frame |
1498 // shouldn't be a parent of current frame. | 1511 // shouldn't be a parent of current frame. |
1499 if (thread_local_.last_step_action_ == StepNext || | 1512 StepAction step_action = thread_local_.last_step_action_; |
1500 thread_local_.last_step_action_ == StepOut) { | 1513 |
| 1514 if (step_action == StepNext || step_action == StepOut) { |
1501 if (frame->fp() < thread_local_.last_fp_) return true; | 1515 if (frame->fp() < thread_local_.last_fp_) return true; |
1502 } | 1516 } |
1503 | 1517 |
| 1518 // We stepped into a new frame if the frame pointer changed. |
| 1519 if (step_action == StepFrame) { |
| 1520 return frame->UnpaddedFP() == thread_local_.last_fp_; |
| 1521 } |
| 1522 |
1504 // If the step last action was step next or step in make sure that a new | 1523 // If the step last action was step next or step in make sure that a new |
1505 // statement is hit. | 1524 // statement is hit. |
1506 if (thread_local_.last_step_action_ == StepNext || | 1525 if (step_action == StepNext || step_action == StepIn) { |
1507 thread_local_.last_step_action_ == StepIn) { | |
1508 // Never continue if returning from function. | 1526 // Never continue if returning from function. |
1509 if (break_location_iterator->IsExit()) return false; | 1527 if (break_location_iterator->IsExit()) return false; |
1510 | 1528 |
1511 // Continue if we are still on the same frame and in the same statement. | 1529 // Continue if we are still on the same frame and in the same statement. |
1512 int current_statement_position = | 1530 int current_statement_position = |
1513 break_location_iterator->code()->SourceStatementPosition(frame->pc()); | 1531 break_location_iterator->code()->SourceStatementPosition(frame->pc()); |
1514 return thread_local_.last_fp_ == frame->UnpaddedFP() && | 1532 return thread_local_.last_fp_ == frame->UnpaddedFP() && |
1515 thread_local_.last_statement_position_ == current_statement_position; | 1533 thread_local_.last_statement_position_ == current_statement_position; |
1516 } | 1534 } |
1517 | 1535 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 | 1582 |
1565 locations->set(count++, position); | 1583 locations->set(count++, position); |
1566 } | 1584 } |
1567 } | 1585 } |
1568 } | 1586 } |
1569 return locations; | 1587 return locations; |
1570 } | 1588 } |
1571 | 1589 |
1572 | 1590 |
1573 // Handle stepping into a function. | 1591 // Handle stepping into a function. |
1574 void Debug::HandleStepIn(Handle<JSFunction> function, | 1592 void Debug::HandleStepIn(Handle<Object> function_obj, Handle<Object> holder, |
1575 Handle<Object> holder, | 1593 Address fp, bool is_constructor) { |
1576 Address fp, | 1594 // Flood getter/setter if we either step in or step to another frame. |
1577 bool is_constructor) { | 1595 bool step_frame = thread_local_.last_step_action_ == StepFrame; |
| 1596 if (!StepInActive() && !step_frame) return; |
| 1597 if (!function_obj->IsJSFunction()) return; |
| 1598 Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj); |
1578 Isolate* isolate = function->GetIsolate(); | 1599 Isolate* isolate = function->GetIsolate(); |
1579 // If the frame pointer is not supplied by the caller find it. | 1600 // If the frame pointer is not supplied by the caller find it. |
1580 if (fp == 0) { | 1601 if (fp == 0) { |
1581 StackFrameIterator it(isolate); | 1602 StackFrameIterator it(isolate); |
1582 it.Advance(); | 1603 it.Advance(); |
1583 // For constructor functions skip another frame. | 1604 // For constructor functions skip another frame. |
1584 if (is_constructor) { | 1605 if (is_constructor) { |
1585 DCHECK(it.frame()->is_construct()); | 1606 DCHECK(it.frame()->is_construct()); |
1586 it.Advance(); | 1607 it.Advance(); |
1587 } | 1608 } |
1588 fp = it.frame()->fp(); | 1609 fp = it.frame()->fp(); |
1589 } | 1610 } |
1590 | 1611 |
1591 // Flood the function with one-shot break points if it is called from where | 1612 // Flood the function with one-shot break points if it is called from where |
1592 // step into was requested. | 1613 // step into was requested, or when stepping into a new frame. |
1593 if (fp == thread_local_.step_into_fp_) { | 1614 if (fp == thread_local_.step_into_fp_ || step_frame) { |
1594 if (function->shared()->bound()) { | 1615 if (function->shared()->bound()) { |
1595 // Handle Function.prototype.bind | 1616 // Handle Function.prototype.bind |
1596 Debug::FloodBoundFunctionWithOneShot(function); | 1617 FloodBoundFunctionWithOneShot(function); |
1597 } else if (!function->IsFromNativeScript()) { | 1618 } else if (!function->IsFromNativeScript()) { |
1598 // Don't allow step into functions in the native context. | 1619 // Don't allow step into functions in the native context. |
1599 if (function->shared()->code() == | 1620 if (function->shared()->code() == |
1600 isolate->builtins()->builtin(Builtins::kFunctionApply) || | 1621 isolate->builtins()->builtin(Builtins::kFunctionApply) || |
1601 function->shared()->code() == | 1622 function->shared()->code() == |
1602 isolate->builtins()->builtin(Builtins::kFunctionCall)) { | 1623 isolate->builtins()->builtin(Builtins::kFunctionCall)) { |
1603 // Handle function.apply and function.call separately to flood the | 1624 // Handle function.apply and function.call separately to flood the |
1604 // function to be called and not the code for Builtins::FunctionApply or | 1625 // function to be called and not the code for Builtins::FunctionApply or |
1605 // Builtins::FunctionCall. The receiver of call/apply is the target | 1626 // Builtins::FunctionCall. The receiver of call/apply is the target |
1606 // function. | 1627 // function. |
1607 if (!holder.is_null() && holder->IsJSFunction()) { | 1628 if (!holder.is_null() && holder->IsJSFunction()) { |
1608 Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder); | 1629 Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder); |
1609 if (!js_function->IsFromNativeScript()) { | 1630 if (!js_function->IsFromNativeScript()) { |
1610 Debug::FloodWithOneShot(js_function); | 1631 FloodWithOneShot(js_function); |
1611 } else if (js_function->shared()->bound()) { | 1632 } else if (js_function->shared()->bound()) { |
1612 // Handle Function.prototype.bind | 1633 // Handle Function.prototype.bind |
1613 Debug::FloodBoundFunctionWithOneShot(js_function); | 1634 FloodBoundFunctionWithOneShot(js_function); |
1614 } | 1635 } |
1615 } | 1636 } |
1616 } else { | 1637 } else { |
1617 Debug::FloodWithOneShot(function); | 1638 FloodWithOneShot(function); |
1618 } | 1639 } |
1619 } | 1640 } |
1620 } | 1641 } |
1621 } | 1642 } |
1622 | 1643 |
1623 | 1644 |
1624 void Debug::ClearStepping() { | 1645 void Debug::ClearStepping() { |
1625 // Clear the various stepping setup. | 1646 // Clear the various stepping setup. |
1626 ClearOneShot(); | 1647 ClearOneShot(); |
1627 ClearStepIn(); | 1648 ClearStepIn(); |
(...skipping 1777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 logger_->DebugEvent("Put", message.text()); | 3426 logger_->DebugEvent("Put", message.text()); |
3406 } | 3427 } |
3407 | 3428 |
3408 | 3429 |
3409 void LockingCommandMessageQueue::Clear() { | 3430 void LockingCommandMessageQueue::Clear() { |
3410 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 3431 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
3411 queue_.Clear(); | 3432 queue_.Clear(); |
3412 } | 3433 } |
3413 | 3434 |
3414 } } // namespace v8::internal | 3435 } } // namespace v8::internal |
OLD | NEW |