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/scopeinfo.h" | 7 #include "src/ast/scopeinfo.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 pointer_address = &Memory::Address_at(*pointer_address); | 1478 pointer_address = &Memory::Address_at(*pointer_address); |
1479 } | 1479 } |
1480 bool change = *above_frame_address != *pointer_address; | 1480 bool change = *above_frame_address != *pointer_address; |
1481 *above_frame_address = *pointer_address; | 1481 *above_frame_address = *pointer_address; |
1482 return change; | 1482 return change; |
1483 } | 1483 } |
1484 | 1484 |
1485 | 1485 |
1486 // Initializes an artificial stack frame. The data it contains is used for: | 1486 // Initializes an artificial stack frame. The data it contains is used for: |
1487 // a. successful work of frame dropper code which eventually gets control, | 1487 // a. successful work of frame dropper code which eventually gets control, |
1488 // b. being compatible with regular stack structure for various stack | 1488 // b. being compatible with a typed frame structure for various stack |
1489 // iterators. | 1489 // iterators. |
1490 // Frame structure (conforms InternalFrame structure): | 1490 // Frame structure (conforms to InternalFrame structure): |
| 1491 // -- function |
1491 // -- code | 1492 // -- code |
1492 // -- SMI maker | 1493 // -- SMI marker |
1493 // -- function (slot is called "context") | |
1494 // -- frame base | 1494 // -- frame base |
1495 static void SetUpFrameDropperFrame(StackFrame* bottom_js_frame, | 1495 static void SetUpFrameDropperFrame(StackFrame* bottom_js_frame, |
1496 Handle<Code> code) { | 1496 Handle<Code> code) { |
1497 DCHECK(bottom_js_frame->is_java_script()); | 1497 DCHECK(bottom_js_frame->is_java_script()); |
1498 | |
1499 Address fp = bottom_js_frame->fp(); | 1498 Address fp = bottom_js_frame->fp(); |
1500 | 1499 Memory::Object_at(fp + FrameDropperFrameConstants::kFunctionOffset) = |
1501 // Move function pointer into "context" slot. | 1500 Memory::Object_at(fp + StandardFrameConstants::kFunctionOffset); |
1502 Memory::Object_at(fp + StandardFrameConstants::kContextOffset) = | 1501 Memory::Object_at(fp + FrameDropperFrameConstants::kFrameTypeOffset) = |
1503 Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset); | |
1504 | |
1505 Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code; | |
1506 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) = | |
1507 Smi::FromInt(StackFrame::INTERNAL); | 1502 Smi::FromInt(StackFrame::INTERNAL); |
| 1503 Memory::Object_at(fp + FrameDropperFrameConstants::kCodeOffset) = *code; |
1508 } | 1504 } |
1509 | 1505 |
1510 | 1506 |
1511 // Removes specified range of frames from stack. There may be 1 or more | 1507 // Removes specified range of frames from stack. There may be 1 or more |
1512 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1508 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
1513 // and therefore has to be a JavaScript frame. | 1509 // and therefore has to be a JavaScript frame. |
1514 // Returns error message or NULL. | 1510 // Returns error message or NULL. |
1515 static const char* DropFrames(Vector<StackFrame*> frames, int top_frame_index, | 1511 static const char* DropFrames(Vector<StackFrame*> frames, int top_frame_index, |
1516 int bottom_js_frame_index, | 1512 int bottom_js_frame_index, |
1517 LiveEdit::FrameDropMode* mode) { | 1513 LiveEdit::FrameDropMode* mode) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); | 1555 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); |
1560 pre_top_frame = frames[top_frame_index - 3]; | 1556 pre_top_frame = frames[top_frame_index - 3]; |
1561 top_frame = frames[top_frame_index - 2]; | 1557 top_frame = frames[top_frame_index - 2]; |
1562 *mode = LiveEdit::CURRENTLY_SET_MODE; | 1558 *mode = LiveEdit::CURRENTLY_SET_MODE; |
1563 frame_has_padding = false; | 1559 frame_has_padding = false; |
1564 } else { | 1560 } else { |
1565 return "Unknown structure of stack above changing function"; | 1561 return "Unknown structure of stack above changing function"; |
1566 } | 1562 } |
1567 | 1563 |
1568 Address unused_stack_top = top_frame->sp(); | 1564 Address unused_stack_top = top_frame->sp(); |
1569 int new_frame_size = LiveEdit::kFrameDropperFrameSize * kPointerSize; | 1565 Address unused_stack_bottom = |
1570 Address unused_stack_bottom = bottom_js_frame->fp() | 1566 bottom_js_frame->fp() - FrameDropperFrameConstants::kFixedFrameSize + |
1571 - new_frame_size + kPointerSize; // Bigger address end is exclusive. | 1567 2 * kPointerSize; // Bigger address end is exclusive. |
1572 | 1568 |
1573 Address* top_frame_pc_address = top_frame->pc_address(); | 1569 Address* top_frame_pc_address = top_frame->pc_address(); |
1574 | 1570 |
1575 // top_frame may be damaged below this point. Do not used it. | 1571 // top_frame may be damaged below this point. Do not used it. |
1576 DCHECK(!(top_frame = NULL)); | 1572 DCHECK(!(top_frame = NULL)); |
1577 | 1573 |
1578 if (unused_stack_top > unused_stack_bottom) { | 1574 if (unused_stack_top > unused_stack_bottom) { |
1579 if (frame_has_padding) { | 1575 if (frame_has_padding) { |
1580 int shortage_bytes = | 1576 int shortage_bytes = |
1581 static_cast<int>(unused_stack_top - unused_stack_bottom); | 1577 static_cast<int>(unused_stack_top - unused_stack_bottom); |
1582 | 1578 |
1583 Address padding_start = pre_top_frame->fp() - | 1579 Address padding_start = |
1584 LiveEdit::kFrameDropperFrameSize * kPointerSize; | 1580 pre_top_frame->fp() - |
| 1581 (FrameDropperFrameConstants::kFixedFrameSize - kPointerSize); |
1585 | 1582 |
1586 Address padding_pointer = padding_start; | 1583 Address padding_pointer = padding_start; |
1587 Smi* padding_object = Smi::FromInt(LiveEdit::kFramePaddingValue); | 1584 Smi* padding_object = Smi::FromInt(LiveEdit::kFramePaddingValue); |
1588 while (Memory::Object_at(padding_pointer) == padding_object) { | 1585 while (Memory::Object_at(padding_pointer) == padding_object) { |
1589 padding_pointer -= kPointerSize; | 1586 padding_pointer -= kPointerSize; |
1590 } | 1587 } |
1591 int padding_counter = | 1588 int padding_counter = |
1592 Smi::cast(Memory::Object_at(padding_pointer))->value(); | 1589 Smi::cast(Memory::Object_at(padding_pointer))->value(); |
1593 if (padding_counter * kPointerSize < shortage_bytes) { | 1590 if (padding_counter * kPointerSize < shortage_bytes) { |
1594 return "Not enough space for frame dropper frame " | 1591 return "Not enough space for frame dropper frame " |
1595 "(even with padding frame)"; | 1592 "(even with padding frame)"; |
1596 } | 1593 } |
1597 Memory::Object_at(padding_pointer) = | 1594 Memory::Object_at(padding_pointer) = |
1598 Smi::FromInt(padding_counter - shortage_bytes / kPointerSize); | 1595 Smi::FromInt(padding_counter - shortage_bytes / kPointerSize); |
1599 | 1596 |
1600 StackFrame* pre_pre_frame = frames[top_frame_index - 2]; | 1597 StackFrame* pre_pre_frame = frames[top_frame_index - 2]; |
1601 | 1598 |
1602 MemMove(padding_start + kPointerSize - shortage_bytes, | 1599 MemMove(padding_start + kPointerSize - shortage_bytes, |
1603 padding_start + kPointerSize, | 1600 padding_start + kPointerSize, |
1604 LiveEdit::kFrameDropperFrameSize * kPointerSize); | 1601 FrameDropperFrameConstants::kFixedFrameSize - kPointerSize); |
1605 | 1602 |
1606 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); | 1603 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); |
1607 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); | 1604 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); |
1608 unused_stack_top -= shortage_bytes; | 1605 unused_stack_top -= shortage_bytes; |
1609 | 1606 |
1610 STATIC_ASSERT(sizeof(Address) == kPointerSize); | 1607 STATIC_ASSERT(sizeof(Address) == kPointerSize); |
1611 top_frame_pc_address -= shortage_bytes / kPointerSize; | 1608 top_frame_pc_address -= shortage_bytes / kPointerSize; |
1612 } else { | 1609 } else { |
1613 return "Not enough space for frame dropper frame"; | 1610 return "Not enough space for frame dropper frame"; |
1614 } | 1611 } |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2038 isolate_->active_function_info_listener()->FunctionCode(code); | 2035 isolate_->active_function_info_listener()->FunctionCode(code); |
2039 } | 2036 } |
2040 | 2037 |
2041 | 2038 |
2042 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2039 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
2043 return isolate->active_function_info_listener() != NULL; | 2040 return isolate->active_function_info_listener() != NULL; |
2044 } | 2041 } |
2045 | 2042 |
2046 } // namespace internal | 2043 } // namespace internal |
2047 } // namespace v8 | 2044 } // namespace v8 |
OLD | NEW |