OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 return change; | 1180 return change; |
1181 } | 1181 } |
1182 | 1182 |
1183 | 1183 |
1184 // Removes specified range of frames from stack. There may be 1 or more | 1184 // Removes specified range of frames from stack. There may be 1 or more |
1185 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1185 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
1186 // and therefore has to be a JavaScript frame. | 1186 // and therefore has to be a JavaScript frame. |
1187 // Returns error message or NULL. | 1187 // Returns error message or NULL. |
1188 static const char* DropFrames(Vector<StackFrame*> frames, | 1188 static const char* DropFrames(Vector<StackFrame*> frames, |
1189 int top_frame_index, | 1189 int top_frame_index, |
1190 int bottom_js_frame_index) { | 1190 int bottom_js_frame_index, |
| 1191 Debug::FrameDropMode* mode) { |
| 1192 if (Debug::kFrameDropperFrameSize < 0) { |
| 1193 return "Stack manipulations are not supported in this architecture."; |
| 1194 } |
| 1195 |
1191 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1196 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
1192 StackFrame* top_frame = frames[top_frame_index]; | 1197 StackFrame* top_frame = frames[top_frame_index]; |
1193 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1198 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
1194 | 1199 |
1195 ASSERT(bottom_js_frame->is_java_script()); | 1200 ASSERT(bottom_js_frame->is_java_script()); |
1196 | 1201 |
1197 // Check the nature of the top frame. | 1202 // Check the nature of the top frame. |
1198 if (pre_top_frame->code()->is_inline_cache_stub() && | 1203 if (pre_top_frame->code()->is_inline_cache_stub() && |
1199 pre_top_frame->code()->ic_state() == DEBUG_BREAK) { | 1204 pre_top_frame->code()->ic_state() == DEBUG_BREAK) { |
1200 // OK, we can drop inline cache calls. | 1205 // OK, we can drop inline cache calls. |
| 1206 *mode = Debug::FRAME_DROPPED_IN_IC_CALL; |
| 1207 } else if (pre_top_frame->code() == Debug::debug_break_slot()) { |
| 1208 // OK, we can drop debug break slot. |
| 1209 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
1201 } else if (pre_top_frame->code() == | 1210 } else if (pre_top_frame->code() == |
1202 Builtins::builtin(Builtins::FrameDropper_LiveEdit)) { | 1211 Builtins::builtin(Builtins::FrameDropper_LiveEdit)) { |
1203 // OK, we can drop our own code. | 1212 // OK, we can drop our own code. |
| 1213 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
1204 } else if (pre_top_frame->code()->kind() == Code::STUB && | 1214 } else if (pre_top_frame->code()->kind() == Code::STUB && |
1205 pre_top_frame->code()->major_key()) { | 1215 pre_top_frame->code()->major_key()) { |
1206 // Unit Test entry, it's fine, we support this case. | 1216 // Entry from our unit tests, it's fine, we support this case. |
| 1217 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
1207 } else { | 1218 } else { |
1208 return "Unknown structure of stack above changing function"; | 1219 return "Unknown structure of stack above changing function"; |
1209 } | 1220 } |
1210 | 1221 |
1211 Address unused_stack_top = top_frame->sp(); | 1222 Address unused_stack_top = top_frame->sp(); |
1212 Address unused_stack_bottom = bottom_js_frame->fp() | 1223 Address unused_stack_bottom = bottom_js_frame->fp() |
1213 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. | 1224 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. |
1214 + kPointerSize; // Bigger address end is exclusive. | 1225 + kPointerSize; // Bigger address end is exclusive. |
1215 | 1226 |
1216 if (unused_stack_top > unused_stack_bottom) { | 1227 if (unused_stack_top > unused_stack_bottom) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 if (!do_drop) { | 1320 if (!do_drop) { |
1310 // We are in check-only mode. | 1321 // We are in check-only mode. |
1311 return NULL; | 1322 return NULL; |
1312 } | 1323 } |
1313 | 1324 |
1314 if (!target_frame_found) { | 1325 if (!target_frame_found) { |
1315 // Nothing to drop. | 1326 // Nothing to drop. |
1316 return NULL; | 1327 return NULL; |
1317 } | 1328 } |
1318 | 1329 |
| 1330 Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED; |
1319 const char* error_message = DropFrames(frames, top_frame_index, | 1331 const char* error_message = DropFrames(frames, top_frame_index, |
1320 bottom_js_frame_index); | 1332 bottom_js_frame_index, &drop_mode); |
1321 | 1333 |
1322 if (error_message != NULL) { | 1334 if (error_message != NULL) { |
1323 return error_message; | 1335 return error_message; |
1324 } | 1336 } |
1325 | 1337 |
1326 // Adjust break_frame after some frames has been dropped. | 1338 // Adjust break_frame after some frames has been dropped. |
1327 StackFrame::Id new_id = StackFrame::NO_ID; | 1339 StackFrame::Id new_id = StackFrame::NO_ID; |
1328 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { | 1340 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { |
1329 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { | 1341 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { |
1330 new_id = frames[i]->id(); | 1342 new_id = frames[i]->id(); |
1331 break; | 1343 break; |
1332 } | 1344 } |
1333 } | 1345 } |
1334 Debug::FramesHaveBeenDropped(new_id); | 1346 Debug::FramesHaveBeenDropped(new_id, drop_mode); |
1335 | 1347 |
1336 // Replace "blocked on active" with "replaced on active" status. | 1348 // Replace "blocked on active" with "replaced on active" status. |
1337 for (int i = 0; i < array_len; i++) { | 1349 for (int i = 0; i < array_len; i++) { |
1338 if (result->GetElement(i) == | 1350 if (result->GetElement(i) == |
1339 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { | 1351 Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) { |
1340 result->SetElement(i, Smi::FromInt( | 1352 result->SetElement(i, Smi::FromInt( |
1341 LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); | 1353 LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK)); |
1342 } | 1354 } |
1343 } | 1355 } |
1344 return NULL; | 1356 return NULL; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 | 1471 |
1460 bool LiveEditFunctionTracker::IsActive() { | 1472 bool LiveEditFunctionTracker::IsActive() { |
1461 return false; | 1473 return false; |
1462 } | 1474 } |
1463 | 1475 |
1464 #endif // ENABLE_DEBUGGER_SUPPORT | 1476 #endif // ENABLE_DEBUGGER_SUPPORT |
1465 | 1477 |
1466 | 1478 |
1467 | 1479 |
1468 } } // namespace v8::internal | 1480 } } // namespace v8::internal |
OLD | NEW |