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

Side by Side Diff: src/deoptimizer.cc

Issue 942513002: Put the type feedback vector in the unoptimized JavaScript frame. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Reduced constant in deep recursion test for windows. Created 5 years, 9 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/frames.h » ('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/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/cpu-profiler.h" 9 #include "src/cpu-profiler.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 return result; 117 return result;
118 } 118 }
119 119
120 120
121 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { 121 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
122 if (jsframe_index == 0) return 0; 122 if (jsframe_index == 0) return 0;
123 123
124 int frame_index = 0; 124 int frame_index = 0;
125 while (jsframe_index >= 0) { 125 while (jsframe_index >= 0) {
126 FrameDescription* frame = output_[frame_index]; 126 FrameDescription* frame = output_[frame_index];
127 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) { 127 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT ||
128 frame->GetFrameType() == StackFrame::OPTIMIZED) {
128 jsframe_index--; 129 jsframe_index--;
129 } 130 }
130 frame_index++; 131 frame_index++;
131 } 132 }
132 133
133 return frame_index - 1; 134 return frame_index - 1;
134 } 135 }
135 136
136 137
137 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 138 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 } 594 }
594 } 595 }
595 compiled_code_ = FindOptimizedCode(function, optimized_code); 596 compiled_code_ = FindOptimizedCode(function, optimized_code);
596 #if DEBUG 597 #if DEBUG
597 DCHECK(compiled_code_ != NULL); 598 DCHECK(compiled_code_ != NULL);
598 if (type == EAGER || type == SOFT || type == LAZY) { 599 if (type == EAGER || type == SOFT || type == LAZY) {
599 DCHECK(compiled_code_->kind() != Code::FUNCTION); 600 DCHECK(compiled_code_->kind() != Code::FUNCTION);
600 } 601 }
601 #endif 602 #endif
602 603
603 StackFrame::Type frame_type = function == NULL 604 StackFrame::Type frame_type =
604 ? StackFrame::STUB 605 function == NULL ? StackFrame::STUB : StackFrame::OPTIMIZED;
605 : StackFrame::JAVA_SCRIPT;
606 trace_scope_ = TraceEnabledFor(type, frame_type) ? 606 trace_scope_ = TraceEnabledFor(type, frame_type) ?
607 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; 607 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL;
608 #ifdef DEBUG 608 #ifdef DEBUG
609 CHECK(AllowHeapAllocation::IsAllowed()); 609 CHECK(AllowHeapAllocation::IsAllowed());
610 disallow_heap_allocation_ = new DisallowHeapAllocation(); 610 disallow_heap_allocation_ = new DisallowHeapAllocation();
611 #endif // DEBUG 611 #endif // DEBUG
612 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { 612 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
613 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_)); 613 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_));
614 } 614 }
615 unsigned size = ComputeInputFrameSize(); 615 unsigned size = ComputeInputFrameSize();
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 unsigned height_in_bytes = height * kPointerSize; 880 unsigned height_in_bytes = height * kPointerSize;
881 if (trace_scope_ != NULL) { 881 if (trace_scope_ != NULL) {
882 PrintF(trace_scope_->file(), " translating "); 882 PrintF(trace_scope_->file(), " translating ");
883 function->PrintName(trace_scope_->file()); 883 function->PrintName(trace_scope_->file());
884 PrintF(trace_scope_->file(), 884 PrintF(trace_scope_->file(),
885 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); 885 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
886 } 886 }
887 887
888 // The 'fixed' part of the frame consists of the incoming parameters and 888 // The 'fixed' part of the frame consists of the incoming parameters and
889 // the part described by JavaScriptFrameConstants. 889 // the part described by JavaScriptFrameConstants.
890 unsigned fixed_frame_size = ComputeFixedSize(function); 890 unsigned fixed_frame_size = ComputeFixedSize(function, true);
891 unsigned input_frame_size = input_->GetFrameSize(); 891 unsigned input_frame_size = input_->GetFrameSize();
892 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 892 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
893 893
894 // Allocate and store the output frame description. 894 // Allocate and store the output frame description.
895 FrameDescription* output_frame = 895 FrameDescription* output_frame =
896 new(output_frame_size) FrameDescription(output_frame_size, function); 896 new(output_frame_size) FrameDescription(output_frame_size, function);
897 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); 897 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
898 898
899 bool is_bottommost = (0 == frame_index); 899 bool is_bottommost = (0 == frame_index);
900 bool is_topmost = (output_count_ - 1 == frame_index); 900 bool is_topmost = (output_count_ - 1 == frame_index);
901 CHECK(frame_index >= 0 && frame_index < output_count_); 901 CHECK(frame_index >= 0 && frame_index < output_count_);
902 CHECK_NULL(output_[frame_index]); 902 CHECK_NULL(output_[frame_index]);
903 output_[frame_index] = output_frame; 903 output_[frame_index] = output_frame;
904 904
905 // The top address for the bottommost output frame can be computed from 905 // The top address for the bottommost output frame can be computed from
906 // the input frame pointer and the output frame's height. For all 906 // the input frame pointer and the output frame's height. For all
907 // subsequent output frames, it can be computed from the previous one's 907 // subsequent output frames, it can be computed from the previous one's
908 // top address and the current frame's size. 908 // top address and the current frame's size.
909 Register fp_reg = JavaScriptFrame::fp_register(); 909 Register fp_reg = JavaScriptFrame::fp_register();
910 intptr_t top_address; 910 intptr_t top_address;
911 if (is_bottommost) { 911 if (is_bottommost) {
912 // Determine whether the input frame contains alignment padding. 912 // Determine whether the input frame contains alignment padding.
913 has_alignment_padding_ = 913 has_alignment_padding_ =
914 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(function)) 914 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(function))
915 ? 1 915 ? 1
916 : 0; 916 : 0;
917 // 2 = context and function in the frame. 917 // 2 = context and function in the frame.
918 // If the optimized frame had alignment padding, adjust the frame pointer 918 // If the optimized frame had alignment padding, adjust the frame pointer
919 // to point to the new position of the old frame pointer after padding 919 // to point to the new position of the old frame pointer after padding
920 // is removed. Subtract 2 * kPointerSize for the context and function slots. 920 // is removed. Subtract the fixed frame size.
921 top_address = input_->GetRegister(fp_reg.code()) - 921 top_address = input_->GetRegister(fp_reg.code()) -
922 StandardFrameConstants::kFixedFrameSizeFromFp - 922 JavaScriptFrameConstants::kUnoptimizedFixedFrameSizeFromFp -
923 height_in_bytes + has_alignment_padding_ * kPointerSize; 923 height_in_bytes + has_alignment_padding_ * kPointerSize;
924 } else { 924 } else {
925 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 925 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
926 } 926 }
927 output_frame->SetTop(top_address); 927 output_frame->SetTop(top_address);
928 928
929 // Compute the incoming parameter translation. 929 // Compute the incoming parameter translation.
930 int parameter_count = 930 int parameter_count =
931 function->shared()->internal_formal_parameter_count() + 1; 931 function->shared()->internal_formal_parameter_count() + 1;
932 unsigned output_offset = output_frame_size; 932 unsigned output_offset = output_frame_size;
933 unsigned input_offset = input_frame_size; 933 unsigned input_offset = input_frame_size;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 // input frame. 1047 // input frame.
1048 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value); 1048 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
1049 output_frame->SetFrameSlot(output_offset, value); 1049 output_frame->SetFrameSlot(output_offset, value);
1050 if (trace_scope_ != NULL) { 1050 if (trace_scope_ != NULL) {
1051 PrintF(trace_scope_->file(), 1051 PrintF(trace_scope_->file(),
1052 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1052 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1053 V8PRIxPTR "; function\n", 1053 V8PRIxPTR "; function\n",
1054 top_address + output_offset, output_offset, value); 1054 top_address + output_offset, output_offset, value);
1055 } 1055 }
1056 1056
1057 // The type feedback vector must be retrieved from the function, as it's
1058 // not available in the input frame.
1059 output_offset -= kPointerSize;
1060 TypeFeedbackVector* vector = function->shared()->feedback_vector();
1061 value = reinterpret_cast<intptr_t>(vector);
1062 output_frame->SetFrameSlot(output_offset, value);
1063 if (trace_scope_ != NULL) {
1064 PrintF(trace_scope_->file(),
1065 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR "; vector\n",
1066 top_address + output_offset, output_offset, value);
1067 }
1068
1057 // Translate the rest of the frame. 1069 // Translate the rest of the frame.
1058 for (unsigned i = 0; i < height; ++i) { 1070 for (unsigned i = 0; i < height; ++i) {
1059 output_offset -= kPointerSize; 1071 output_offset -= kPointerSize;
1060 DoTranslateCommand(iterator, frame_index, output_offset); 1072 DoTranslateCommand(iterator, frame_index, output_offset);
1061 } 1073 }
1062 CHECK_EQ(0u, output_offset); 1074 CHECK_EQ(0u, output_offset);
1063 1075
1064 // Compute this frame's PC, state, and continuation. 1076 // Compute this frame's PC, state, and continuation.
1065 Code* non_optimized_code = function->shared()->code(); 1077 Code* non_optimized_code = function->shared()->code();
1066 FixedArray* raw_data = non_optimized_code->deoptimization_data(); 1078 FixedArray* raw_data = non_optimized_code->deoptimization_data();
(...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after
2703 StandardFrameConstants::kFixedFrameSizeFromFp; 2715 StandardFrameConstants::kFixedFrameSizeFromFp;
2704 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { 2716 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
2705 unsigned stack_slots = compiled_code_->stack_slots(); 2717 unsigned stack_slots = compiled_code_->stack_slots();
2706 unsigned outgoing_size = ComputeOutgoingArgumentSize(); 2718 unsigned outgoing_size = ComputeOutgoingArgumentSize();
2707 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); 2719 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
2708 } 2720 }
2709 return result; 2721 return result;
2710 } 2722 }
2711 2723
2712 2724
2713 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { 2725 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function,
2726 bool unoptimized_frame) const {
2714 // The fixed part of the frame consists of the return address, frame 2727 // The fixed part of the frame consists of the return address, frame
2715 // pointer, function, context, and all the incoming arguments. 2728 // pointer, function, context, and all the incoming arguments.
2716 return ComputeIncomingArgumentSize(function) + 2729 return ComputeIncomingArgumentSize(function) +
2717 StandardFrameConstants::kFixedFrameSize; 2730 (unoptimized_frame
2731 ? JavaScriptFrameConstants::kUnoptimizedFixedFrameSize
2732 : StandardFrameConstants::kFixedFrameSize);
2718 } 2733 }
2719 2734
2720 2735
2721 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 2736 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
2722 // The incoming arguments is the values for formal parameters and 2737 // The incoming arguments is the values for formal parameters and
2723 // the receiver. Every slot contains a pointer. 2738 // the receiver. Every slot contains a pointer.
2724 if (function->IsSmi()) { 2739 if (function->IsSmi()) {
2725 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB)); 2740 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
2726 return 0; 2741 return 0;
2727 } 2742 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2833 } 2848 }
2834 2849
2835 // Zap all the slots. 2850 // Zap all the slots.
2836 for (unsigned o = 0; o < frame_size; o += kPointerSize) { 2851 for (unsigned o = 0; o < frame_size; o += kPointerSize) {
2837 SetFrameSlot(o, kZapUint32); 2852 SetFrameSlot(o, kZapUint32);
2838 } 2853 }
2839 } 2854 }
2840 2855
2841 2856
2842 int FrameDescription::ComputeFixedSize() { 2857 int FrameDescription::ComputeFixedSize() {
2843 return StandardFrameConstants::kFixedFrameSize + 2858 // Full-code javascript frames have a type feedback vector.
2844 (ComputeParametersCount() + 1) * kPointerSize; 2859 const int fixed_size =
2860 type_ == StackFrame::JAVA_SCRIPT
2861 ? JavaScriptFrameConstants::kUnoptimizedFixedFrameSize
2862 : StandardFrameConstants::kFixedFrameSize;
2863 return fixed_size + (ComputeParametersCount() + 1) * kPointerSize;
2845 } 2864 }
2846 2865
2847 2866
2848 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { 2867 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
2849 if (slot_index >= 0) { 2868 if (slot_index >= 0) {
2850 // Local or spill slots. Skip the fixed part of the frame 2869 // Local or spill slots. Skip the fixed part of the frame
2851 // including all arguments. 2870 // including all arguments.
2852 unsigned base = GetFrameSize() - ComputeFixedSize(); 2871 unsigned base = GetFrameSize() - ComputeFixedSize();
2853 return base - ((slot_index + 1) * kPointerSize); 2872 return base - ((slot_index + 1) * kPointerSize);
2854 } else { 2873 } else {
2855 // Incoming parameter. 2874 // Incoming parameter.
2856 int arg_size = (ComputeParametersCount() + 1) * kPointerSize; 2875 int arg_size = (ComputeParametersCount() + 1) * kPointerSize;
2857 unsigned base = GetFrameSize() - arg_size; 2876 unsigned base = GetFrameSize() - arg_size;
2858 return base - ((slot_index + 1) * kPointerSize); 2877 return base - ((slot_index + 1) * kPointerSize);
2859 } 2878 }
2860 } 2879 }
2861 2880
2862 2881
2863 int FrameDescription::ComputeParametersCount() { 2882 int FrameDescription::ComputeParametersCount() {
2864 switch (type_) { 2883 switch (type_) {
2884 case StackFrame::OPTIMIZED:
2865 case StackFrame::JAVA_SCRIPT: 2885 case StackFrame::JAVA_SCRIPT:
2866 return function_->shared()->internal_formal_parameter_count(); 2886 return function_->shared()->internal_formal_parameter_count();
2867 case StackFrame::ARGUMENTS_ADAPTOR: { 2887 case StackFrame::ARGUMENTS_ADAPTOR: {
2868 // Last slot contains number of incomming arguments as a smi. 2888 // Last slot contains number of incomming arguments as a smi.
2869 // Can't use GetExpression(0) because it would cause infinite recursion. 2889 // Can't use GetExpression(0) because it would cause infinite recursion.
2870 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value(); 2890 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
2871 } 2891 }
2872 case StackFrame::STUB: 2892 case StackFrame::STUB:
2873 return -1; // Minus receiver. 2893 return -1; // Minus receiver.
2874 default: 2894 default:
2875 FATAL("Unexpected stack frame type"); 2895 FATAL("Unexpected stack frame type");
2876 return 0; 2896 return 0;
2877 } 2897 }
2878 } 2898 }
2879 2899
2880 2900
2881 Object* FrameDescription::GetParameter(int index) { 2901 Object* FrameDescription::GetParameter(int index) {
2882 CHECK_GE(index, 0); 2902 CHECK_GE(index, 0);
2883 CHECK_LT(index, ComputeParametersCount()); 2903 CHECK_LT(index, ComputeParametersCount());
2884 // The slot indexes for incoming arguments are negative. 2904 // The slot indexes for incoming arguments are negative.
2885 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount()); 2905 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
2886 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2906 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2887 } 2907 }
2888 2908
2889 2909
2890 unsigned FrameDescription::GetExpressionCount() { 2910 unsigned FrameDescription::GetExpressionCount() {
2891 CHECK_EQ(StackFrame::JAVA_SCRIPT, type_); 2911 CHECK(type_ == StackFrame::JAVA_SCRIPT);
2892 unsigned size = GetFrameSize() - ComputeFixedSize(); 2912 unsigned size = GetFrameSize() - ComputeFixedSize();
2893 return size / kPointerSize; 2913 return size / kPointerSize;
2894 } 2914 }
2895 2915
2896 2916
2897 Object* FrameDescription::GetExpression(int index) { 2917 Object* FrameDescription::GetExpression(int index) {
2898 DCHECK_EQ(StackFrame::JAVA_SCRIPT, type_); 2918 DCHECK(type_ == StackFrame::JAVA_SCRIPT);
2899 unsigned offset = GetOffsetFromSlotIndex(index); 2919 unsigned offset = GetOffsetFromSlotIndex(index);
2900 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2920 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2901 } 2921 }
2902 2922
2903 2923
2904 void TranslationBuffer::Add(int32_t value, Zone* zone) { 2924 void TranslationBuffer::Add(int32_t value, Zone* zone) {
2905 // Encode the sign bit in the least significant bit. 2925 // Encode the sign bit in the least significant bit.
2906 bool is_negative = (value < 0); 2926 bool is_negative = (value < 0);
2907 uint32_t bits = ((is_negative ? -value : value) << 1) | 2927 uint32_t bits = ((is_negative ? -value : value) << 1) |
2908 static_cast<int32_t>(is_negative); 2928 static_cast<int32_t>(is_negative);
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
3660 int raw_position = static_cast<int>(info->data()); 3680 int raw_position = static_cast<int>(info->data());
3661 last_position = raw_position ? SourcePosition::FromRaw(raw_position) 3681 last_position = raw_position ? SourcePosition::FromRaw(raw_position)
3662 : SourcePosition::Unknown(); 3682 : SourcePosition::Unknown();
3663 } else if (info->rmode() == RelocInfo::DEOPT_REASON) { 3683 } else if (info->rmode() == RelocInfo::DEOPT_REASON) {
3664 last_reason = static_cast<Deoptimizer::DeoptReason>(info->data()); 3684 last_reason = static_cast<Deoptimizer::DeoptReason>(info->data());
3665 } 3685 }
3666 } 3686 }
3667 return DeoptInfo(SourcePosition::Unknown(), NULL, Deoptimizer::kNoReason); 3687 return DeoptInfo(SourcePosition::Unknown(), NULL, Deoptimizer::kNoReason);
3668 } 3688 }
3669 } } // namespace v8::internal 3689 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698