| 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 | 
|---|