| 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 "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/ast/prettyprinter.h" | 8 #include "src/ast/prettyprinter.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 // Allocate and store the output frame description. | 886 // Allocate and store the output frame description. |
| 887 int parameter_count = shared->internal_formal_parameter_count() + 1; | 887 int parameter_count = shared->internal_formal_parameter_count() + 1; |
| 888 FrameDescription* output_frame = new (output_frame_size) | 888 FrameDescription* output_frame = new (output_frame_size) |
| 889 FrameDescription(output_frame_size, parameter_count); | 889 FrameDescription(output_frame_size, parameter_count); |
| 890 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 890 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
| 891 | 891 |
| 892 CHECK(frame_index >= 0 && frame_index < output_count_); | 892 CHECK(frame_index >= 0 && frame_index < output_count_); |
| 893 CHECK_NULL(output_[frame_index]); | 893 CHECK_NULL(output_[frame_index]); |
| 894 output_[frame_index] = output_frame; | 894 output_[frame_index] = output_frame; |
| 895 | 895 |
| 896 // The top address for the bottommost output frame can be computed from | 896 // The top address of the frame is computed from the previous frame's top and |
| 897 // the input frame pointer and the output frame's height. For all | 897 // this frame's size. |
| 898 // subsequent output frames, it can be computed from the previous one's | |
| 899 // top address and the current frame's size. | |
| 900 Register fp_reg = JavaScriptFrame::fp_register(); | |
| 901 intptr_t top_address; | 898 intptr_t top_address; |
| 902 if (is_bottommost) { | 899 if (is_bottommost) { |
| 903 top_address = caller_frame_top_ - output_frame_size; | 900 top_address = caller_frame_top_ - output_frame_size; |
| 904 } else { | 901 } else { |
| 905 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 902 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 906 } | 903 } |
| 907 output_frame->SetTop(top_address); | 904 output_frame->SetTop(top_address); |
| 908 | 905 |
| 909 // Compute the incoming parameter translation. | 906 // Compute the incoming parameter translation. |
| 910 unsigned output_offset = output_frame_size; | 907 unsigned output_offset = output_frame_size; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 938 // pointer. | 935 // pointer. |
| 939 output_offset -= kFPOnStackSize; | 936 output_offset -= kFPOnStackSize; |
| 940 if (is_bottommost) { | 937 if (is_bottommost) { |
| 941 value = caller_fp_; | 938 value = caller_fp_; |
| 942 } else { | 939 } else { |
| 943 value = output_[frame_index - 1]->GetFp(); | 940 value = output_[frame_index - 1]->GetFp(); |
| 944 } | 941 } |
| 945 output_frame->SetCallerFp(output_offset, value); | 942 output_frame->SetCallerFp(output_offset, value); |
| 946 intptr_t fp_value = top_address + output_offset; | 943 intptr_t fp_value = top_address + output_offset; |
| 947 output_frame->SetFp(fp_value); | 944 output_frame->SetFp(fp_value); |
| 948 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 945 if (is_topmost) { |
| 946 Register fp_reg = JavaScriptFrame::fp_register(); |
| 947 output_frame->SetRegister(fp_reg.code(), fp_value); |
| 948 } |
| 949 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 949 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
| 950 | 950 |
| 951 if (FLAG_enable_embedded_constant_pool) { | 951 if (FLAG_enable_embedded_constant_pool) { |
| 952 // For the bottommost output frame the constant pool pointer can be gotten | 952 // For the bottommost output frame the constant pool pointer can be gotten |
| 953 // from the input frame. For subsequent output frames, it can be read from | 953 // from the input frame. For subsequent output frames, it can be read from |
| 954 // the previous frame. | 954 // the previous frame. |
| 955 output_offset -= kPointerSize; | 955 output_offset -= kPointerSize; |
| 956 if (is_bottommost) { | 956 if (is_bottommost) { |
| 957 value = caller_constant_pool_; | 957 value = caller_constant_pool_; |
| 958 } else { | 958 } else { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1108 FrameDescription* output_frame = new (output_frame_size) | 1108 FrameDescription* output_frame = new (output_frame_size) |
| 1109 FrameDescription(output_frame_size, parameter_count); | 1109 FrameDescription(output_frame_size, parameter_count); |
| 1110 output_frame->SetFrameType(StackFrame::INTERPRETED); | 1110 output_frame->SetFrameType(StackFrame::INTERPRETED); |
| 1111 | 1111 |
| 1112 bool is_bottommost = (0 == frame_index); | 1112 bool is_bottommost = (0 == frame_index); |
| 1113 bool is_topmost = (output_count_ - 1 == frame_index); | 1113 bool is_topmost = (output_count_ - 1 == frame_index); |
| 1114 CHECK(frame_index >= 0 && frame_index < output_count_); | 1114 CHECK(frame_index >= 0 && frame_index < output_count_); |
| 1115 CHECK_NULL(output_[frame_index]); | 1115 CHECK_NULL(output_[frame_index]); |
| 1116 output_[frame_index] = output_frame; | 1116 output_[frame_index] = output_frame; |
| 1117 | 1117 |
| 1118 // The top address for the bottommost output frame can be computed from | 1118 // The top address of the frame is computed from the previous frame's top and |
| 1119 // the input frame pointer and the output frame's height. For all | 1119 // this frame's size. |
| 1120 // subsequent output frames, it can be computed from the previous one's | |
| 1121 // top address and the current frame's size. | |
| 1122 Register fp_reg = InterpretedFrame::fp_register(); | |
| 1123 intptr_t top_address; | 1120 intptr_t top_address; |
| 1124 if (is_bottommost) { | 1121 if (is_bottommost) { |
| 1125 top_address = caller_frame_top_ - output_frame_size; | 1122 top_address = caller_frame_top_ - output_frame_size; |
| 1126 } else { | 1123 } else { |
| 1127 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1124 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1128 } | 1125 } |
| 1129 output_frame->SetTop(top_address); | 1126 output_frame->SetTop(top_address); |
| 1130 | 1127 |
| 1131 // Compute the incoming parameter translation. | 1128 // Compute the incoming parameter translation. |
| 1132 unsigned output_offset = output_frame_size; | 1129 unsigned output_offset = output_frame_size; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1161 // pointer. | 1158 // pointer. |
| 1162 output_offset -= kFPOnStackSize; | 1159 output_offset -= kFPOnStackSize; |
| 1163 if (is_bottommost) { | 1160 if (is_bottommost) { |
| 1164 value = caller_fp_; | 1161 value = caller_fp_; |
| 1165 } else { | 1162 } else { |
| 1166 value = output_[frame_index - 1]->GetFp(); | 1163 value = output_[frame_index - 1]->GetFp(); |
| 1167 } | 1164 } |
| 1168 output_frame->SetCallerFp(output_offset, value); | 1165 output_frame->SetCallerFp(output_offset, value); |
| 1169 intptr_t fp_value = top_address + output_offset; | 1166 intptr_t fp_value = top_address + output_offset; |
| 1170 output_frame->SetFp(fp_value); | 1167 output_frame->SetFp(fp_value); |
| 1171 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 1168 if (is_topmost) { |
| 1169 Register fp_reg = InterpretedFrame::fp_register(); |
| 1170 output_frame->SetRegister(fp_reg.code(), fp_value); |
| 1171 } |
| 1172 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 1172 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
| 1173 | 1173 |
| 1174 if (FLAG_enable_embedded_constant_pool) { | 1174 if (FLAG_enable_embedded_constant_pool) { |
| 1175 // For the bottommost output frame the constant pool pointer can be gotten | 1175 // For the bottommost output frame the constant pool pointer can be gotten |
| 1176 // from the input frame. For subsequent output frames, it can be read from | 1176 // from the input frame. For subsequent output frames, it can be read from |
| 1177 // the previous frame. | 1177 // the previous frame. |
| 1178 output_offset -= kPointerSize; | 1178 output_offset -= kPointerSize; |
| 1179 if (is_bottommost) { | 1179 if (is_bottommost) { |
| 1180 value = caller_constant_pool_; | 1180 value = caller_constant_pool_; |
| 1181 } else { | 1181 } else { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 int parameter_count = height; | 1325 int parameter_count = height; |
| 1326 FrameDescription* output_frame = new (output_frame_size) | 1326 FrameDescription* output_frame = new (output_frame_size) |
| 1327 FrameDescription(output_frame_size, parameter_count); | 1327 FrameDescription(output_frame_size, parameter_count); |
| 1328 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); | 1328 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
| 1329 | 1329 |
| 1330 // Arguments adaptor can not be topmost. | 1330 // Arguments adaptor can not be topmost. |
| 1331 CHECK(frame_index < output_count_ - 1); | 1331 CHECK(frame_index < output_count_ - 1); |
| 1332 CHECK(output_[frame_index] == NULL); | 1332 CHECK(output_[frame_index] == NULL); |
| 1333 output_[frame_index] = output_frame; | 1333 output_[frame_index] = output_frame; |
| 1334 | 1334 |
| 1335 // The top address of the frame is computed from the previous | 1335 // The top address of the frame is computed from the previous frame's top and |
| 1336 // frame's top and this frame's size. | 1336 // this frame's size. |
| 1337 intptr_t top_address; | 1337 intptr_t top_address; |
| 1338 if (is_bottommost) { | 1338 if (is_bottommost) { |
| 1339 top_address = caller_frame_top_ - output_frame_size; | 1339 top_address = caller_frame_top_ - output_frame_size; |
| 1340 } else { | 1340 } else { |
| 1341 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1341 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1342 } | 1342 } |
| 1343 output_frame->SetTop(top_address); | 1343 output_frame->SetTop(top_address); |
| 1344 | 1344 |
| 1345 // Compute the incoming parameter translation. | 1345 // Compute the incoming parameter translation. |
| 1346 unsigned output_offset = output_frame_size; | 1346 unsigned output_offset = output_frame_size; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 | 1476 |
| 1477 if (trace_scope_ != NULL) { | 1477 if (trace_scope_ != NULL) { |
| 1478 PrintF(trace_scope_->file(), | 1478 PrintF(trace_scope_->file(), |
| 1479 " dropping caller arguments adaptor frame: offset=%d, " | 1479 " dropping caller arguments adaptor frame: offset=%d, " |
| 1480 "fp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR | 1480 "fp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR |
| 1481 ", " | 1481 ", " |
| 1482 "caller sp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR "\n", | 1482 "caller sp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR "\n", |
| 1483 offset, stack_fp_, new_stack_fp, caller_frame_top_, | 1483 offset, stack_fp_, new_stack_fp, caller_frame_top_, |
| 1484 new_caller_frame_top); | 1484 new_caller_frame_top); |
| 1485 } | 1485 } |
| 1486 stack_fp_ = new_stack_fp; | |
| 1487 caller_frame_top_ = new_caller_frame_top; | 1486 caller_frame_top_ = new_caller_frame_top; |
| 1488 caller_fp_ = adaptor_caller_fp; | 1487 caller_fp_ = adaptor_caller_fp; |
| 1489 caller_pc_ = adaptor_caller_pc; | 1488 caller_pc_ = adaptor_caller_pc; |
| 1490 } | 1489 } |
| 1491 | 1490 |
| 1492 void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, | 1491 void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, |
| 1493 int frame_index) { | 1492 int frame_index) { |
| 1494 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1493 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 1495 int input_index = 0; | 1494 int input_index = 0; |
| 1496 | 1495 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1512 // Allocate and store the output frame description. | 1511 // Allocate and store the output frame description. |
| 1513 FrameDescription* output_frame = | 1512 FrameDescription* output_frame = |
| 1514 new (output_frame_size) FrameDescription(output_frame_size); | 1513 new (output_frame_size) FrameDescription(output_frame_size); |
| 1515 output_frame->SetFrameType(StackFrame::CONSTRUCT); | 1514 output_frame->SetFrameType(StackFrame::CONSTRUCT); |
| 1516 | 1515 |
| 1517 // Construct stub can not be topmost or bottommost. | 1516 // Construct stub can not be topmost or bottommost. |
| 1518 DCHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1517 DCHECK(frame_index > 0 && frame_index < output_count_ - 1); |
| 1519 DCHECK(output_[frame_index] == NULL); | 1518 DCHECK(output_[frame_index] == NULL); |
| 1520 output_[frame_index] = output_frame; | 1519 output_[frame_index] = output_frame; |
| 1521 | 1520 |
| 1522 // The top address of the frame is computed from the previous | 1521 // The top address of the frame is computed from the previous frame's top and |
| 1523 // frame's top and this frame's size. | 1522 // this frame's size. |
| 1524 intptr_t top_address; | 1523 intptr_t top_address; |
| 1525 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1524 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1526 output_frame->SetTop(top_address); | 1525 output_frame->SetTop(top_address); |
| 1527 | 1526 |
| 1528 // Compute the incoming parameter translation. | 1527 // Compute the incoming parameter translation. |
| 1529 int parameter_count = height; | 1528 int parameter_count = height; |
| 1530 unsigned output_offset = output_frame_size; | 1529 unsigned output_offset = output_frame_size; |
| 1531 for (int i = 0; i < parameter_count; ++i) { | 1530 for (int i = 0; i < parameter_count; ++i) { |
| 1532 output_offset -= kPointerSize; | 1531 output_offset -= kPointerSize; |
| 1533 // The allocated receiver of a construct stub frame is passed as the | 1532 // The allocated receiver of a construct stub frame is passed as the |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1798 height_in_bytes); | 1797 height_in_bytes); |
| 1799 } | 1798 } |
| 1800 | 1799 |
| 1801 // The stub failure trampoline is a single frame. | 1800 // The stub failure trampoline is a single frame. |
| 1802 FrameDescription* output_frame = | 1801 FrameDescription* output_frame = |
| 1803 new (output_frame_size) FrameDescription(output_frame_size); | 1802 new (output_frame_size) FrameDescription(output_frame_size); |
| 1804 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 1803 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 1805 CHECK_EQ(frame_index, 0); | 1804 CHECK_EQ(frame_index, 0); |
| 1806 output_[frame_index] = output_frame; | 1805 output_[frame_index] = output_frame; |
| 1807 | 1806 |
| 1808 // The top address for the output frame can be computed from the input | 1807 // The top address of the frame is computed from the previous frame's top and |
| 1809 // frame pointer and the output frame's height. Subtract space for the | 1808 // this frame's size. |
| 1810 // context and function slots. | 1809 intptr_t top_address = caller_frame_top_ - output_frame_size; |
| 1811 Register fp_reg = StubFailureTrampolineFrame::fp_register(); | |
| 1812 intptr_t top_address = | |
| 1813 stack_fp_ - StubFailureTrampolineFrameConstants::kFixedFrameSizeFromFp - | |
| 1814 height_in_bytes; | |
| 1815 output_frame->SetTop(top_address); | 1810 output_frame->SetTop(top_address); |
| 1816 | 1811 |
| 1817 // Set caller's PC (JSFunction continuation). | 1812 // Set caller's PC (JSFunction continuation). |
| 1818 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; | 1813 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; |
| 1819 intptr_t value = caller_pc_; | 1814 intptr_t value = caller_pc_; |
| 1820 output_frame->SetCallerPc(output_frame_offset, value); | 1815 output_frame->SetCallerPc(output_frame_offset, value); |
| 1821 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1816 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 1822 "caller's pc\n"); | 1817 "caller's pc\n"); |
| 1823 | 1818 |
| 1824 // Read caller's FP from the input frame, and set this frame's FP. | 1819 // Read caller's FP from the input frame, and set this frame's FP. |
| 1825 value = caller_fp_; | 1820 value = caller_fp_; |
| 1826 output_frame_offset -= kFPOnStackSize; | 1821 output_frame_offset -= kFPOnStackSize; |
| 1827 output_frame->SetCallerFp(output_frame_offset, value); | 1822 output_frame->SetCallerFp(output_frame_offset, value); |
| 1828 intptr_t frame_ptr = stack_fp_; | 1823 intptr_t frame_ptr = top_address + output_frame_offset; |
| 1824 Register fp_reg = StubFailureTrampolineFrame::fp_register(); |
| 1829 output_frame->SetRegister(fp_reg.code(), frame_ptr); | 1825 output_frame->SetRegister(fp_reg.code(), frame_ptr); |
| 1830 output_frame->SetFp(frame_ptr); | 1826 output_frame->SetFp(frame_ptr); |
| 1831 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1827 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 1832 "caller's fp\n"); | 1828 "caller's fp\n"); |
| 1833 | 1829 |
| 1834 if (FLAG_enable_embedded_constant_pool) { | 1830 if (FLAG_enable_embedded_constant_pool) { |
| 1835 // Read the caller's constant pool from the input frame. | 1831 // Read the caller's constant pool from the input frame. |
| 1836 value = caller_constant_pool_; | 1832 value = caller_constant_pool_; |
| 1837 output_frame_offset -= kPointerSize; | 1833 output_frame_offset -= kPointerSize; |
| 1838 output_frame->SetCallerConstantPool(output_frame_offset, value); | 1834 output_frame->SetCallerConstantPool(output_frame_offset, value); |
| (...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3812 CHECK(value_info->IsMaterializedObject()); | 3808 CHECK(value_info->IsMaterializedObject()); |
| 3813 | 3809 |
| 3814 value_info->value_ = | 3810 value_info->value_ = |
| 3815 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3811 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
| 3816 } | 3812 } |
| 3817 } | 3813 } |
| 3818 } | 3814 } |
| 3819 | 3815 |
| 3820 } // namespace internal | 3816 } // namespace internal |
| 3821 } // namespace v8 | 3817 } // namespace v8 |
| OLD | NEW |