OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 Object* context = context_pos->GetRawValue(); | 957 Object* context = context_pos->GetRawValue(); |
958 if (context->IsUndefined(isolate_)) { | 958 if (context->IsUndefined(isolate_)) { |
959 // If the context was optimized away, just use the context from | 959 // If the context was optimized away, just use the context from |
960 // the activation. This should only apply to Crankshaft code. | 960 // the activation. This should only apply to Crankshaft code. |
961 CHECK(!compiled_code_->is_turbofanned()); | 961 CHECK(!compiled_code_->is_turbofanned()); |
962 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_) | 962 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_) |
963 : function->context(); | 963 : function->context(); |
964 } | 964 } |
965 value = reinterpret_cast<intptr_t>(context); | 965 value = reinterpret_cast<intptr_t>(context); |
966 output_frame->SetContext(value); | 966 output_frame->SetContext(value); |
967 if (is_topmost) { | |
968 Register context_reg = JavaScriptFrame::context_register(); | |
969 output_frame->SetRegister(context_reg.code(), value); | |
970 } | |
971 WriteValueToOutput(context, context_input_index, frame_index, output_offset, | 967 WriteValueToOutput(context, context_input_index, frame_index, output_offset, |
972 "context "); | 968 "context "); |
973 if (context == isolate_->heap()->arguments_marker()) { | 969 if (context == isolate_->heap()->arguments_marker()) { |
974 Address output_address = | 970 Address output_address = |
975 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + | 971 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + |
976 output_offset; | 972 output_offset; |
977 values_to_materialize_.push_back({output_address, context_pos}); | 973 values_to_materialize_.push_back({output_address, context_pos}); |
978 } | 974 } |
979 value_iterator++; | 975 value_iterator++; |
980 input_index++; | 976 input_index++; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 output_frame->SetPc(pc_value); | 1022 output_frame->SetPc(pc_value); |
1027 | 1023 |
1028 // If we are going to the catch handler, then the exception lives in | 1024 // If we are going to the catch handler, then the exception lives in |
1029 // the accumulator. | 1025 // the accumulator. |
1030 BailoutState state = | 1026 BailoutState state = |
1031 goto_catch_handler | 1027 goto_catch_handler |
1032 ? BailoutState::TOS_REGISTER | 1028 ? BailoutState::TOS_REGISTER |
1033 : FullCodeGenerator::BailoutStateField::decode(pc_and_state); | 1029 : FullCodeGenerator::BailoutStateField::decode(pc_and_state); |
1034 output_frame->SetState(Smi::FromInt(static_cast<int>(state))); | 1030 output_frame->SetState(Smi::FromInt(static_cast<int>(state))); |
1035 | 1031 |
| 1032 // Clear the context register. The context might be a de-materialized object |
| 1033 // and will be materialized by {Runtime_NotifyDeoptimized}. For additional |
| 1034 // safety we use Smi(0) instead of the potential {arguments_marker} here. |
| 1035 if (is_topmost) { |
| 1036 intptr_t context_value = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1037 Register context_reg = JavaScriptFrame::context_register(); |
| 1038 output_frame->SetRegister(context_reg.code(), context_value); |
| 1039 } |
| 1040 |
1036 // Set the continuation for the topmost frame. | 1041 // Set the continuation for the topmost frame. |
1037 if (is_topmost) { | 1042 if (is_topmost) { |
1038 Builtins* builtins = isolate_->builtins(); | 1043 Builtins* builtins = isolate_->builtins(); |
1039 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); | 1044 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); |
1040 if (bailout_type_ == LAZY) { | 1045 if (bailout_type_ == LAZY) { |
1041 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); | 1046 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); |
1042 } else if (bailout_type_ == SOFT) { | 1047 } else if (bailout_type_ == SOFT) { |
1043 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); | 1048 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1044 } else { | 1049 } else { |
1045 CHECK_EQ(bailout_type_, EAGER); | 1050 CHECK_EQ(bailout_type_, EAGER); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 // in the handler table. | 1189 // in the handler table. |
1185 for (int i = 0; i < catch_handler_data_ + 1; ++i) { | 1190 for (int i = 0; i < catch_handler_data_ + 1; ++i) { |
1186 context_pos++; | 1191 context_pos++; |
1187 context_input_index++; | 1192 context_input_index++; |
1188 } | 1193 } |
1189 } | 1194 } |
1190 // Read the context from the translations. | 1195 // Read the context from the translations. |
1191 Object* context = context_pos->GetRawValue(); | 1196 Object* context = context_pos->GetRawValue(); |
1192 value = reinterpret_cast<intptr_t>(context); | 1197 value = reinterpret_cast<intptr_t>(context); |
1193 output_frame->SetContext(value); | 1198 output_frame->SetContext(value); |
1194 if (is_topmost) { | |
1195 Register context_reg = InterpretedFrame::context_register(); | |
1196 output_frame->SetRegister(context_reg.code(), value); | |
1197 } | |
1198 WriteValueToOutput(context, context_input_index, frame_index, output_offset, | 1199 WriteValueToOutput(context, context_input_index, frame_index, output_offset, |
1199 "context "); | 1200 "context "); |
1200 if (context == isolate_->heap()->arguments_marker()) { | 1201 if (context == isolate_->heap()->arguments_marker()) { |
1201 Address output_address = | 1202 Address output_address = |
1202 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + | 1203 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + |
1203 output_offset; | 1204 output_offset; |
1204 values_to_materialize_.push_back({output_address, context_pos}); | 1205 values_to_materialize_.push_back({output_address, context_pos}); |
1205 } | 1206 } |
1206 value_iterator++; | 1207 value_iterator++; |
1207 input_index++; | 1208 input_index++; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 intptr_t constant_pool_value = | 1282 intptr_t constant_pool_value = |
1282 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); | 1283 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); |
1283 output_frame->SetConstantPool(constant_pool_value); | 1284 output_frame->SetConstantPool(constant_pool_value); |
1284 if (is_topmost) { | 1285 if (is_topmost) { |
1285 Register constant_pool_reg = | 1286 Register constant_pool_reg = |
1286 InterpretedFrame::constant_pool_pointer_register(); | 1287 InterpretedFrame::constant_pool_pointer_register(); |
1287 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | 1288 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
1288 } | 1289 } |
1289 } | 1290 } |
1290 | 1291 |
| 1292 // Clear the context register. The context might be a de-materialized object |
| 1293 // and will be materialized by {Runtime_NotifyDeoptimized}. For additional |
| 1294 // safety we use Smi(0) instead of the potential {arguments_marker} here. |
| 1295 if (is_topmost) { |
| 1296 intptr_t context_value = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1297 Register context_reg = JavaScriptFrame::context_register(); |
| 1298 output_frame->SetRegister(context_reg.code(), context_value); |
| 1299 } |
| 1300 |
1291 // Set the continuation for the topmost frame. | 1301 // Set the continuation for the topmost frame. |
1292 if (is_topmost) { | 1302 if (is_topmost) { |
1293 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); | 1303 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); |
1294 if (bailout_type_ == LAZY) { | 1304 if (bailout_type_ == LAZY) { |
1295 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); | 1305 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); |
1296 } else if (bailout_type_ == SOFT) { | 1306 } else if (bailout_type_ == SOFT) { |
1297 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); | 1307 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1298 } else { | 1308 } else { |
1299 CHECK_EQ(bailout_type_, EAGER); | 1309 CHECK_EQ(bailout_type_, EAGER); |
1300 } | 1310 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 output_offset -= kPointerSize; | 1594 output_offset -= kPointerSize; |
1585 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); | 1595 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); |
1586 output_frame->SetFrameSlot(output_offset, value); | 1596 output_frame->SetFrameSlot(output_offset, value); |
1587 DebugPrintOutputSlot(value, frame_index, output_offset, | 1597 DebugPrintOutputSlot(value, frame_index, output_offset, |
1588 "typed frame marker\n"); | 1598 "typed frame marker\n"); |
1589 | 1599 |
1590 // The context can be gotten from the previous frame. | 1600 // The context can be gotten from the previous frame. |
1591 output_offset -= kPointerSize; | 1601 output_offset -= kPointerSize; |
1592 value = output_[frame_index - 1]->GetContext(); | 1602 value = output_[frame_index - 1]->GetContext(); |
1593 output_frame->SetFrameSlot(output_offset, value); | 1603 output_frame->SetFrameSlot(output_offset, value); |
1594 if (is_topmost) { | |
1595 Register context_reg = JavaScriptFrame::context_register(); | |
1596 output_frame->SetRegister(context_reg.code(), value); | |
1597 } | |
1598 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); | 1604 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); |
1599 | 1605 |
1600 // The allocation site. | 1606 // The allocation site. |
1601 output_offset -= kPointerSize; | 1607 output_offset -= kPointerSize; |
1602 value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value()); | 1608 value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value()); |
1603 output_frame->SetFrameSlot(output_offset, value); | 1609 output_frame->SetFrameSlot(output_offset, value); |
1604 DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n"); | 1610 DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n"); |
1605 | 1611 |
1606 // Number of incoming arguments. | 1612 // Number of incoming arguments. |
1607 output_offset -= kPointerSize; | 1613 output_offset -= kPointerSize; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 intptr_t constant_pool_value = | 1649 intptr_t constant_pool_value = |
1644 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); | 1650 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); |
1645 output_frame->SetConstantPool(constant_pool_value); | 1651 output_frame->SetConstantPool(constant_pool_value); |
1646 if (is_topmost) { | 1652 if (is_topmost) { |
1647 Register constant_pool_reg = | 1653 Register constant_pool_reg = |
1648 JavaScriptFrame::constant_pool_pointer_register(); | 1654 JavaScriptFrame::constant_pool_pointer_register(); |
1649 output_frame->SetRegister(constant_pool_reg.code(), fp_value); | 1655 output_frame->SetRegister(constant_pool_reg.code(), fp_value); |
1650 } | 1656 } |
1651 } | 1657 } |
1652 | 1658 |
| 1659 // Clear the context register. The context might be a de-materialized object |
| 1660 // and will be materialized by {Runtime_NotifyDeoptimized}. For additional |
| 1661 // safety we use Smi(0) instead of the potential {arguments_marker} here. |
| 1662 if (is_topmost) { |
| 1663 intptr_t context_value = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1664 Register context_reg = JavaScriptFrame::context_register(); |
| 1665 output_frame->SetRegister(context_reg.code(), context_value); |
| 1666 } |
| 1667 |
1653 // Set the continuation for the topmost frame. | 1668 // Set the continuation for the topmost frame. |
1654 if (is_topmost) { | 1669 if (is_topmost) { |
1655 Builtins* builtins = isolate_->builtins(); | 1670 Builtins* builtins = isolate_->builtins(); |
1656 DCHECK_EQ(LAZY, bailout_type_); | 1671 DCHECK_EQ(LAZY, bailout_type_); |
1657 Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); | 1672 Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); |
1658 output_frame->SetContinuation( | 1673 output_frame->SetContinuation( |
1659 reinterpret_cast<intptr_t>(continuation->entry())); | 1674 reinterpret_cast<intptr_t>(continuation->entry())); |
1660 } | 1675 } |
1661 } | 1676 } |
1662 | 1677 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 Builtins::kLoadIC_Getter_ForDeopt; | 1784 Builtins::kLoadIC_Getter_ForDeopt; |
1770 Code* accessor_stub = isolate_->builtins()->builtin(name); | 1785 Code* accessor_stub = isolate_->builtins()->builtin(name); |
1771 value = reinterpret_cast<intptr_t>(accessor_stub); | 1786 value = reinterpret_cast<intptr_t>(accessor_stub); |
1772 output_frame->SetFrameSlot(output_offset, value); | 1787 output_frame->SetFrameSlot(output_offset, value); |
1773 DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n"); | 1788 DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n"); |
1774 | 1789 |
1775 // The context can be gotten from the previous frame. | 1790 // The context can be gotten from the previous frame. |
1776 output_offset -= kPointerSize; | 1791 output_offset -= kPointerSize; |
1777 value = output_[frame_index - 1]->GetContext(); | 1792 value = output_[frame_index - 1]->GetContext(); |
1778 output_frame->SetFrameSlot(output_offset, value); | 1793 output_frame->SetFrameSlot(output_offset, value); |
1779 if (is_topmost) { | |
1780 Register context_reg = JavaScriptFrame::context_register(); | |
1781 output_frame->SetRegister(context_reg.code(), value); | |
1782 } | |
1783 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); | 1794 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); |
1784 | 1795 |
1785 // Skip receiver. | 1796 // Skip receiver. |
1786 value_iterator++; | 1797 value_iterator++; |
1787 input_index++; | 1798 input_index++; |
1788 | 1799 |
1789 if (is_setter_stub_frame) { | 1800 if (is_setter_stub_frame) { |
1790 // The implicit return value was part of the artificial setter stub | 1801 // The implicit return value was part of the artificial setter stub |
1791 // environment. | 1802 // environment. |
1792 output_offset -= kPointerSize; | 1803 output_offset -= kPointerSize; |
(...skipping 29 matching lines...) Expand all Loading... |
1822 intptr_t constant_pool_value = | 1833 intptr_t constant_pool_value = |
1823 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); | 1834 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); |
1824 output_frame->SetConstantPool(constant_pool_value); | 1835 output_frame->SetConstantPool(constant_pool_value); |
1825 if (is_topmost) { | 1836 if (is_topmost) { |
1826 Register constant_pool_reg = | 1837 Register constant_pool_reg = |
1827 JavaScriptFrame::constant_pool_pointer_register(); | 1838 JavaScriptFrame::constant_pool_pointer_register(); |
1828 output_frame->SetRegister(constant_pool_reg.code(), fp_value); | 1839 output_frame->SetRegister(constant_pool_reg.code(), fp_value); |
1829 } | 1840 } |
1830 } | 1841 } |
1831 | 1842 |
| 1843 // Clear the context register. The context might be a de-materialized object |
| 1844 // and will be materialized by {Runtime_NotifyDeoptimized}. For additional |
| 1845 // safety we use Smi(0) instead of the potential {arguments_marker} here. |
| 1846 if (is_topmost) { |
| 1847 intptr_t context_value = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1848 Register context_reg = JavaScriptFrame::context_register(); |
| 1849 output_frame->SetRegister(context_reg.code(), context_value); |
| 1850 } |
| 1851 |
1832 // Set the continuation for the topmost frame. | 1852 // Set the continuation for the topmost frame. |
1833 if (is_topmost) { | 1853 if (is_topmost) { |
1834 Builtins* builtins = isolate_->builtins(); | 1854 Builtins* builtins = isolate_->builtins(); |
1835 DCHECK_EQ(LAZY, bailout_type_); | 1855 DCHECK_EQ(LAZY, bailout_type_); |
1836 Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); | 1856 Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); |
1837 output_frame->SetContinuation( | 1857 output_frame->SetContinuation( |
1838 reinterpret_cast<intptr_t>(continuation->entry())); | 1858 reinterpret_cast<intptr_t>(continuation->entry())); |
1839 } | 1859 } |
1840 } | 1860 } |
1841 | 1861 |
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4004 CHECK(value_info->IsMaterializedObject()); | 4024 CHECK(value_info->IsMaterializedObject()); |
4005 | 4025 |
4006 value_info->value_ = | 4026 value_info->value_ = |
4007 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4027 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4008 } | 4028 } |
4009 } | 4029 } |
4010 } | 4030 } |
4011 | 4031 |
4012 } // namespace internal | 4032 } // namespace internal |
4013 } // namespace v8 | 4033 } // namespace v8 |
OLD | NEW |