| 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/debug/liveedit.h" | 5 #include "src/debug/liveedit.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 | 647 |
| 648 | 648 |
| 649 Handle<SharedFunctionInfo> SharedInfoWrapper::GetInfo() { | 649 Handle<SharedFunctionInfo> SharedInfoWrapper::GetInfo() { |
| 650 Handle<Object> element = this->GetField(kSharedInfoOffset_); | 650 Handle<Object> element = this->GetField(kSharedInfoOffset_); |
| 651 Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element); | 651 Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element); |
| 652 return UnwrapSharedFunctionInfoFromJSValue(value_wrapper); | 652 return UnwrapSharedFunctionInfoFromJSValue(value_wrapper); |
| 653 } | 653 } |
| 654 | 654 |
| 655 | 655 |
| 656 void LiveEdit::InitializeThreadLocal(Debug* debug) { | 656 void LiveEdit::InitializeThreadLocal(Debug* debug) { |
| 657 debug->thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; | 657 debug->thread_local_.frame_drop_mode_ = LIVE_EDIT_FRAMES_UNTOUCHED; |
| 658 } | 658 } |
| 659 | 659 |
| 660 | 660 |
| 661 bool LiveEdit::SetAfterBreakTarget(Debug* debug) { | 661 bool LiveEdit::SetAfterBreakTarget(Debug* debug) { |
| 662 Code* code = NULL; | 662 Code* code = NULL; |
| 663 Isolate* isolate = debug->isolate_; | 663 Isolate* isolate = debug->isolate_; |
| 664 switch (debug->thread_local_.frame_drop_mode_) { | 664 switch (debug->thread_local_.frame_drop_mode_) { |
| 665 case FRAMES_UNTOUCHED: | 665 case LIVE_EDIT_FRAMES_UNTOUCHED: |
| 666 return false; | 666 return false; |
| 667 case FRAME_DROPPED_IN_DEBUG_SLOT_CALL: | 667 case LIVE_EDIT_FRAME_DROPPED_IN_DEBUG_SLOT_CALL: |
| 668 // Debug break slot stub does not return normally, instead it manually | 668 // Debug break slot stub does not return normally, instead it manually |
| 669 // cleans the stack and jumps. We should patch the jump address. | 669 // cleans the stack and jumps. We should patch the jump address. |
| 670 code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit); | 670 code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit); |
| 671 break; | 671 break; |
| 672 case FRAME_DROPPED_IN_DIRECT_CALL: | 672 case LIVE_EDIT_FRAME_DROPPED_IN_DIRECT_CALL: |
| 673 // Nothing to do, after_break_target is not used here. | 673 // Nothing to do, after_break_target is not used here. |
| 674 return true; | 674 return true; |
| 675 case FRAME_DROPPED_IN_RETURN_CALL: | 675 case LIVE_EDIT_FRAME_DROPPED_IN_RETURN_CALL: |
| 676 code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit); | 676 code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit); |
| 677 break; | 677 break; |
| 678 case CURRENTLY_SET_MODE: | 678 case LIVE_EDIT_CURRENTLY_SET_MODE: |
| 679 UNREACHABLE(); | 679 UNREACHABLE(); |
| 680 break; | 680 break; |
| 681 } | 681 } |
| 682 debug->after_break_target_ = code->entry(); | 682 debug->after_break_target_ = code->entry(); |
| 683 return true; | 683 return true; |
| 684 } | 684 } |
| 685 | 685 |
| 686 | 686 |
| 687 MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script, | 687 MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script, |
| 688 Handle<String> source) { | 688 Handle<String> source) { |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1295 Memory::Object_at(fp + FrameDropperFrameConstants::kCodeOffset) = *code; | 1295 Memory::Object_at(fp + FrameDropperFrameConstants::kCodeOffset) = *code; |
| 1296 } | 1296 } |
| 1297 | 1297 |
| 1298 | 1298 |
| 1299 // Removes specified range of frames from stack. There may be 1 or more | 1299 // Removes specified range of frames from stack. There may be 1 or more |
| 1300 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1300 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
| 1301 // and therefore has to be a JavaScript frame. | 1301 // and therefore has to be a JavaScript frame. |
| 1302 // Returns error message or NULL. | 1302 // Returns error message or NULL. |
| 1303 static const char* DropFrames(Vector<StackFrame*> frames, int top_frame_index, | 1303 static const char* DropFrames(Vector<StackFrame*> frames, int top_frame_index, |
| 1304 int bottom_js_frame_index, | 1304 int bottom_js_frame_index, |
| 1305 LiveEdit::FrameDropMode* mode) { | 1305 LiveEditFrameDropMode* mode) { |
| 1306 if (!LiveEdit::kFrameDropperSupported) { | 1306 if (!LiveEdit::kFrameDropperSupported) { |
| 1307 return "Stack manipulations are not supported in this architecture."; | 1307 return "Stack manipulations are not supported in this architecture."; |
| 1308 } | 1308 } |
| 1309 | 1309 |
| 1310 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1310 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
| 1311 StackFrame* top_frame = frames[top_frame_index]; | 1311 StackFrame* top_frame = frames[top_frame_index]; |
| 1312 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1312 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
| 1313 | 1313 |
| 1314 DCHECK(bottom_js_frame->is_java_script()); | 1314 DCHECK(bottom_js_frame->is_java_script()); |
| 1315 | 1315 |
| 1316 // Check the nature of the top frame. | 1316 // Check the nature of the top frame. |
| 1317 Isolate* isolate = bottom_js_frame->isolate(); | 1317 Isolate* isolate = bottom_js_frame->isolate(); |
| 1318 Code* pre_top_frame_code = pre_top_frame->LookupCode(); | 1318 Code* pre_top_frame_code = pre_top_frame->LookupCode(); |
| 1319 bool frame_has_padding = true; | 1319 bool frame_has_padding = true; |
| 1320 if (pre_top_frame_code == | 1320 if (pre_top_frame_code == |
| 1321 isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) { | 1321 isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) { |
| 1322 // OK, we can drop debug break slot. | 1322 // OK, we can drop debug break slot. |
| 1323 *mode = LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; | 1323 *mode = LIVE_EDIT_FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
| 1324 } else if (pre_top_frame_code == | 1324 } else if (pre_top_frame_code == |
| 1325 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)) { | 1325 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)) { |
| 1326 // OK, we can drop our own code. | 1326 // OK, we can drop our own code. |
| 1327 pre_top_frame = frames[top_frame_index - 2]; | 1327 pre_top_frame = frames[top_frame_index - 2]; |
| 1328 top_frame = frames[top_frame_index - 1]; | 1328 top_frame = frames[top_frame_index - 1]; |
| 1329 *mode = LiveEdit::CURRENTLY_SET_MODE; | 1329 *mode = LIVE_EDIT_CURRENTLY_SET_MODE; |
| 1330 frame_has_padding = false; | 1330 frame_has_padding = false; |
| 1331 } else if (pre_top_frame_code == | 1331 } else if (pre_top_frame_code == |
| 1332 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { | 1332 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { |
| 1333 *mode = LiveEdit::FRAME_DROPPED_IN_RETURN_CALL; | 1333 *mode = LIVE_EDIT_FRAME_DROPPED_IN_RETURN_CALL; |
| 1334 } else if (pre_top_frame_code->kind() == Code::STUB && | 1334 } else if (pre_top_frame_code->kind() == Code::STUB && |
| 1335 CodeStub::GetMajorKey(pre_top_frame_code) == CodeStub::CEntry) { | 1335 CodeStub::GetMajorKey(pre_top_frame_code) == CodeStub::CEntry) { |
| 1336 // Entry from our unit tests on 'debugger' statement. | 1336 // Entry from our unit tests on 'debugger' statement. |
| 1337 // It's fine, we support this case. | 1337 // It's fine, we support this case. |
| 1338 *mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL; | 1338 *mode = LIVE_EDIT_FRAME_DROPPED_IN_DIRECT_CALL; |
| 1339 // We don't have a padding from 'debugger' statement call. | 1339 // We don't have a padding from 'debugger' statement call. |
| 1340 // Here the stub is CEntry, it's not debug-only and can't be padded. | 1340 // Here the stub is CEntry, it's not debug-only and can't be padded. |
| 1341 // If anyone would complain, a proxy padded stub could be added. | 1341 // If anyone would complain, a proxy padded stub could be added. |
| 1342 frame_has_padding = false; | 1342 frame_has_padding = false; |
| 1343 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { | 1343 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { |
| 1344 // This must be adaptor that remain from the frame dropping that | 1344 // This must be adaptor that remain from the frame dropping that |
| 1345 // is still on stack. A frame dropper frame must be above it. | 1345 // is still on stack. A frame dropper frame must be above it. |
| 1346 DCHECK(frames[top_frame_index - 2]->LookupCode() == | 1346 DCHECK(frames[top_frame_index - 2]->LookupCode() == |
| 1347 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); | 1347 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); |
| 1348 pre_top_frame = frames[top_frame_index - 3]; | 1348 pre_top_frame = frames[top_frame_index - 3]; |
| 1349 top_frame = frames[top_frame_index - 2]; | 1349 top_frame = frames[top_frame_index - 2]; |
| 1350 *mode = LiveEdit::CURRENTLY_SET_MODE; | 1350 *mode = LIVE_EDIT_CURRENTLY_SET_MODE; |
| 1351 frame_has_padding = false; | 1351 frame_has_padding = false; |
| 1352 } else if (pre_top_frame_code->kind() == Code::BYTECODE_HANDLER) { | 1352 } else if (pre_top_frame_code->kind() == Code::BYTECODE_HANDLER) { |
| 1353 // Interpreted bytecode takes up two stack frames, one for the bytecode | 1353 // Interpreted bytecode takes up two stack frames, one for the bytecode |
| 1354 // handler and one for the interpreter entry trampoline. Therefore we shift | 1354 // handler and one for the interpreter entry trampoline. Therefore we shift |
| 1355 // up by one frame. | 1355 // up by one frame. |
| 1356 *mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL; | 1356 *mode = LIVE_EDIT_FRAME_DROPPED_IN_DIRECT_CALL; |
| 1357 pre_top_frame = frames[top_frame_index - 2]; | 1357 pre_top_frame = frames[top_frame_index - 2]; |
| 1358 top_frame = frames[top_frame_index - 1]; | 1358 top_frame = frames[top_frame_index - 1]; |
| 1359 } else { | 1359 } else { |
| 1360 return "Unknown structure of stack above changing function"; | 1360 return "Unknown structure of stack above changing function"; |
| 1361 } | 1361 } |
| 1362 | 1362 |
| 1363 Address unused_stack_top = top_frame->sp(); | 1363 Address unused_stack_top = top_frame->sp(); |
| 1364 Address unused_stack_bottom = | 1364 Address unused_stack_bottom = |
| 1365 bottom_js_frame->fp() - FrameDropperFrameConstants::kFixedFrameSize + | 1365 bottom_js_frame->fp() - FrameDropperFrameConstants::kFixedFrameSize + |
| 1366 2 * kPointerSize; // Bigger address end is exclusive. | 1366 2 * kPointerSize; // Bigger address end is exclusive. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 if (!do_drop) { | 1597 if (!do_drop) { |
| 1598 // We are in check-only mode. | 1598 // We are in check-only mode. |
| 1599 return NULL; | 1599 return NULL; |
| 1600 } | 1600 } |
| 1601 | 1601 |
| 1602 if (!target_frame_found) { | 1602 if (!target_frame_found) { |
| 1603 // Nothing to drop. | 1603 // Nothing to drop. |
| 1604 return target.GetNotFoundMessage(); | 1604 return target.GetNotFoundMessage(); |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 LiveEdit::FrameDropMode drop_mode = LiveEdit::FRAMES_UNTOUCHED; | 1607 LiveEditFrameDropMode drop_mode = LIVE_EDIT_FRAMES_UNTOUCHED; |
| 1608 const char* error_message = | 1608 const char* error_message = |
| 1609 DropFrames(frames, top_frame_index, bottom_js_frame_index, &drop_mode); | 1609 DropFrames(frames, top_frame_index, bottom_js_frame_index, &drop_mode); |
| 1610 | 1610 |
| 1611 if (error_message != NULL) { | 1611 if (error_message != NULL) { |
| 1612 return error_message; | 1612 return error_message; |
| 1613 } | 1613 } |
| 1614 | 1614 |
| 1615 // Adjust break_frame after some frames has been dropped. | 1615 // Adjust break_frame after some frames has been dropped. |
| 1616 StackFrame::Id new_id = StackFrame::NO_ID; | 1616 StackFrame::Id new_id = StackFrame::NO_ID; |
| 1617 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { | 1617 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 scope_info_length++; | 1915 scope_info_length++; |
| 1916 | 1916 |
| 1917 current_scope = current_scope->outer_scope(); | 1917 current_scope = current_scope->outer_scope(); |
| 1918 } | 1918 } |
| 1919 | 1919 |
| 1920 return scope_info_list; | 1920 return scope_info_list; |
| 1921 } | 1921 } |
| 1922 | 1922 |
| 1923 } // namespace internal | 1923 } // namespace internal |
| 1924 } // namespace v8 | 1924 } // namespace v8 |
| OLD | NEW |