| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_; | 103 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_; |
| 104 int commit_page_size = static_cast<int>(base::OS::CommitPageSize()); | 104 int commit_page_size = static_cast<int>(base::OS::CommitPageSize()); |
| 105 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) / | 105 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) / |
| 106 commit_page_size) + 1; | 106 commit_page_size) + 1; |
| 107 return static_cast<size_t>(commit_page_size * page_count); | 107 return static_cast<size_t>(commit_page_size * page_count); |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { | 111 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { |
| 112 Deoptimizer* result = isolate->deoptimizer_data()->current_; | 112 Deoptimizer* result = isolate->deoptimizer_data()->current_; |
| 113 CHECK_NE(result, NULL); | 113 CHECK_NOT_NULL(result); |
| 114 result->DeleteFrameDescriptions(); | 114 result->DeleteFrameDescriptions(); |
| 115 isolate->deoptimizer_data()->current_ = NULL; | 115 isolate->deoptimizer_data()->current_ = NULL; |
| 116 return result; | 116 return result; |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { | 120 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { |
| 121 if (jsframe_index == 0) return 0; | 121 if (jsframe_index == 0) return 0; |
| 122 | 122 |
| 123 int frame_index = 0; | 123 int frame_index = 0; |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 894 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 895 | 895 |
| 896 // Allocate and store the output frame description. | 896 // Allocate and store the output frame description. |
| 897 FrameDescription* output_frame = | 897 FrameDescription* output_frame = |
| 898 new(output_frame_size) FrameDescription(output_frame_size, function); | 898 new(output_frame_size) FrameDescription(output_frame_size, function); |
| 899 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 899 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
| 900 | 900 |
| 901 bool is_bottommost = (0 == frame_index); | 901 bool is_bottommost = (0 == frame_index); |
| 902 bool is_topmost = (output_count_ - 1 == frame_index); | 902 bool is_topmost = (output_count_ - 1 == frame_index); |
| 903 CHECK(frame_index >= 0 && frame_index < output_count_); | 903 CHECK(frame_index >= 0 && frame_index < output_count_); |
| 904 CHECK_EQ(output_[frame_index], NULL); | 904 CHECK_NULL(output_[frame_index]); |
| 905 output_[frame_index] = output_frame; | 905 output_[frame_index] = output_frame; |
| 906 | 906 |
| 907 // The top address for the bottommost output frame can be computed from | 907 // The top address for the bottommost output frame can be computed from |
| 908 // the input frame pointer and the output frame's height. For all | 908 // the input frame pointer and the output frame's height. For all |
| 909 // subsequent output frames, it can be computed from the previous one's | 909 // subsequent output frames, it can be computed from the previous one's |
| 910 // top address and the current frame's size. | 910 // top address and the current frame's size. |
| 911 Register fp_reg = JavaScriptFrame::fp_register(); | 911 Register fp_reg = JavaScriptFrame::fp_register(); |
| 912 intptr_t top_address; | 912 intptr_t top_address; |
| 913 if (is_bottommost) { | 913 if (is_bottommost) { |
| 914 // Determine whether the input frame contains alignment padding. | 914 // Determine whether the input frame contains alignment padding. |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1053 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1054 V8PRIxPTR "; function\n", | 1054 V8PRIxPTR "; function\n", |
| 1055 top_address + output_offset, output_offset, value); | 1055 top_address + output_offset, output_offset, value); |
| 1056 } | 1056 } |
| 1057 | 1057 |
| 1058 // Translate the rest of the frame. | 1058 // Translate the rest of the frame. |
| 1059 for (unsigned i = 0; i < height; ++i) { | 1059 for (unsigned i = 0; i < height; ++i) { |
| 1060 output_offset -= kPointerSize; | 1060 output_offset -= kPointerSize; |
| 1061 DoTranslateCommand(iterator, frame_index, output_offset); | 1061 DoTranslateCommand(iterator, frame_index, output_offset); |
| 1062 } | 1062 } |
| 1063 CHECK_EQ(0, output_offset); | 1063 CHECK_EQ(0u, output_offset); |
| 1064 | 1064 |
| 1065 // Compute this frame's PC, state, and continuation. | 1065 // Compute this frame's PC, state, and continuation. |
| 1066 Code* non_optimized_code = function->shared()->code(); | 1066 Code* non_optimized_code = function->shared()->code(); |
| 1067 FixedArray* raw_data = non_optimized_code->deoptimization_data(); | 1067 FixedArray* raw_data = non_optimized_code->deoptimization_data(); |
| 1068 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); | 1068 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); |
| 1069 Address start = non_optimized_code->instruction_start(); | 1069 Address start = non_optimized_code->instruction_start(); |
| 1070 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); | 1070 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); |
| 1071 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); | 1071 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); |
| 1072 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); | 1072 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); |
| 1073 output_frame->SetPc(pc_value); | 1073 output_frame->SetPc(pc_value); |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 output_offset -= kPointerSize; | 1375 output_offset -= kPointerSize; |
| 1376 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); | 1376 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); |
| 1377 output_frame->SetFrameSlot(output_offset, value); | 1377 output_frame->SetFrameSlot(output_offset, value); |
| 1378 if (trace_scope_ != NULL) { | 1378 if (trace_scope_ != NULL) { |
| 1379 PrintF(trace_scope_->file(), | 1379 PrintF(trace_scope_->file(), |
| 1380 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1380 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1381 V8PRIxPTR " ; allocated receiver\n", | 1381 V8PRIxPTR " ; allocated receiver\n", |
| 1382 top_address + output_offset, output_offset, value); | 1382 top_address + output_offset, output_offset, value); |
| 1383 } | 1383 } |
| 1384 | 1384 |
| 1385 CHECK_EQ(0, output_offset); | 1385 CHECK_EQ(0u, output_offset); |
| 1386 | 1386 |
| 1387 intptr_t pc = reinterpret_cast<intptr_t>( | 1387 intptr_t pc = reinterpret_cast<intptr_t>( |
| 1388 construct_stub->instruction_start() + | 1388 construct_stub->instruction_start() + |
| 1389 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 1389 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
| 1390 output_frame->SetPc(pc); | 1390 output_frame->SetPc(pc); |
| 1391 if (FLAG_enable_ool_constant_pool) { | 1391 if (FLAG_enable_ool_constant_pool) { |
| 1392 intptr_t constant_pool_value = | 1392 intptr_t constant_pool_value = |
| 1393 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); | 1393 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); |
| 1394 output_frame->SetConstantPool(constant_pool_value); | 1394 output_frame->SetConstantPool(constant_pool_value); |
| 1395 } | 1395 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1422 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; | 1422 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; |
| 1423 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1423 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 1424 | 1424 |
| 1425 // Allocate and store the output frame description. | 1425 // Allocate and store the output frame description. |
| 1426 FrameDescription* output_frame = | 1426 FrameDescription* output_frame = |
| 1427 new(output_frame_size) FrameDescription(output_frame_size, accessor); | 1427 new(output_frame_size) FrameDescription(output_frame_size, accessor); |
| 1428 output_frame->SetFrameType(StackFrame::INTERNAL); | 1428 output_frame->SetFrameType(StackFrame::INTERNAL); |
| 1429 | 1429 |
| 1430 // A frame for an accessor stub can not be the topmost or bottommost one. | 1430 // A frame for an accessor stub can not be the topmost or bottommost one. |
| 1431 CHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1431 CHECK(frame_index > 0 && frame_index < output_count_ - 1); |
| 1432 CHECK_EQ(output_[frame_index], NULL); | 1432 CHECK_NULL(output_[frame_index]); |
| 1433 output_[frame_index] = output_frame; | 1433 output_[frame_index] = output_frame; |
| 1434 | 1434 |
| 1435 // The top address of the frame is computed from the previous frame's top and | 1435 // The top address of the frame is computed from the previous frame's top and |
| 1436 // this frame's size. | 1436 // this frame's size. |
| 1437 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1437 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1438 output_frame->SetTop(top_address); | 1438 output_frame->SetTop(top_address); |
| 1439 | 1439 |
| 1440 unsigned output_offset = output_frame_size; | 1440 unsigned output_offset = output_frame_size; |
| 1441 | 1441 |
| 1442 // Read caller's PC from the previous frame. | 1442 // Read caller's PC from the previous frame. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 // Skip receiver. | 1515 // Skip receiver. |
| 1516 DoTranslateObjectAndSkip(iterator); | 1516 DoTranslateObjectAndSkip(iterator); |
| 1517 | 1517 |
| 1518 if (is_setter_stub_frame) { | 1518 if (is_setter_stub_frame) { |
| 1519 // The implicit return value was part of the artificial setter stub | 1519 // The implicit return value was part of the artificial setter stub |
| 1520 // environment. | 1520 // environment. |
| 1521 output_offset -= kPointerSize; | 1521 output_offset -= kPointerSize; |
| 1522 DoTranslateCommand(iterator, frame_index, output_offset); | 1522 DoTranslateCommand(iterator, frame_index, output_offset); |
| 1523 } | 1523 } |
| 1524 | 1524 |
| 1525 CHECK_EQ(output_offset, 0); | 1525 CHECK_EQ(0u, output_offset); |
| 1526 | 1526 |
| 1527 Smi* offset = is_setter_stub_frame ? | 1527 Smi* offset = is_setter_stub_frame ? |
| 1528 isolate_->heap()->setter_stub_deopt_pc_offset() : | 1528 isolate_->heap()->setter_stub_deopt_pc_offset() : |
| 1529 isolate_->heap()->getter_stub_deopt_pc_offset(); | 1529 isolate_->heap()->getter_stub_deopt_pc_offset(); |
| 1530 intptr_t pc = reinterpret_cast<intptr_t>( | 1530 intptr_t pc = reinterpret_cast<intptr_t>( |
| 1531 accessor_stub->instruction_start() + offset->value()); | 1531 accessor_stub->instruction_start() + offset->value()); |
| 1532 output_frame->SetPc(pc); | 1532 output_frame->SetPc(pc); |
| 1533 if (FLAG_enable_ool_constant_pool) { | 1533 if (FLAG_enable_ool_constant_pool) { |
| 1534 intptr_t constant_pool_value = | 1534 intptr_t constant_pool_value = |
| 1535 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); | 1535 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 int arguments_length_offset = -1; | 1728 int arguments_length_offset = -1; |
| 1729 for (int i = 0; i < param_count; ++i) { | 1729 for (int i = 0; i < param_count; ++i) { |
| 1730 output_frame_offset -= kPointerSize; | 1730 output_frame_offset -= kPointerSize; |
| 1731 DoTranslateCommand(iterator, 0, output_frame_offset); | 1731 DoTranslateCommand(iterator, 0, output_frame_offset); |
| 1732 | 1732 |
| 1733 if (!arg_count_known && descriptor.IsEnvironmentParameterCountRegister(i)) { | 1733 if (!arg_count_known && descriptor.IsEnvironmentParameterCountRegister(i)) { |
| 1734 arguments_length_offset = output_frame_offset; | 1734 arguments_length_offset = output_frame_offset; |
| 1735 } | 1735 } |
| 1736 } | 1736 } |
| 1737 | 1737 |
| 1738 CHECK_EQ(output_frame_offset, 0); | 1738 CHECK_EQ(0u, output_frame_offset); |
| 1739 | 1739 |
| 1740 if (!arg_count_known) { | 1740 if (!arg_count_known) { |
| 1741 CHECK_GE(arguments_length_offset, 0); | 1741 CHECK_GE(arguments_length_offset, 0); |
| 1742 // We know it's a smi because 1) the code stub guarantees the stack | 1742 // We know it's a smi because 1) the code stub guarantees the stack |
| 1743 // parameter count is in smi range, and 2) the DoTranslateCommand in the | 1743 // parameter count is in smi range, and 2) the DoTranslateCommand in the |
| 1744 // parameter loop above translated that to a tagged value. | 1744 // parameter loop above translated that to a tagged value. |
| 1745 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( | 1745 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( |
| 1746 output_frame->GetFrameSlot(arguments_length_offset)); | 1746 output_frame->GetFrameSlot(arguments_length_offset)); |
| 1747 caller_arg_count = smi_caller_arg_count->value(); | 1747 caller_arg_count = smi_caller_arg_count->value(); |
| 1748 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); | 1748 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); |
| (...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3622 | 3622 |
| 3623 | 3623 |
| 3624 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3624 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 3625 v->VisitPointer(bit_cast<Object**>(&function_)); | 3625 v->VisitPointer(bit_cast<Object**>(&function_)); |
| 3626 v->VisitPointer(&context_); | 3626 v->VisitPointer(&context_); |
| 3627 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3627 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 3628 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3628 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 3629 } | 3629 } |
| 3630 | 3630 |
| 3631 } } // namespace v8::internal | 3631 } } // namespace v8::internal |
| OLD | NEW |