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

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: ia32 lithium fix. Created 5 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
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/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/disasm.h" 10 #include "src/disasm.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
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;
124 while (jsframe_index >= 0) { 124 while (jsframe_index >= 0) {
125 FrameDescription* frame = output_[frame_index]; 125 FrameDescription* frame = output_[frame_index];
126 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) { 126 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT ||
127 frame->GetFrameType() == StackFrame::OPTIMIZED) {
127 jsframe_index--; 128 jsframe_index--;
128 } 129 }
129 frame_index++; 130 frame_index++;
130 } 131 }
131 132
132 return frame_index - 1; 133 return frame_index - 1;
133 } 134 }
134 135
135 136
136 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 137 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 } 593 }
593 } 594 }
594 compiled_code_ = FindOptimizedCode(function, optimized_code); 595 compiled_code_ = FindOptimizedCode(function, optimized_code);
595 #if DEBUG 596 #if DEBUG
596 DCHECK(compiled_code_ != NULL); 597 DCHECK(compiled_code_ != NULL);
597 if (type == EAGER || type == SOFT || type == LAZY) { 598 if (type == EAGER || type == SOFT || type == LAZY) {
598 DCHECK(compiled_code_->kind() != Code::FUNCTION); 599 DCHECK(compiled_code_->kind() != Code::FUNCTION);
599 } 600 }
600 #endif 601 #endif
601 602
602 StackFrame::Type frame_type = function == NULL 603 StackFrame::Type frame_type =
603 ? StackFrame::STUB 604 function == NULL ? StackFrame::STUB : StackFrame::OPTIMIZED;
604 : StackFrame::JAVA_SCRIPT;
605 trace_scope_ = TraceEnabledFor(type, frame_type) ? 605 trace_scope_ = TraceEnabledFor(type, frame_type) ?
606 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; 606 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL;
607 #ifdef DEBUG 607 #ifdef DEBUG
608 CHECK(AllowHeapAllocation::IsAllowed()); 608 CHECK(AllowHeapAllocation::IsAllowed());
609 disallow_heap_allocation_ = new DisallowHeapAllocation(); 609 disallow_heap_allocation_ = new DisallowHeapAllocation();
610 #endif // DEBUG 610 #endif // DEBUG
611 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { 611 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
612 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, bailout_id_, from_, 612 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, bailout_id_, from_,
613 fp_to_sp_delta_)); 613 fp_to_sp_delta_));
614 } 614 }
(...skipping 265 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 || type_ == StackFrame::OPTIMIZED);
Jarin 2015/02/26 09:22:06 I am quite confused about how we could get StackFr
mvstanton 2015/03/20 12:21:09 Good point, I've fixed it. That change came out of
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 || type_ == StackFrame::OPTIMIZED);
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 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
3672 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), 3692 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(),
3673 Deoptimizer::LAZY))) { 3693 Deoptimizer::LAZY))) {
3674 CHECK(RelocInfo::IsRuntimeEntry(info->rmode())); 3694 CHECK(RelocInfo::IsRuntimeEntry(info->rmode()));
3675 return DeoptInfo(last_position, NULL, last_reason); 3695 return DeoptInfo(last_position, NULL, last_reason);
3676 } 3696 }
3677 } 3697 }
3678 } 3698 }
3679 return DeoptInfo(0, NULL, Deoptimizer::kNoReason); 3699 return DeoptInfo(0, NULL, Deoptimizer::kNoReason);
3680 } 3700 }
3681 } } // namespace v8::internal 3701 } } // namespace v8::internal
OLDNEW
« src/arm/macro-assembler-arm.h ('K') | « src/deoptimizer.h ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698