| 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 | 5 |
| 6 #include "v8.h" | 6 #include "v8.h" |
| 7 | 7 |
| 8 #include "liveedit.h" | 8 #include "liveedit.h" |
| 9 | 9 |
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 | 798 |
| 799 return scope_info_list; | 799 return scope_info_list; |
| 800 } | 800 } |
| 801 | 801 |
| 802 Handle<JSArray> result_; | 802 Handle<JSArray> result_; |
| 803 int len_; | 803 int len_; |
| 804 int current_parent_index_; | 804 int current_parent_index_; |
| 805 }; | 805 }; |
| 806 | 806 |
| 807 | 807 |
| 808 Address LiveEdit::AfterBreakTarget(FrameDropMode mode, Isolate* isolate) { |
| 809 Code* code = NULL; |
| 810 switch (mode) { |
| 811 case FRAMES_UNTOUCHED: |
| 812 break; |
| 813 case FRAME_DROPPED_IN_IC_CALL: |
| 814 // We must have been calling IC stub. Do not go there anymore. |
| 815 code = isolate->builtins()->builtin(Builtins::kPlainReturn_LiveEdit); |
| 816 break; |
| 817 case FRAME_DROPPED_IN_DIRECT_CALL: |
| 818 // Nothing to do, after_break_target is not used here. |
| 819 break; |
| 820 case FRAME_DROPPED_IN_DEBUG_SLOT_CALL: |
| 821 // Debug break slot stub does not return normally, instead it manually |
| 822 // cleans the stack and jumps. We should patch the jump address. |
| 823 case FRAME_DROPPED_IN_RETURN_CALL: |
| 824 code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit); |
| 825 break; |
| 826 case CURRENTLY_SET_MODE: |
| 827 UNREACHABLE(); |
| 828 break; |
| 829 } |
| 830 if (code == NULL) return NULL; |
| 831 return code->entry(); |
| 832 } |
| 833 |
| 834 |
| 808 MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script, | 835 MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script, |
| 809 Handle<String> source) { | 836 Handle<String> source) { |
| 810 Isolate* isolate = script->GetIsolate(); | 837 Isolate* isolate = script->GetIsolate(); |
| 811 | 838 |
| 812 FunctionInfoListener listener(isolate); | 839 FunctionInfoListener listener(isolate); |
| 813 Handle<Object> original_source = | 840 Handle<Object> original_source = |
| 814 Handle<Object>(script->source(), isolate); | 841 Handle<Object>(script->source(), isolate); |
| 815 script->set_source(*source); | 842 script->set_source(*source); |
| 816 isolate->set_active_function_info_listener(&listener); | 843 isolate->set_active_function_info_listener(&listener); |
| 817 | 844 |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 | 1466 |
| 1440 Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script, | 1467 Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script, |
| 1441 Handle<String> new_source, | 1468 Handle<String> new_source, |
| 1442 Handle<Object> old_script_name) { | 1469 Handle<Object> old_script_name) { |
| 1443 Isolate* isolate = original_script->GetIsolate(); | 1470 Isolate* isolate = original_script->GetIsolate(); |
| 1444 Handle<Object> old_script_object; | 1471 Handle<Object> old_script_object; |
| 1445 if (old_script_name->IsString()) { | 1472 if (old_script_name->IsString()) { |
| 1446 Handle<Script> old_script = CreateScriptCopy(original_script); | 1473 Handle<Script> old_script = CreateScriptCopy(original_script); |
| 1447 old_script->set_name(String::cast(*old_script_name)); | 1474 old_script->set_name(String::cast(*old_script_name)); |
| 1448 old_script_object = old_script; | 1475 old_script_object = old_script; |
| 1449 isolate->debugger()->OnAfterCompile( | 1476 isolate->debug()->OnAfterCompile(old_script, Debug::SEND_WHEN_DEBUGGING); |
| 1450 old_script, Debugger::SEND_WHEN_DEBUGGING); | |
| 1451 } else { | 1477 } else { |
| 1452 old_script_object = isolate->factory()->null_value(); | 1478 old_script_object = isolate->factory()->null_value(); |
| 1453 } | 1479 } |
| 1454 | 1480 |
| 1455 original_script->set_source(*new_source); | 1481 original_script->set_source(*new_source); |
| 1456 | 1482 |
| 1457 // Drop line ends so that they will be recalculated. | 1483 // Drop line ends so that they will be recalculated. |
| 1458 original_script->set_line_ends(isolate->heap()->undefined_value()); | 1484 original_script->set_line_ends(isolate->heap()->undefined_value()); |
| 1459 | 1485 |
| 1460 return old_script_object; | 1486 return old_script_object; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 Address* above_frame_address = pointer_address; | 1553 Address* above_frame_address = pointer_address; |
| 1528 while (*pointer_address < bottom_frame->fp()) { | 1554 while (*pointer_address < bottom_frame->fp()) { |
| 1529 pointer_address = &Memory::Address_at(*pointer_address); | 1555 pointer_address = &Memory::Address_at(*pointer_address); |
| 1530 } | 1556 } |
| 1531 bool change = *above_frame_address != *pointer_address; | 1557 bool change = *above_frame_address != *pointer_address; |
| 1532 *above_frame_address = *pointer_address; | 1558 *above_frame_address = *pointer_address; |
| 1533 return change; | 1559 return change; |
| 1534 } | 1560 } |
| 1535 | 1561 |
| 1536 | 1562 |
| 1563 // Initializes an artificial stack frame. The data it contains is used for: |
| 1564 // a. successful work of frame dropper code which eventually gets control, |
| 1565 // b. being compatible with regular stack structure for various stack |
| 1566 // iterators. |
| 1567 // Returns address of stack allocated pointer to restarted function, |
| 1568 // the value that is called 'restarter_frame_function_pointer'. The value |
| 1569 // at this address (possibly updated by GC) may be used later when preparing |
| 1570 // 'step in' operation. |
| 1571 // Frame structure (conforms InternalFrame structure): |
| 1572 // -- code |
| 1573 // -- SMI maker |
| 1574 // -- function (slot is called "context") |
| 1575 // -- frame base |
| 1576 static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame, |
| 1577 Handle<Code> code) { |
| 1578 ASSERT(bottom_js_frame->is_java_script()); |
| 1579 |
| 1580 Address fp = bottom_js_frame->fp(); |
| 1581 |
| 1582 // Move function pointer into "context" slot. |
| 1583 Memory::Object_at(fp + StandardFrameConstants::kContextOffset) = |
| 1584 Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset); |
| 1585 |
| 1586 Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code; |
| 1587 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) = |
| 1588 Smi::FromInt(StackFrame::INTERNAL); |
| 1589 |
| 1590 return reinterpret_cast<Object**>(&Memory::Object_at( |
| 1591 fp + StandardFrameConstants::kContextOffset)); |
| 1592 } |
| 1593 |
| 1594 |
| 1537 // Removes specified range of frames from stack. There may be 1 or more | 1595 // Removes specified range of frames from stack. There may be 1 or more |
| 1538 // frames in range. Anyway the bottom frame is restarted rather than dropped, | 1596 // frames in range. Anyway the bottom frame is restarted rather than dropped, |
| 1539 // and therefore has to be a JavaScript frame. | 1597 // and therefore has to be a JavaScript frame. |
| 1540 // Returns error message or NULL. | 1598 // Returns error message or NULL. |
| 1541 static const char* DropFrames(Vector<StackFrame*> frames, | 1599 static const char* DropFrames(Vector<StackFrame*> frames, |
| 1542 int top_frame_index, | 1600 int top_frame_index, |
| 1543 int bottom_js_frame_index, | 1601 int bottom_js_frame_index, |
| 1544 Debug::FrameDropMode* mode, | 1602 LiveEdit::FrameDropMode* mode, |
| 1545 Object*** restarter_frame_function_pointer) { | 1603 Object*** restarter_frame_function_pointer) { |
| 1546 if (!Debug::kFrameDropperSupported) { | 1604 if (!LiveEdit::kFrameDropperSupported) { |
| 1547 return "Stack manipulations are not supported in this architecture."; | 1605 return "Stack manipulations are not supported in this architecture."; |
| 1548 } | 1606 } |
| 1549 | 1607 |
| 1550 StackFrame* pre_top_frame = frames[top_frame_index - 1]; | 1608 StackFrame* pre_top_frame = frames[top_frame_index - 1]; |
| 1551 StackFrame* top_frame = frames[top_frame_index]; | 1609 StackFrame* top_frame = frames[top_frame_index]; |
| 1552 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; | 1610 StackFrame* bottom_js_frame = frames[bottom_js_frame_index]; |
| 1553 | 1611 |
| 1554 ASSERT(bottom_js_frame->is_java_script()); | 1612 ASSERT(bottom_js_frame->is_java_script()); |
| 1555 | 1613 |
| 1556 // Check the nature of the top frame. | 1614 // Check the nature of the top frame. |
| 1557 Isolate* isolate = bottom_js_frame->isolate(); | 1615 Isolate* isolate = bottom_js_frame->isolate(); |
| 1558 Code* pre_top_frame_code = pre_top_frame->LookupCode(); | 1616 Code* pre_top_frame_code = pre_top_frame->LookupCode(); |
| 1559 bool frame_has_padding; | 1617 bool frame_has_padding = true; |
| 1560 if (pre_top_frame_code->is_inline_cache_stub() && | 1618 if (pre_top_frame_code->is_inline_cache_stub() && |
| 1561 pre_top_frame_code->is_debug_stub()) { | 1619 pre_top_frame_code->is_debug_stub()) { |
| 1562 // OK, we can drop inline cache calls. | 1620 // OK, we can drop inline cache calls. |
| 1563 *mode = Debug::FRAME_DROPPED_IN_IC_CALL; | 1621 *mode = LiveEdit::FRAME_DROPPED_IN_IC_CALL; |
| 1564 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | |
| 1565 } else if (pre_top_frame_code == | 1622 } else if (pre_top_frame_code == |
| 1566 isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) { | 1623 isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) { |
| 1567 // OK, we can drop debug break slot. | 1624 // OK, we can drop debug break slot. |
| 1568 *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; | 1625 *mode = LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
| 1569 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | |
| 1570 } else if (pre_top_frame_code == | 1626 } else if (pre_top_frame_code == |
| 1571 isolate->builtins()->builtin( | 1627 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)) { |
| 1572 Builtins::kFrameDropper_LiveEdit)) { | |
| 1573 // OK, we can drop our own code. | 1628 // OK, we can drop our own code. |
| 1574 pre_top_frame = frames[top_frame_index - 2]; | 1629 pre_top_frame = frames[top_frame_index - 2]; |
| 1575 top_frame = frames[top_frame_index - 1]; | 1630 top_frame = frames[top_frame_index - 1]; |
| 1576 *mode = Debug::CURRENTLY_SET_MODE; | 1631 *mode = LiveEdit::CURRENTLY_SET_MODE; |
| 1577 frame_has_padding = false; | 1632 frame_has_padding = false; |
| 1578 } else if (pre_top_frame_code == | 1633 } else if (pre_top_frame_code == |
| 1579 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { | 1634 isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { |
| 1580 *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; | 1635 *mode = LiveEdit::FRAME_DROPPED_IN_RETURN_CALL; |
| 1581 frame_has_padding = Debug::FramePaddingLayout::kIsSupported; | |
| 1582 } else if (pre_top_frame_code->kind() == Code::STUB && | 1636 } else if (pre_top_frame_code->kind() == Code::STUB && |
| 1583 pre_top_frame_code->major_key() == CodeStub::CEntry) { | 1637 pre_top_frame_code->major_key() == CodeStub::CEntry) { |
| 1584 // Entry from our unit tests on 'debugger' statement. | 1638 // Entry from our unit tests on 'debugger' statement. |
| 1585 // It's fine, we support this case. | 1639 // It's fine, we support this case. |
| 1586 *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; | 1640 *mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL; |
| 1587 // We don't have a padding from 'debugger' statement call. | 1641 // We don't have a padding from 'debugger' statement call. |
| 1588 // Here the stub is CEntry, it's not debug-only and can't be padded. | 1642 // Here the stub is CEntry, it's not debug-only and can't be padded. |
| 1589 // If anyone would complain, a proxy padded stub could be added. | 1643 // If anyone would complain, a proxy padded stub could be added. |
| 1590 frame_has_padding = false; | 1644 frame_has_padding = false; |
| 1591 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { | 1645 } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) { |
| 1592 // This must be adaptor that remain from the frame dropping that | 1646 // This must be adaptor that remain from the frame dropping that |
| 1593 // is still on stack. A frame dropper frame must be above it. | 1647 // is still on stack. A frame dropper frame must be above it. |
| 1594 ASSERT(frames[top_frame_index - 2]->LookupCode() == | 1648 ASSERT(frames[top_frame_index - 2]->LookupCode() == |
| 1595 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); | 1649 isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)); |
| 1596 pre_top_frame = frames[top_frame_index - 3]; | 1650 pre_top_frame = frames[top_frame_index - 3]; |
| 1597 top_frame = frames[top_frame_index - 2]; | 1651 top_frame = frames[top_frame_index - 2]; |
| 1598 *mode = Debug::CURRENTLY_SET_MODE; | 1652 *mode = LiveEdit::CURRENTLY_SET_MODE; |
| 1599 frame_has_padding = false; | 1653 frame_has_padding = false; |
| 1600 } else { | 1654 } else { |
| 1601 return "Unknown structure of stack above changing function"; | 1655 return "Unknown structure of stack above changing function"; |
| 1602 } | 1656 } |
| 1603 | 1657 |
| 1604 Address unused_stack_top = top_frame->sp(); | 1658 Address unused_stack_top = top_frame->sp(); |
| 1659 int new_frame_size = LiveEdit::kFrameDropperFrameSize * kPointerSize; |
| 1605 Address unused_stack_bottom = bottom_js_frame->fp() | 1660 Address unused_stack_bottom = bottom_js_frame->fp() |
| 1606 - Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. | 1661 - new_frame_size + kPointerSize; // Bigger address end is exclusive. |
| 1607 + kPointerSize; // Bigger address end is exclusive. | |
| 1608 | 1662 |
| 1609 Address* top_frame_pc_address = top_frame->pc_address(); | 1663 Address* top_frame_pc_address = top_frame->pc_address(); |
| 1610 | 1664 |
| 1611 // top_frame may be damaged below this point. Do not used it. | 1665 // top_frame may be damaged below this point. Do not used it. |
| 1612 ASSERT(!(top_frame = NULL)); | 1666 ASSERT(!(top_frame = NULL)); |
| 1613 | 1667 |
| 1614 if (unused_stack_top > unused_stack_bottom) { | 1668 if (unused_stack_top > unused_stack_bottom) { |
| 1615 if (frame_has_padding) { | 1669 if (frame_has_padding) { |
| 1616 int shortage_bytes = | 1670 int shortage_bytes = |
| 1617 static_cast<int>(unused_stack_top - unused_stack_bottom); | 1671 static_cast<int>(unused_stack_top - unused_stack_bottom); |
| 1618 | 1672 |
| 1619 Address padding_start = pre_top_frame->fp() - | 1673 Address padding_start = pre_top_frame->fp() - |
| 1620 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; | 1674 LiveEdit::kFrameDropperFrameSize * kPointerSize; |
| 1621 | 1675 |
| 1622 Address padding_pointer = padding_start; | 1676 Address padding_pointer = padding_start; |
| 1623 Smi* padding_object = | 1677 Smi* padding_object = Smi::FromInt(LiveEdit::kFramePaddingValue); |
| 1624 Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue); | |
| 1625 while (Memory::Object_at(padding_pointer) == padding_object) { | 1678 while (Memory::Object_at(padding_pointer) == padding_object) { |
| 1626 padding_pointer -= kPointerSize; | 1679 padding_pointer -= kPointerSize; |
| 1627 } | 1680 } |
| 1628 int padding_counter = | 1681 int padding_counter = |
| 1629 Smi::cast(Memory::Object_at(padding_pointer))->value(); | 1682 Smi::cast(Memory::Object_at(padding_pointer))->value(); |
| 1630 if (padding_counter * kPointerSize < shortage_bytes) { | 1683 if (padding_counter * kPointerSize < shortage_bytes) { |
| 1631 return "Not enough space for frame dropper frame " | 1684 return "Not enough space for frame dropper frame " |
| 1632 "(even with padding frame)"; | 1685 "(even with padding frame)"; |
| 1633 } | 1686 } |
| 1634 Memory::Object_at(padding_pointer) = | 1687 Memory::Object_at(padding_pointer) = |
| 1635 Smi::FromInt(padding_counter - shortage_bytes / kPointerSize); | 1688 Smi::FromInt(padding_counter - shortage_bytes / kPointerSize); |
| 1636 | 1689 |
| 1637 StackFrame* pre_pre_frame = frames[top_frame_index - 2]; | 1690 StackFrame* pre_pre_frame = frames[top_frame_index - 2]; |
| 1638 | 1691 |
| 1639 OS::MemMove(padding_start + kPointerSize - shortage_bytes, | 1692 OS::MemMove(padding_start + kPointerSize - shortage_bytes, |
| 1640 padding_start + kPointerSize, | 1693 padding_start + kPointerSize, |
| 1641 Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); | 1694 LiveEdit::kFrameDropperFrameSize * kPointerSize); |
| 1642 | 1695 |
| 1643 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); | 1696 pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); |
| 1644 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); | 1697 pre_pre_frame->SetCallerFp(pre_top_frame->fp()); |
| 1645 unused_stack_top -= shortage_bytes; | 1698 unused_stack_top -= shortage_bytes; |
| 1646 | 1699 |
| 1647 STATIC_ASSERT(sizeof(Address) == kPointerSize); | 1700 STATIC_ASSERT(sizeof(Address) == kPointerSize); |
| 1648 top_frame_pc_address -= shortage_bytes / kPointerSize; | 1701 top_frame_pc_address -= shortage_bytes / kPointerSize; |
| 1649 } else { | 1702 } else { |
| 1650 return "Not enough space for frame dropper frame"; | 1703 return "Not enough space for frame dropper frame"; |
| 1651 } | 1704 } |
| 1652 } | 1705 } |
| 1653 | 1706 |
| 1654 // Committing now. After this point we should return only NULL value. | 1707 // Committing now. After this point we should return only NULL value. |
| 1655 | 1708 |
| 1656 FixTryCatchHandler(pre_top_frame, bottom_js_frame); | 1709 FixTryCatchHandler(pre_top_frame, bottom_js_frame); |
| 1657 // Make sure FixTryCatchHandler is idempotent. | 1710 // Make sure FixTryCatchHandler is idempotent. |
| 1658 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); | 1711 ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); |
| 1659 | 1712 |
| 1660 Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit(); | 1713 Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit(); |
| 1661 *top_frame_pc_address = code->entry(); | 1714 *top_frame_pc_address = code->entry(); |
| 1662 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); | 1715 pre_top_frame->SetCallerFp(bottom_js_frame->fp()); |
| 1663 | 1716 |
| 1664 *restarter_frame_function_pointer = | 1717 *restarter_frame_function_pointer = |
| 1665 Debug::SetUpFrameDropperFrame(bottom_js_frame, code); | 1718 SetUpFrameDropperFrame(bottom_js_frame, code); |
| 1666 | 1719 |
| 1667 ASSERT((**restarter_frame_function_pointer)->IsJSFunction()); | 1720 ASSERT((**restarter_frame_function_pointer)->IsJSFunction()); |
| 1668 | 1721 |
| 1669 for (Address a = unused_stack_top; | 1722 for (Address a = unused_stack_top; |
| 1670 a < unused_stack_bottom; | 1723 a < unused_stack_bottom; |
| 1671 a += kPointerSize) { | 1724 a += kPointerSize) { |
| 1672 Memory::Object_at(a) = Smi::FromInt(0); | 1725 Memory::Object_at(a) = Smi::FromInt(0); |
| 1673 } | 1726 } |
| 1674 | 1727 |
| 1675 return NULL; | 1728 return NULL; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 if (!do_drop) { | 1823 if (!do_drop) { |
| 1771 // We are in check-only mode. | 1824 // We are in check-only mode. |
| 1772 return NULL; | 1825 return NULL; |
| 1773 } | 1826 } |
| 1774 | 1827 |
| 1775 if (!target_frame_found) { | 1828 if (!target_frame_found) { |
| 1776 // Nothing to drop. | 1829 // Nothing to drop. |
| 1777 return target.GetNotFoundMessage(); | 1830 return target.GetNotFoundMessage(); |
| 1778 } | 1831 } |
| 1779 | 1832 |
| 1780 Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED; | 1833 LiveEdit::FrameDropMode drop_mode = LiveEdit::FRAMES_UNTOUCHED; |
| 1781 Object** restarter_frame_function_pointer = NULL; | 1834 Object** restarter_frame_function_pointer = NULL; |
| 1782 const char* error_message = DropFrames(frames, top_frame_index, | 1835 const char* error_message = DropFrames(frames, top_frame_index, |
| 1783 bottom_js_frame_index, &drop_mode, | 1836 bottom_js_frame_index, &drop_mode, |
| 1784 &restarter_frame_function_pointer); | 1837 &restarter_frame_function_pointer); |
| 1785 | 1838 |
| 1786 if (error_message != NULL) { | 1839 if (error_message != NULL) { |
| 1787 return error_message; | 1840 return error_message; |
| 1788 } | 1841 } |
| 1789 | 1842 |
| 1790 // Adjust break_frame after some frames has been dropped. | 1843 // Adjust break_frame after some frames has been dropped. |
| 1791 StackFrame::Id new_id = StackFrame::NO_ID; | 1844 StackFrame::Id new_id = StackFrame::NO_ID; |
| 1792 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { | 1845 for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) { |
| 1793 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { | 1846 if (frames[i]->type() == StackFrame::JAVA_SCRIPT) { |
| 1794 new_id = frames[i]->id(); | 1847 new_id = frames[i]->id(); |
| 1795 break; | 1848 break; |
| 1796 } | 1849 } |
| 1797 } | 1850 } |
| 1798 debug->FramesHaveBeenDropped(new_id, drop_mode, | 1851 debug->FramesHaveBeenDropped( |
| 1799 restarter_frame_function_pointer); | 1852 new_id, drop_mode, restarter_frame_function_pointer); |
| 1800 return NULL; | 1853 return NULL; |
| 1801 } | 1854 } |
| 1802 | 1855 |
| 1803 | 1856 |
| 1804 // Fills result array with statuses of functions. Modifies the stack | 1857 // Fills result array with statuses of functions. Modifies the stack |
| 1805 // removing all listed function if possible and if do_drop is true. | 1858 // removing all listed function if possible and if do_drop is true. |
| 1806 static const char* DropActivationsInActiveThread( | 1859 static const char* DropActivationsInActiveThread( |
| 1807 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) { | 1860 Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) { |
| 1808 MultipleFunctionTarget target(shared_info_array, result); | 1861 MultipleFunctionTarget target(shared_info_array, result); |
| 1809 | 1862 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { | 2072 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
| 2020 isolate_->active_function_info_listener()->FunctionCode(code); | 2073 isolate_->active_function_info_listener()->FunctionCode(code); |
| 2021 } | 2074 } |
| 2022 | 2075 |
| 2023 | 2076 |
| 2024 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2077 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
| 2025 return isolate->active_function_info_listener() != NULL; | 2078 return isolate->active_function_info_listener() != NULL; |
| 2026 } | 2079 } |
| 2027 | 2080 |
| 2028 } } // namespace v8::internal | 2081 } } // namespace v8::internal |
| OLD | NEW |