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

Side by Side Diff: src/deoptimizer.cc

Issue 1686183003: Use SharedFunctionInfo rather than the JSFunction in the deoptimizer (first step). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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/ia32/deoptimizer-ia32.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 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 output_[index]->GetState()->value())), 806 output_[index]->GetState()->value())),
807 has_alignment_padding_ ? "with padding" : "no padding", 807 has_alignment_padding_ ? "with padding" : "no padding",
808 ms); 808 ms);
809 } 809 }
810 } 810 }
811 811
812 812
813 void Deoptimizer::DoComputeJSFrame(int frame_index) { 813 void Deoptimizer::DoComputeJSFrame(int frame_index) {
814 TranslatedFrame* translated_frame = 814 TranslatedFrame* translated_frame =
815 &(translated_state_.frames()[frame_index]); 815 &(translated_state_.frames()[frame_index]);
816 SharedFunctionInfo* shared = translated_frame->raw_shared_info();
817
816 TranslatedFrame::iterator value_iterator = translated_frame->begin(); 818 TranslatedFrame::iterator value_iterator = translated_frame->begin();
817 int input_index = 0; 819 int input_index = 0;
818 820
819 BailoutId node_id = translated_frame->node_id(); 821 BailoutId node_id = translated_frame->node_id();
820 unsigned height = 822 unsigned height =
821 translated_frame->height() - 1; // Do not count the context. 823 translated_frame->height() - 1; // Do not count the context.
822 unsigned height_in_bytes = height * kPointerSize; 824 unsigned height_in_bytes = height * kPointerSize;
823 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); 825 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
824 value_iterator++; 826 value_iterator++;
825 input_index++; 827 input_index++;
826 if (trace_scope_ != NULL) { 828 if (trace_scope_ != NULL) {
827 PrintF(trace_scope_->file(), " translating frame "); 829 PrintF(trace_scope_->file(), " translating frame ");
828 function->PrintName(trace_scope_->file()); 830 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString();
831 PrintF(trace_scope_->file(), "%s", name.get());
829 PrintF(trace_scope_->file(), 832 PrintF(trace_scope_->file(),
830 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); 833 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
831 } 834 }
832 835
833 // The 'fixed' part of the frame consists of the incoming parameters and 836 // The 'fixed' part of the frame consists of the incoming parameters and
834 // the part described by JavaScriptFrameConstants. 837 // the part described by JavaScriptFrameConstants.
835 unsigned fixed_frame_size = ComputeJavascriptFixedSize(function); 838 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
836 unsigned input_frame_size = input_->GetFrameSize(); 839 unsigned input_frame_size = input_->GetFrameSize();
837 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 840 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
838 841
839 // Allocate and store the output frame description. 842 // Allocate and store the output frame description.
840 FrameDescription* output_frame = 843 FrameDescription* output_frame =
841 new(output_frame_size) FrameDescription(output_frame_size, function); 844 new(output_frame_size) FrameDescription(output_frame_size, function);
842 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); 845 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
843 846
844 bool is_bottommost = (0 == frame_index); 847 bool is_bottommost = (0 == frame_index);
845 bool is_topmost = (output_count_ - 1 == frame_index); 848 bool is_topmost = (output_count_ - 1 == frame_index);
846 CHECK(frame_index >= 0 && frame_index < output_count_); 849 CHECK(frame_index >= 0 && frame_index < output_count_);
847 CHECK_NULL(output_[frame_index]); 850 CHECK_NULL(output_[frame_index]);
848 output_[frame_index] = output_frame; 851 output_[frame_index] = output_frame;
849 852
850 // The top address for the bottommost output frame can be computed from 853 // The top address for the bottommost output frame can be computed from
851 // the input frame pointer and the output frame's height. For all 854 // the input frame pointer and the output frame's height. For all
852 // subsequent output frames, it can be computed from the previous one's 855 // subsequent output frames, it can be computed from the previous one's
853 // top address and the current frame's size. 856 // top address and the current frame's size.
854 Register fp_reg = JavaScriptFrame::fp_register(); 857 Register fp_reg = JavaScriptFrame::fp_register();
855 intptr_t top_address; 858 intptr_t top_address;
856 if (is_bottommost) { 859 if (is_bottommost) {
857 // Determine whether the input frame contains alignment padding. 860 // Determine whether the input frame contains alignment padding.
858 has_alignment_padding_ = 861 has_alignment_padding_ =
859 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(function)) 862 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(shared)) ? 1
860 ? 1 863 : 0;
861 : 0;
862 // 2 = context and function in the frame. 864 // 2 = context and function in the frame.
863 // If the optimized frame had alignment padding, adjust the frame pointer 865 // If the optimized frame had alignment padding, adjust the frame pointer
864 // to point to the new position of the old frame pointer after padding 866 // to point to the new position of the old frame pointer after padding
865 // is removed. Subtract 2 * kPointerSize for the context and function slots. 867 // is removed. Subtract 2 * kPointerSize for the context and function slots.
866 top_address = input_->GetRegister(fp_reg.code()) - 868 top_address = input_->GetRegister(fp_reg.code()) -
867 StandardFrameConstants::kFixedFrameSizeFromFp - 869 StandardFrameConstants::kFixedFrameSizeFromFp -
868 height_in_bytes + has_alignment_padding_ * kPointerSize; 870 height_in_bytes + has_alignment_padding_ * kPointerSize;
869 } else { 871 } else {
870 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 872 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
871 } 873 }
872 output_frame->SetTop(top_address); 874 output_frame->SetTop(top_address);
873 875
874 // Compute the incoming parameter translation. 876 // Compute the incoming parameter translation.
875 int parameter_count = 877 int parameter_count = shared->internal_formal_parameter_count() + 1;
876 function->shared()->internal_formal_parameter_count() + 1;
877 unsigned output_offset = output_frame_size; 878 unsigned output_offset = output_frame_size;
878 unsigned input_offset = input_frame_size; 879 unsigned input_offset = input_frame_size;
879 for (int i = 0; i < parameter_count; ++i) { 880 for (int i = 0; i < parameter_count; ++i) {
880 output_offset -= kPointerSize; 881 output_offset -= kPointerSize;
881 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, 882 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
882 output_offset); 883 output_offset);
883 } 884 }
884 input_offset -= (parameter_count * kPointerSize); 885 input_offset -= (parameter_count * kPointerSize);
885 886
886 // There are no translation commands for the caller's pc and fp, the 887 // There are no translation commands for the caller's pc and fp, the
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 982
982 // Translate the rest of the frame. 983 // Translate the rest of the frame.
983 for (unsigned i = 0; i < height; ++i) { 984 for (unsigned i = 0; i < height; ++i) {
984 output_offset -= kPointerSize; 985 output_offset -= kPointerSize;
985 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, 986 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
986 output_offset); 987 output_offset);
987 } 988 }
988 CHECK_EQ(0u, output_offset); 989 CHECK_EQ(0u, output_offset);
989 990
990 // Compute this frame's PC, state, and continuation. 991 // Compute this frame's PC, state, and continuation.
991 Code* non_optimized_code = function->shared()->code(); 992 Code* non_optimized_code = shared->code();
992 FixedArray* raw_data = non_optimized_code->deoptimization_data(); 993 FixedArray* raw_data = non_optimized_code->deoptimization_data();
993 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); 994 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
994 Address start = non_optimized_code->instruction_start(); 995 Address start = non_optimized_code->instruction_start();
995 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); 996 unsigned pc_and_state = GetOutputInfo(data, node_id, shared);
996 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); 997 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
997 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); 998 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
998 output_frame->SetPc(pc_value); 999 output_frame->SetPc(pc_value);
999 1000
1000 // Update constant pool. 1001 // Update constant pool.
1001 if (FLAG_enable_embedded_constant_pool) { 1002 if (FLAG_enable_embedded_constant_pool) {
1002 intptr_t constant_pool_value = 1003 intptr_t constant_pool_value =
1003 reinterpret_cast<intptr_t>(non_optimized_code->constant_pool()); 1004 reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
1004 output_frame->SetConstantPool(constant_pool_value); 1005 output_frame->SetConstantPool(constant_pool_value);
1005 if (is_topmost) { 1006 if (is_topmost) {
(...skipping 20 matching lines...) Expand all
1026 } 1027 }
1027 output_frame->SetContinuation( 1028 output_frame->SetContinuation(
1028 reinterpret_cast<intptr_t>(continuation->entry())); 1029 reinterpret_cast<intptr_t>(continuation->entry()));
1029 } 1030 }
1030 } 1031 }
1031 1032
1032 1033
1033 void Deoptimizer::DoComputeInterpretedFrame(int frame_index) { 1034 void Deoptimizer::DoComputeInterpretedFrame(int frame_index) {
1034 TranslatedFrame* translated_frame = 1035 TranslatedFrame* translated_frame =
1035 &(translated_state_.frames()[frame_index]); 1036 &(translated_state_.frames()[frame_index]);
1037 SharedFunctionInfo* shared = translated_frame->raw_shared_info();
1038
1036 TranslatedFrame::iterator value_iterator = translated_frame->begin(); 1039 TranslatedFrame::iterator value_iterator = translated_frame->begin();
1037 int input_index = 0; 1040 int input_index = 0;
1038 1041
1039 BailoutId bytecode_offset = translated_frame->node_id(); 1042 BailoutId bytecode_offset = translated_frame->node_id();
1040 unsigned height = translated_frame->height(); 1043 unsigned height = translated_frame->height();
1041 unsigned height_in_bytes = height * kPointerSize; 1044 unsigned height_in_bytes = height * kPointerSize;
1042 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); 1045 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
1043 value_iterator++; 1046 value_iterator++;
1044 input_index++; 1047 input_index++;
1045 if (trace_scope_ != NULL) { 1048 if (trace_scope_ != NULL) {
1046 PrintF(trace_scope_->file(), " translating interpreted frame "); 1049 PrintF(trace_scope_->file(), " translating interpreted frame ");
1047 function->PrintName(trace_scope_->file()); 1050 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString();
1051 PrintF(trace_scope_->file(), "%s", name.get());
1048 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d\n", 1052 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d\n",
1049 bytecode_offset.ToInt(), height_in_bytes); 1053 bytecode_offset.ToInt(), height_in_bytes);
1050 } 1054 }
1051 1055
1052 // The 'fixed' part of the frame consists of the incoming parameters and 1056 // The 'fixed' part of the frame consists of the incoming parameters and
1053 // the part described by InterpreterFrameConstants. 1057 // the part described by InterpreterFrameConstants.
1054 unsigned fixed_frame_size = ComputeInterpretedFixedSize(function); 1058 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared);
1055 unsigned input_frame_size = input_->GetFrameSize(); 1059 unsigned input_frame_size = input_->GetFrameSize();
1056 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1060 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1057 1061
1058 // Allocate and store the output frame description. 1062 // Allocate and store the output frame description.
1059 FrameDescription* output_frame = 1063 FrameDescription* output_frame =
1060 new (output_frame_size) FrameDescription(output_frame_size, function); 1064 new (output_frame_size) FrameDescription(output_frame_size, function);
1061 output_frame->SetFrameType(StackFrame::INTERPRETED); 1065 output_frame->SetFrameType(StackFrame::INTERPRETED);
1062 1066
1063 bool is_bottommost = (0 == frame_index); 1067 bool is_bottommost = (0 == frame_index);
1064 bool is_topmost = (output_count_ - 1 == frame_index); 1068 bool is_topmost = (output_count_ - 1 == frame_index);
(...skipping 12 matching lines...) Expand all
1077 // new,target and bytecode offset. 1081 // new,target and bytecode offset.
1078 top_address = input_->GetRegister(fp_reg.code()) - 1082 top_address = input_->GetRegister(fp_reg.code()) -
1079 InterpreterFrameConstants::kFixedFrameSizeFromFp - 1083 InterpreterFrameConstants::kFixedFrameSizeFromFp -
1080 height_in_bytes; 1084 height_in_bytes;
1081 } else { 1085 } else {
1082 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1086 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1083 } 1087 }
1084 output_frame->SetTop(top_address); 1088 output_frame->SetTop(top_address);
1085 1089
1086 // Compute the incoming parameter translation. 1090 // Compute the incoming parameter translation.
1087 int parameter_count = 1091 int parameter_count = shared->internal_formal_parameter_count() + 1;
1088 function->shared()->internal_formal_parameter_count() + 1;
1089 unsigned output_offset = output_frame_size; 1092 unsigned output_offset = output_frame_size;
1090 unsigned input_offset = input_frame_size; 1093 unsigned input_offset = input_frame_size;
1091 for (int i = 0; i < parameter_count; ++i) { 1094 for (int i = 0; i < parameter_count; ++i) {
1092 output_offset -= kPointerSize; 1095 output_offset -= kPointerSize;
1093 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, 1096 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1094 output_offset); 1097 output_offset);
1095 } 1098 }
1096 input_offset -= (parameter_count * kPointerSize); 1099 input_offset -= (parameter_count * kPointerSize);
1097 1100
1098 // There are no translation commands for the caller's pc and fp, the 1101 // There are no translation commands for the caller's pc and fp, the
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
1974 output_offset; 1977 output_offset;
1975 PrintF(trace_scope_->file(), 1978 PrintF(trace_scope_->file(),
1976 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", 1979 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s",
1977 reinterpret_cast<intptr_t>(output_address), output_offset, value, 1980 reinterpret_cast<intptr_t>(output_address), output_offset, value,
1978 debug_hint_string == nullptr ? "" : debug_hint_string); 1981 debug_hint_string == nullptr ? "" : debug_hint_string);
1979 } 1982 }
1980 } 1983 }
1981 1984
1982 1985
1983 unsigned Deoptimizer::ComputeInputFrameSize() const { 1986 unsigned Deoptimizer::ComputeInputFrameSize() const {
1984 unsigned fixed_size = ComputeJavascriptFixedSize(function_); 1987 unsigned fixed_size = StandardFrameConstants::kFixedFrameSize;
1988 if (!function_->IsSmi()) {
1989 fixed_size += ComputeIncomingArgumentSize(function_->shared());
1990 } else {
1991 CHECK_EQ(Smi::cast(function_), Smi::FromInt(StackFrame::STUB));
1992 }
1985 // The fp-to-sp delta already takes the context, constant pool pointer and the 1993 // The fp-to-sp delta already takes the context, constant pool pointer and the
1986 // function into account so we have to avoid double counting them. 1994 // function into account so we have to avoid double counting them.
1987 unsigned result = fixed_size + fp_to_sp_delta_ - 1995 unsigned result = fixed_size + fp_to_sp_delta_ -
1988 StandardFrameConstants::kFixedFrameSizeFromFp; 1996 StandardFrameConstants::kFixedFrameSizeFromFp;
1989 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { 1997 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
1990 unsigned stack_slots = compiled_code_->stack_slots(); 1998 unsigned stack_slots = compiled_code_->stack_slots();
1991 unsigned outgoing_size = 1999 unsigned outgoing_size =
1992 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); 2000 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
1993 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); 2001 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
1994 } 2002 }
1995 return result; 2003 return result;
1996 } 2004 }
1997 2005
1998 2006 // static
1999 unsigned Deoptimizer::ComputeJavascriptFixedSize(JSFunction* function) const { 2007 unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) {
2000 // The fixed part of the frame consists of the return address, frame 2008 // The fixed part of the frame consists of the return address, frame
2001 // pointer, function, context, and all the incoming arguments. 2009 // pointer, function, context, and all the incoming arguments.
2002 return ComputeIncomingArgumentSize(function) + 2010 return ComputeIncomingArgumentSize(shared) +
2003 StandardFrameConstants::kFixedFrameSize; 2011 StandardFrameConstants::kFixedFrameSize;
2004 } 2012 }
2005 2013
2006 2014 // static
2007 unsigned Deoptimizer::ComputeInterpretedFixedSize(JSFunction* function) const { 2015 unsigned Deoptimizer::ComputeInterpretedFixedSize(SharedFunctionInfo* shared) {
2008 // The fixed part of the frame consists of the return address, frame 2016 // The fixed part of the frame consists of the return address, frame
2009 // pointer, function, context, new.target, bytecode offset and all the 2017 // pointer, function, context, new.target, bytecode offset and all the
2010 // incoming arguments. 2018 // incoming arguments.
2011 return ComputeIncomingArgumentSize(function) + 2019 return ComputeIncomingArgumentSize(shared) +
2012 InterpreterFrameConstants::kFixedFrameSize; 2020 InterpreterFrameConstants::kFixedFrameSize;
2013 } 2021 }
2014 2022
2015 2023 // static
2016 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 2024 unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
2017 // The incoming arguments is the values for formal parameters and 2025 return (shared->internal_formal_parameter_count() + 1) * kPointerSize;
2018 // the receiver. Every slot contains a pointer.
2019 if (function->IsSmi()) {
2020 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
2021 return 0;
2022 }
2023 unsigned arguments =
2024 function->shared()->internal_formal_parameter_count() + 1;
2025 return arguments * kPointerSize;
2026 } 2026 }
2027 2027
2028 2028
2029 // static 2029 // static
2030 unsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code, 2030 unsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
2031 unsigned bailout_id) { 2031 unsigned bailout_id) {
2032 DeoptimizationInputData* data = 2032 DeoptimizationInputData* data =
2033 DeoptimizationInputData::cast(code->deoptimization_data()); 2033 DeoptimizationInputData::cast(code->deoptimization_data());
2034 unsigned height = data->ArgumentsStackHeight(bailout_id)->value(); 2034 unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
2035 return height * kPointerSize; 2035 return height * kPointerSize;
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after
3699 DCHECK(value_info->IsMaterializedObject()); 3699 DCHECK(value_info->IsMaterializedObject());
3700 3700
3701 value_info->value_ = 3701 value_info->value_ =
3702 Handle<Object>(previously_materialized_objects->get(i), isolate_); 3702 Handle<Object>(previously_materialized_objects->get(i), isolate_);
3703 } 3703 }
3704 } 3704 }
3705 } 3705 }
3706 3706
3707 } // namespace internal 3707 } // namespace internal
3708 } // namespace v8 3708 } // namespace v8
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698