Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: src/deoptimizer.cc

Issue 1969423002: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | src/full-codegen/arm/full-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 if (trace_scope_ != NULL) { 834 if (trace_scope_ != NULL) {
835 double ms = timer.Elapsed().InMillisecondsF(); 835 double ms = timer.Elapsed().InMillisecondsF();
836 int index = output_count_ - 1; // Index of the topmost frame. 836 int index = output_count_ - 1; // Index of the topmost frame.
837 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", 837 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
838 MessageFor(bailout_type_)); 838 MessageFor(bailout_type_));
839 PrintFunctionName(); 839 PrintFunctionName();
840 PrintF(trace_scope_->file(), 840 PrintF(trace_scope_->file(),
841 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR 841 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR
842 ", state=%s, took %0.3f ms]\n", 842 ", state=%s, took %0.3f ms]\n",
843 bailout_id_, node_id.ToInt(), output_[index]->GetPc(), 843 bailout_id_, node_id.ToInt(), output_[index]->GetPc(),
844 caller_frame_top_, FullCodeGenerator::State2String( 844 caller_frame_top_, BailoutStateToString(static_cast<BailoutState>(
845 static_cast<FullCodeGenerator::State>( 845 output_[index]->GetState()->value())),
846 output_[index]->GetState()->value())),
847 ms); 846 ms);
848 } 847 }
849 } 848 }
850 849
851 void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame, 850 void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
852 int frame_index, bool goto_catch_handler) { 851 int frame_index, bool goto_catch_handler) {
853 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); 852 SharedFunctionInfo* shared = translated_frame->raw_shared_info();
854 853
855 TranslatedFrame::iterator value_iterator = translated_frame->begin(); 854 TranslatedFrame::iterator value_iterator = translated_frame->begin();
856 bool is_bottommost = (0 == frame_index); 855 bool is_bottommost = (0 == frame_index);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 Address start = non_optimized_code->instruction_start(); 1047 Address start = non_optimized_code->instruction_start();
1049 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); 1048 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1050 unsigned pc_offset = goto_catch_handler 1049 unsigned pc_offset = goto_catch_handler
1051 ? catch_handler_pc_offset_ 1050 ? catch_handler_pc_offset_
1052 : FullCodeGenerator::PcField::decode(pc_and_state); 1051 : FullCodeGenerator::PcField::decode(pc_and_state);
1053 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); 1052 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1054 output_frame->SetPc(pc_value); 1053 output_frame->SetPc(pc_value);
1055 1054
1056 // If we are going to the catch handler, then the exception lives in 1055 // If we are going to the catch handler, then the exception lives in
1057 // the accumulator. 1056 // the accumulator.
1058 FullCodeGenerator::State state = 1057 BailoutState state =
1059 goto_catch_handler ? FullCodeGenerator::TOS_REG 1058 goto_catch_handler
1060 : FullCodeGenerator::StateField::decode(pc_and_state); 1059 ? BailoutState::TOS_REGISTER
1061 output_frame->SetState(Smi::FromInt(state)); 1060 : FullCodeGenerator::BailoutStateField::decode(pc_and_state);
1061 output_frame->SetState(Smi::FromInt(static_cast<int>(state)));
1062 1062
1063 // Set the continuation for the topmost frame. 1063 // Set the continuation for the topmost frame.
1064 if (is_topmost) { 1064 if (is_topmost) {
1065 Builtins* builtins = isolate_->builtins(); 1065 Builtins* builtins = isolate_->builtins();
1066 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); 1066 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1067 if (bailout_type_ == LAZY) { 1067 if (bailout_type_ == LAZY) {
1068 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); 1068 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1069 } else if (bailout_type_ == SOFT) { 1069 } else if (bailout_type_ == SOFT) {
1070 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); 1070 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1071 } else { 1071 } else {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 } else { 1267 } else {
1268 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, 1268 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1269 output_offset); 1269 output_offset);
1270 } 1270 }
1271 CHECK_EQ(0u, output_offset); 1271 CHECK_EQ(0u, output_offset);
1272 1272
1273 Builtins* builtins = isolate_->builtins(); 1273 Builtins* builtins = isolate_->builtins();
1274 Code* dispatch_builtin = 1274 Code* dispatch_builtin =
1275 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); 1275 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
1276 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); 1276 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry()));
1277 output_frame->SetState(0); 1277 // Restore accumulator (TOS) register.
1278 output_frame->SetState(
1279 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
1278 1280
1279 // Update constant pool. 1281 // Update constant pool.
1280 if (FLAG_enable_embedded_constant_pool) { 1282 if (FLAG_enable_embedded_constant_pool) {
1281 intptr_t constant_pool_value = 1283 intptr_t constant_pool_value =
1282 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); 1284 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool());
1283 output_frame->SetConstantPool(constant_pool_value); 1285 output_frame->SetConstantPool(constant_pool_value);
1284 if (is_topmost) { 1286 if (is_topmost) {
1285 Register constant_pool_reg = 1287 Register constant_pool_reg =
1286 InterpretedFrame::constant_pool_pointer_register(); 1288 InterpretedFrame::constant_pool_pointer_register();
1287 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); 1289 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1288 } 1290 }
1289 } 1291 }
1290 1292
1291 // Set the continuation for the topmost frame. 1293 // Set the continuation for the topmost frame.
1292 if (is_topmost) { 1294 if (is_topmost) {
1293 Code* continuation = 1295 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1294 builtins->builtin(Builtins::kInterpreterNotifyDeoptimized);
1295 if (bailout_type_ == LAZY) { 1296 if (bailout_type_ == LAZY) {
1296 continuation = 1297 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1297 builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized);
1298 } else if (bailout_type_ == SOFT) { 1298 } else if (bailout_type_ == SOFT) {
1299 continuation = 1299 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1300 builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized);
1301 } else { 1300 } else {
1302 CHECK_EQ(bailout_type_, EAGER); 1301 CHECK_EQ(bailout_type_, EAGER);
1303 } 1302 }
1304 output_frame->SetContinuation( 1303 output_frame->SetContinuation(
1305 reinterpret_cast<intptr_t>(continuation->entry())); 1304 reinterpret_cast<intptr_t>(continuation->entry()));
1306 } 1305 }
1307 } 1306 }
1308 1307
1309 void Deoptimizer::DoComputeArgumentsAdaptorFrame( 1308 void Deoptimizer::DoComputeArgumentsAdaptorFrame(
1310 TranslatedFrame* translated_frame, int frame_index) { 1309 TranslatedFrame* translated_frame, int frame_index) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 1503
1505 Builtins* builtins = isolate_->builtins(); 1504 Builtins* builtins = isolate_->builtins();
1506 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 1505 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1507 unsigned height = translated_frame->height(); 1506 unsigned height = translated_frame->height();
1508 unsigned height_in_bytes = height * kPointerSize; 1507 unsigned height_in_bytes = height * kPointerSize;
1509 1508
1510 // If the construct frame appears to be topmost we should ensure that the 1509 // If the construct frame appears to be topmost we should ensure that the
1511 // value of result register is preserved during continuation execution. 1510 // value of result register is preserved during continuation execution.
1512 // We do this here by "pushing" the result of the constructor function to the 1511 // We do this here by "pushing" the result of the constructor function to the
1513 // top of the reconstructed stack and then using the 1512 // top of the reconstructed stack and then using the
1514 // FullCodeGenerator::TOS_REG machinery. 1513 // BailoutState::TOS_REGISTER machinery.
1515 if (is_topmost) { 1514 if (is_topmost) {
1516 height_in_bytes += kPointerSize; 1515 height_in_bytes += kPointerSize;
1517 } 1516 }
1518 1517
1519 // Skip function. 1518 // Skip function.
1520 value_iterator++; 1519 value_iterator++;
1521 input_index++; 1520 input_index++;
1522 if (trace_scope_ != NULL) { 1521 if (trace_scope_ != NULL) {
1523 PrintF(trace_scope_->file(), 1522 PrintF(trace_scope_->file(),
1524 " translating construct stub => height=%d\n", height_in_bytes); 1523 " translating construct stub => height=%d\n", height_in_bytes);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 1624
1626 if (is_topmost) { 1625 if (is_topmost) {
1627 // Ensure the result is restored back when we return to the stub. 1626 // Ensure the result is restored back when we return to the stub.
1628 output_offset -= kPointerSize; 1627 output_offset -= kPointerSize;
1629 Register result_reg = FullCodeGenerator::result_register(); 1628 Register result_reg = FullCodeGenerator::result_register();
1630 value = input_->GetRegister(result_reg.code()); 1629 value = input_->GetRegister(result_reg.code());
1631 output_frame->SetFrameSlot(output_offset, value); 1630 output_frame->SetFrameSlot(output_offset, value);
1632 DebugPrintOutputSlot(value, frame_index, output_offset, 1631 DebugPrintOutputSlot(value, frame_index, output_offset,
1633 "constructor result\n"); 1632 "constructor result\n");
1634 1633
1635 output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG)); 1634 output_frame->SetState(
1635 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
1636 } 1636 }
1637 1637
1638 CHECK_EQ(0u, output_offset); 1638 CHECK_EQ(0u, output_offset);
1639 1639
1640 intptr_t pc = reinterpret_cast<intptr_t>( 1640 intptr_t pc = reinterpret_cast<intptr_t>(
1641 construct_stub->instruction_start() + 1641 construct_stub->instruction_start() +
1642 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 1642 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1643 output_frame->SetPc(pc); 1643 output_frame->SetPc(pc);
1644 if (FLAG_enable_embedded_constant_pool) { 1644 if (FLAG_enable_embedded_constant_pool) {
1645 intptr_t constant_pool_value = 1645 intptr_t constant_pool_value =
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 // The receiver (and the implicit return value, if any) are expected in 1679 // The receiver (and the implicit return value, if any) are expected in
1680 // registers by the LoadIC/StoreIC, so they don't belong to the output stack 1680 // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1681 // frame. This means that we have to use a height of 0. 1681 // frame. This means that we have to use a height of 0.
1682 unsigned height = 0; 1682 unsigned height = 0;
1683 unsigned height_in_bytes = height * kPointerSize; 1683 unsigned height_in_bytes = height * kPointerSize;
1684 1684
1685 // If the accessor frame appears to be topmost we should ensure that the 1685 // If the accessor frame appears to be topmost we should ensure that the
1686 // value of result register is preserved during continuation execution. 1686 // value of result register is preserved during continuation execution.
1687 // We do this here by "pushing" the result of the accessor function to the 1687 // We do this here by "pushing" the result of the accessor function to the
1688 // top of the reconstructed stack and then using the 1688 // top of the reconstructed stack and then using the
1689 // FullCodeGenerator::TOS_REG machinery. 1689 // BailoutState::TOS_REGISTER machinery.
1690 // We don't need to restore the result in case of a setter call because we 1690 // We don't need to restore the result in case of a setter call because we
1691 // have to return the stored value but not the result of the setter function. 1691 // have to return the stored value but not the result of the setter function.
1692 bool should_preserve_result = is_topmost && !is_setter_stub_frame; 1692 bool should_preserve_result = is_topmost && !is_setter_stub_frame;
1693 if (should_preserve_result) { 1693 if (should_preserve_result) {
1694 height_in_bytes += kPointerSize; 1694 height_in_bytes += kPointerSize;
1695 } 1695 }
1696 1696
1697 const char* kind = is_setter_stub_frame ? "setter" : "getter"; 1697 const char* kind = is_setter_stub_frame ? "setter" : "getter";
1698 if (trace_scope_ != NULL) { 1698 if (trace_scope_ != NULL) {
1699 PrintF(trace_scope_->file(), 1699 PrintF(trace_scope_->file(),
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1798 1798
1799 if (should_preserve_result) { 1799 if (should_preserve_result) {
1800 // Ensure the result is restored back when we return to the stub. 1800 // Ensure the result is restored back when we return to the stub.
1801 output_offset -= kPointerSize; 1801 output_offset -= kPointerSize;
1802 Register result_reg = FullCodeGenerator::result_register(); 1802 Register result_reg = FullCodeGenerator::result_register();
1803 value = input_->GetRegister(result_reg.code()); 1803 value = input_->GetRegister(result_reg.code());
1804 output_frame->SetFrameSlot(output_offset, value); 1804 output_frame->SetFrameSlot(output_offset, value);
1805 DebugPrintOutputSlot(value, frame_index, output_offset, 1805 DebugPrintOutputSlot(value, frame_index, output_offset,
1806 "accessor result\n"); 1806 "accessor result\n");
1807 1807
1808 output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG)); 1808 output_frame->SetState(
1809 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER)));
1809 } else { 1810 } else {
1810 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); 1811 output_frame->SetState(
1812 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
1811 } 1813 }
1812 1814
1813 CHECK_EQ(0u, output_offset); 1815 CHECK_EQ(0u, output_offset);
1814 1816
1815 Smi* offset = is_setter_stub_frame ? 1817 Smi* offset = is_setter_stub_frame ?
1816 isolate_->heap()->setter_stub_deopt_pc_offset() : 1818 isolate_->heap()->setter_stub_deopt_pc_offset() :
1817 isolate_->heap()->getter_stub_deopt_pc_offset(); 1819 isolate_->heap()->getter_stub_deopt_pc_offset();
1818 intptr_t pc = reinterpret_cast<intptr_t>( 1820 intptr_t pc = reinterpret_cast<intptr_t>(
1819 accessor_stub->instruction_start() + offset->value()); 1821 accessor_stub->instruction_start() + offset->value());
1820 output_frame->SetPc(pc); 1822 output_frame->SetPc(pc);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 output_frame->SetPc(reinterpret_cast<intptr_t>( 2057 output_frame->SetPc(reinterpret_cast<intptr_t>(
2056 trampoline->instruction_start())); 2058 trampoline->instruction_start()));
2057 if (FLAG_enable_embedded_constant_pool) { 2059 if (FLAG_enable_embedded_constant_pool) {
2058 Register constant_pool_reg = 2060 Register constant_pool_reg =
2059 StubFailureTrampolineFrame::constant_pool_pointer_register(); 2061 StubFailureTrampolineFrame::constant_pool_pointer_register();
2060 intptr_t constant_pool_value = 2062 intptr_t constant_pool_value =
2061 reinterpret_cast<intptr_t>(trampoline->constant_pool()); 2063 reinterpret_cast<intptr_t>(trampoline->constant_pool());
2062 output_frame->SetConstantPool(constant_pool_value); 2064 output_frame->SetConstantPool(constant_pool_value);
2063 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); 2065 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
2064 } 2066 }
2065 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); 2067 output_frame->SetState(
2068 Smi::FromInt(static_cast<int>(BailoutState::NO_REGISTERS)));
2066 Code* notify_failure = 2069 Code* notify_failure =
2067 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); 2070 isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles);
2068 output_frame->SetContinuation( 2071 output_frame->SetContinuation(
2069 reinterpret_cast<intptr_t>(notify_failure->entry())); 2072 reinterpret_cast<intptr_t>(notify_failure->entry()));
2070 } 2073 }
2071 2074
2072 2075
2073 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { 2076 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
2074 // Walk to the last JavaScript output frame to find out if it has 2077 // Walk to the last JavaScript output frame to find out if it has
2075 // adapted arguments. 2078 // adapted arguments.
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after
3923 CHECK(value_info->IsMaterializedObject()); 3926 CHECK(value_info->IsMaterializedObject());
3924 3927
3925 value_info->value_ = 3928 value_info->value_ =
3926 Handle<Object>(previously_materialized_objects->get(i), isolate_); 3929 Handle<Object>(previously_materialized_objects->get(i), isolate_);
3927 } 3930 }
3928 } 3931 }
3929 } 3932 }
3930 3933
3931 } // namespace internal 3934 } // namespace internal
3932 } // namespace v8 3935 } // namespace v8
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/full-codegen/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698