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

Side by Side Diff: src/ic/ic.cc

Issue 2503183002: [Tracing] Implement IC statistics in tracing. (Closed)
Patch Set: add cache for function name Created 4 years 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/ic/ic.h" 5 #include "src/ic/ic.h"
6 6
7 #include <iostream> 7 #include <iostream>
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/api-arguments-inl.h" 10 #include "src/api-arguments-inl.h"
11 #include "src/api.h" 11 #include "src/api.h"
12 #include "src/arguments.h" 12 #include "src/arguments.h"
13 #include "src/base/bits.h" 13 #include "src/base/bits.h"
14 #include "src/codegen.h" 14 #include "src/codegen.h"
15 #include "src/conversions.h" 15 #include "src/conversions.h"
16 #include "src/execution.h" 16 #include "src/execution.h"
17 #include "src/field-type.h" 17 #include "src/field-type.h"
18 #include "src/frames-inl.h" 18 #include "src/frames-inl.h"
19 #include "src/ic/call-optimization.h" 19 #include "src/ic/call-optimization.h"
20 #include "src/ic/handler-compiler.h" 20 #include "src/ic/handler-compiler.h"
21 #include "src/ic/handler-configuration-inl.h" 21 #include "src/ic/handler-configuration-inl.h"
22 #include "src/ic/ic-compiler.h" 22 #include "src/ic/ic-compiler.h"
23 #include "src/ic/ic-inl.h" 23 #include "src/ic/ic-inl.h"
24 #include "src/ic/ic-stats.h"
24 #include "src/ic/stub-cache.h" 25 #include "src/ic/stub-cache.h"
25 #include "src/isolate-inl.h" 26 #include "src/isolate-inl.h"
26 #include "src/macro-assembler.h" 27 #include "src/macro-assembler.h"
27 #include "src/prototype.h" 28 #include "src/prototype.h"
28 #include "src/runtime-profiler.h" 29 #include "src/runtime-profiler.h"
29 #include "src/runtime/runtime-utils.h" 30 #include "src/runtime/runtime-utils.h"
30 #include "src/runtime/runtime.h" 31 #include "src/runtime/runtime.h"
31 #include "src/tracing/trace-event.h" 32 #include "src/tracing/trace-event.h"
33 #include "src/tracing/tracing-category-observer.h"
32 34
33 namespace v8 { 35 namespace v8 {
34 namespace internal { 36 namespace internal {
35 37
36 char IC::TransitionMarkFromState(IC::State state) { 38 char IC::TransitionMarkFromState(IC::State state) {
37 switch (state) { 39 switch (state) {
38 case UNINITIALIZED: 40 case UNINITIALIZED:
39 return '0'; 41 return '0';
40 case PREMONOMORPHIC: 42 case PREMONOMORPHIC:
41 return '.'; 43 return '.';
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 if (FLAG_trace_ic) { \ 85 if (FLAG_trace_ic) { \
84 PrintF("[%s patching generic stub in ", type); \ 86 PrintF("[%s patching generic stub in ", type); \
85 PrintF("(see below) (%s)]\n", reason); \ 87 PrintF("(see below) (%s)]\n", reason); \
86 } \ 88 } \
87 } while (false) 89 } while (false)
88 90
89 #endif // DEBUG 91 #endif // DEBUG
90 92
91 93
92 void IC::TraceIC(const char* type, Handle<Object> name) { 94 void IC::TraceIC(const char* type, Handle<Object> name) {
93 if (FLAG_trace_ic) { 95 if (FLAG_ic_stats) {
94 if (AddressIsDeoptimizedCode()) return; 96 if (AddressIsDeoptimizedCode()) return;
95 DCHECK(UseVector()); 97 DCHECK(UseVector());
96 State new_state = nexus()->StateFromFeedback(); 98 State new_state = nexus()->StateFromFeedback();
97 TraceIC(type, name, state(), new_state); 99 TraceIC(type, name, state(), new_state);
98 } 100 }
99 } 101 }
100 102
101 103
102 void IC::TraceIC(const char* type, Handle<Object> name, State old_state, 104 void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
103 State new_state) { 105 State new_state) {
104 if (!FLAG_trace_ic) return; 106 if (V8_LIKELY(!FLAG_ic_stats)) return;
105 PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type); 107
108 if (FLAG_ic_stats &
Camillo Bruni 2016/12/02 12:12:55 no need to recheck the flag
lpy 2016/12/05 17:49:11 same here, we want to check whether the flag is en
109 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
110 ICStats::instance()->Begin();
111 ICInfo& ic_info = ICStats::instance()->Current();
112 ic_info.type = is_keyed() ? "Keyed" : "";
113 ic_info.type += type;
114 } else if (FLAG_ic_stats) {
Camillo Bruni 2016/12/02 12:12:55 same here.
lpy 2016/12/05 17:49:11 see explanation above
115 PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type);
116 }
106 117
107 // TODO(jkummerow): Add support for "apply". The logic is roughly: 118 // TODO(jkummerow): Add support for "apply". The logic is roughly:
108 // marker = [fp_ + kMarkerOffset]; 119 // marker = [fp_ + kMarkerOffset];
109 // if marker is smi and marker.value == INTERNAL and 120 // if marker is smi and marker.value == INTERNAL and
110 // the frame's code == builtin(Builtins::kFunctionApply): 121 // the frame's code == builtin(Builtins::kFunctionApply):
111 // then print "apply from" and advance one frame 122 // then print "apply from" and advance one frame
112 123
113 Object* maybe_function = 124 Object* maybe_function =
114 Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset); 125 Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset);
115 if (maybe_function->IsJSFunction()) { 126 if (maybe_function->IsJSFunction()) {
116 JSFunction* function = JSFunction::cast(maybe_function); 127 JSFunction* function = JSFunction::cast(maybe_function);
117 int code_offset = 0; 128 int code_offset = 0;
118 if (function->IsInterpreted()) { 129 if (function->IsInterpreted()) {
119 code_offset = InterpretedFrame::GetBytecodeOffset(fp()); 130 code_offset = InterpretedFrame::GetBytecodeOffset(fp());
120 } else { 131 } else {
121 code_offset = 132 code_offset =
122 static_cast<int>(pc() - function->code()->instruction_start()); 133 static_cast<int>(pc() - function->code()->instruction_start());
123 } 134 }
124 JavaScriptFrame::PrintFunctionAndOffset(function, function->abstract_code(), 135 if (FLAG_ic_stats &
125 code_offset, stdout, true); 136 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
137 JavaScriptFrame::CollectFunctionAndOffsetForICStats(
138 function, function->abstract_code(), code_offset);
139 } else if (FLAG_ic_stats) {
140 JavaScriptFrame::PrintFunctionAndOffset(
141 function, function->abstract_code(), code_offset, stdout, true);
142 }
126 } 143 }
127 144
128 const char* modifier = ""; 145 const char* modifier = "";
129 if (kind() == Code::KEYED_STORE_IC) { 146 if (kind() == Code::KEYED_STORE_IC) {
130 KeyedAccessStoreMode mode = 147 KeyedAccessStoreMode mode =
131 casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); 148 casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode();
132 modifier = GetTransitionMarkModifier(mode); 149 modifier = GetTransitionMarkModifier(mode);
133 } 150 }
134 Map* map = nullptr; 151 Map* map = nullptr;
135 if (!receiver_map().is_null()) { 152 if (!receiver_map().is_null()) {
136 map = *receiver_map(); 153 map = *receiver_map();
137 } 154 }
138 PrintF(" (%c->%c%s) map=(%p", TransitionMarkFromState(old_state), 155 if (FLAG_ic_stats &
139 TransitionMarkFromState(new_state), modifier, 156 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
140 reinterpret_cast<void*>(map)); 157 ICInfo& ic_info = ICStats::instance()->Current();
158 ic_info.state = "(";
Camillo Bruni 2016/12/02 12:12:55 I'm not too familiar with the C++ standard library
lpy 2016/12/05 17:49:11 Done.
159 ic_info.state += TransitionMarkFromState(old_state);
160 ic_info.state += "->";
161 ic_info.state += TransitionMarkFromState(new_state);
162 ic_info.state += modifier;
163 ic_info.state += ")";
164 ic_info.map = reinterpret_cast<void*>(map);
165 } else if (FLAG_ic_stats) {
166 PrintF(" (%c->%c%s) map=(%p", TransitionMarkFromState(old_state),
167 TransitionMarkFromState(new_state), modifier,
168 reinterpret_cast<void*>(map));
169 }
141 if (map != nullptr) { 170 if (map != nullptr) {
142 PrintF(" dict=%u own=%u type=", map->is_dictionary_map(), 171 if (FLAG_ic_stats &
143 map->NumberOfOwnDescriptors()); 172 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
144 std::cout << map->instance_type(); 173 ICInfo& ic_info = ICStats::instance()->Current();
174 ic_info.dict = map->is_dictionary_map();
175 ic_info.own = map->NumberOfOwnDescriptors();
176 ic_info.instance_type = std::to_string(map->instance_type());
177 } else if (FLAG_ic_stats) {
178 PrintF(" dict=%u own=%u type=", map->is_dictionary_map(),
179 map->NumberOfOwnDescriptors());
180 std::cout << map->instance_type();
181 }
145 } 182 }
146 PrintF(") "); 183 if (FLAG_ic_stats &
147 name->ShortPrint(stdout); 184 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
148 PrintF("]\n"); 185 // TODO(lpy) Add name as key field in ICStats.
186 ICStats::instance()->End();
187 } else if (FLAG_ic_stats) {
188 PrintF(") ");
189 name->ShortPrint(stdout);
190 PrintF("]\n");
191 }
149 } 192 }
150 193
151 194
152 #define TRACE_IC(type, name) TraceIC(type, name) 195 #define TRACE_IC(type, name) TraceIC(type, name)
153 196
154 197
155 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus) 198 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
156 : isolate_(isolate), 199 : isolate_(isolate),
157 vector_set_(false), 200 vector_set_(false),
158 target_maps_set_(false), 201 target_maps_set_(false),
(...skipping 2746 matching lines...) Expand 10 before | Expand all | Expand 10 after
2905 } else { 2948 } else {
2906 // Install the generic stub. 2949 // Install the generic stub.
2907 BinaryOpICStub stub(isolate(), state); 2950 BinaryOpICStub stub(isolate(), state);
2908 new_target = stub.GetCode(); 2951 new_target = stub.GetCode();
2909 2952
2910 // Sanity check the generic stub. 2953 // Sanity check the generic stub.
2911 DCHECK_NULL(new_target->FindFirstAllocationSite()); 2954 DCHECK_NULL(new_target->FindFirstAllocationSite());
2912 } 2955 }
2913 set_target(*new_target); 2956 set_target(*new_target);
2914 2957
2915 if (FLAG_trace_ic) { 2958 if (FLAG_ic_stats &
2959 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
2960 auto ic_stats = ICStats::instance();
2961 ic_stats->Begin();
2962 ICInfo& ic_info = ic_stats->Current();
2963 ic_info.type = "BinaryOpIC";
2964 ic_info.state = old_state.ToString();
2965 ic_info.state += " => ";
2966 ic_info.state += state.ToString();
2967 JavaScriptFrame::CollectTopFrameForICStats(isolate());
2968 ic_stats->End();
2969 } else if (FLAG_ic_stats) {
2970 // if (FLAG_trace_ic) {
2916 OFStream os(stdout); 2971 OFStream os(stdout);
2917 os << "[BinaryOpIC" << old_state << " => " << state << " @ " 2972 os << "[BinaryOpIC" << old_state << " => " << state << " @ "
2918 << static_cast<void*>(*new_target) << " <- "; 2973 << static_cast<void*>(*new_target) << " <- ";
2919 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2974 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2920 if (!allocation_site.is_null()) { 2975 if (!allocation_site.is_null()) {
2921 os << " using allocation site " << static_cast<void*>(*allocation_site); 2976 os << " using allocation site " << static_cast<void*>(*allocation_site);
2922 } 2977 }
2923 os << "]" << std::endl; 2978 os << "]" << std::endl;
2924 } 2979 }
2925 2980
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 isolate(), old_stub.state(), old_stub.left(), old_stub.right(), op_, 3034 isolate(), old_stub.state(), old_stub.left(), old_stub.right(), op_,
2980 HasInlinedSmiCode(address()), x, y); 3035 HasInlinedSmiCode(address()), x, y);
2981 CompareICStub stub(isolate(), op_, new_left, new_right, state); 3036 CompareICStub stub(isolate(), op_, new_left, new_right, state);
2982 if (state == CompareICState::KNOWN_RECEIVER) { 3037 if (state == CompareICState::KNOWN_RECEIVER) {
2983 stub.set_known_map( 3038 stub.set_known_map(
2984 Handle<Map>(Handle<JSReceiver>::cast(x)->map(), isolate())); 3039 Handle<Map>(Handle<JSReceiver>::cast(x)->map(), isolate()));
2985 } 3040 }
2986 Handle<Code> new_target = stub.GetCode(); 3041 Handle<Code> new_target = stub.GetCode();
2987 set_target(*new_target); 3042 set_target(*new_target);
2988 3043
2989 if (FLAG_trace_ic) { 3044 if (FLAG_ic_stats &
3045 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
3046 auto ic_stats = ICStats::instance();
3047 ic_stats->Begin();
3048 ICInfo& ic_info = ic_stats->Current();
3049 ic_info.type = "CompareIC";
3050 JavaScriptFrame::CollectTopFrameForICStats(isolate());
3051 ic_info.state = "((";
3052 ic_info.state += CompareICState::GetStateName(old_stub.left());
3053 ic_info.state += "+";
3054 ic_info.state += CompareICState::GetStateName(old_stub.right());
3055 ic_info.state += "=";
3056 ic_info.state += CompareICState::GetStateName(old_stub.state());
3057 ic_info.state += ")->(";
3058 ic_info.state += CompareICState::GetStateName(new_left);
3059 ic_info.state += "+";
3060 ic_info.state += CompareICState::GetStateName(new_right);
3061 ic_info.state += "=";
3062 ic_info.state += CompareICState::GetStateName(state);
3063 ic_info.state += "))#";
3064 ic_info.state += Token::Name(op_);
3065 ic_stats->End();
3066 } else if (FLAG_ic_stats) {
3067 // if (FLAG_trace_ic) {
2990 PrintF("[CompareIC in "); 3068 PrintF("[CompareIC in ");
2991 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 3069 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2992 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", 3070 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
2993 CompareICState::GetStateName(old_stub.left()), 3071 CompareICState::GetStateName(old_stub.left()),
2994 CompareICState::GetStateName(old_stub.right()), 3072 CompareICState::GetStateName(old_stub.right()),
2995 CompareICState::GetStateName(old_stub.state()), 3073 CompareICState::GetStateName(old_stub.state()),
2996 CompareICState::GetStateName(new_left), 3074 CompareICState::GetStateName(new_left),
2997 CompareICState::GetStateName(new_right), 3075 CompareICState::GetStateName(new_right),
2998 CompareICState::GetStateName(state), Token::Name(op_), 3076 CompareICState::GetStateName(state), Token::Name(op_),
2999 static_cast<void*>(*stub.GetCode())); 3077 static_cast<void*>(*stub.GetCode()));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
3237 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); 3315 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
3238 it.Next(); 3316 it.Next();
3239 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 3317 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
3240 Object::GetProperty(&it)); 3318 Object::GetProperty(&it));
3241 } 3319 }
3242 3320
3243 return *result; 3321 return *result;
3244 } 3322 }
3245 } // namespace internal 3323 } // namespace internal
3246 } // namespace v8 3324 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698