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 |