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