| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 static const int kMaxSizeEarlyOpt = | 73 static const int kMaxSizeEarlyOpt = |
| 74 5 * FullCodeGenerator::kCodeSizeMultiplier; | 74 5 * FullCodeGenerator::kCodeSizeMultiplier; |
| 75 | 75 |
| 76 | 76 |
| 77 RuntimeProfiler::RuntimeProfiler(Isolate* isolate) | 77 RuntimeProfiler::RuntimeProfiler(Isolate* isolate) |
| 78 : isolate_(isolate), | 78 : isolate_(isolate), |
| 79 any_ic_changed_(false) { | 79 any_ic_changed_(false) { |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 static void GetICCounts(Code* shared_code, | |
| 84 int* ic_with_type_info_count, | |
| 85 int* ic_total_count, | |
| 86 int* percentage) { | |
| 87 *ic_total_count = 0; | |
| 88 *ic_with_type_info_count = 0; | |
| 89 Object* raw_info = shared_code->type_feedback_info(); | |
| 90 if (raw_info->IsTypeFeedbackInfo()) { | |
| 91 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); | |
| 92 *ic_with_type_info_count = info->ic_with_type_info_count(); | |
| 93 *ic_total_count = info->ic_total_count(); | |
| 94 } | |
| 95 *percentage = *ic_total_count > 0 | |
| 96 ? 100 * *ic_with_type_info_count / *ic_total_count | |
| 97 : 100; | |
| 98 } | |
| 99 | |
| 100 | |
| 101 void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) { | |
| 102 ASSERT(function->IsOptimizable()); | |
| 103 | |
| 104 if (FLAG_trace_opt && function->PassesFilter(FLAG_hydrogen_filter)) { | |
| 105 PrintF("[marking "); | |
| 106 function->ShortPrint(); | |
| 107 PrintF(" for recompilation, reason: %s", reason); | |
| 108 if (FLAG_type_info_threshold > 0) { | |
| 109 int typeinfo, total, percentage; | |
| 110 GetICCounts(function->shared()->code(), &typeinfo, &total, &percentage); | |
| 111 PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, percentage); | |
| 112 } | |
| 113 PrintF("]\n"); | |
| 114 } | |
| 115 | |
| 116 | |
| 117 if (isolate_->concurrent_recompilation_enabled() && | |
| 118 !isolate_->bootstrapper()->IsActive()) { | |
| 119 if (isolate_->concurrent_osr_enabled() && | |
| 120 isolate_->optimizing_compiler_thread()->IsQueuedForOSR(function)) { | |
| 121 // Do not attempt regular recompilation if we already queued this for OSR. | |
| 122 // TODO(yangguo): This is necessary so that we don't install optimized | |
| 123 // code on a function that is already optimized, since OSR and regular | |
| 124 // recompilation race. This goes away as soon as OSR becomes one-shot. | |
| 125 return; | |
| 126 } | |
| 127 ASSERT(!function->IsInOptimizationQueue()); | |
| 128 function->MarkForConcurrentOptimization(); | |
| 129 } else { | |
| 130 // The next call to the function will trigger optimization. | |
| 131 function->MarkForOptimization(); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 | |
| 136 void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) { | 83 void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) { |
| 137 // See AlwaysFullCompiler (in compiler.cc) comment on why we need | 84 // See AlwaysFullCompiler (in compiler.cc) comment on why we need |
| 138 // Debug::has_break_points(). | 85 // Debug::has_break_points(). |
| 139 if (!FLAG_use_osr || | 86 if (!FLAG_use_osr || |
| 140 isolate_->DebuggerHasBreakPoints() || | 87 isolate_->DebuggerHasBreakPoints() || |
| 141 function->IsBuiltin()) { | 88 function->IsBuiltin()) { |
| 142 return; | 89 return; |
| 143 } | 90 } |
| 144 | 91 |
| 145 SharedFunctionInfo* shared = function->shared(); | 92 SharedFunctionInfo* shared = function->shared(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 } | 189 } |
| 243 } | 190 } |
| 244 continue; | 191 continue; |
| 245 } | 192 } |
| 246 if (!function->IsOptimizable()) continue; | 193 if (!function->IsOptimizable()) continue; |
| 247 | 194 |
| 248 int ticks = shared_code->profiler_ticks(); | 195 int ticks = shared_code->profiler_ticks(); |
| 249 | 196 |
| 250 if (ticks >= kProfilerTicksBeforeOptimization) { | 197 if (ticks >= kProfilerTicksBeforeOptimization) { |
| 251 int typeinfo, total, percentage; | 198 int typeinfo, total, percentage; |
| 252 GetICCounts(shared_code, &typeinfo, &total, &percentage); | 199 shared_code->GetICCounts(&typeinfo, &total, &percentage); |
| 253 if (percentage >= FLAG_type_info_threshold) { | 200 if (percentage >= FLAG_type_info_threshold) { |
| 254 // If this particular function hasn't had any ICs patched for enough | 201 // If this particular function hasn't had any ICs patched for enough |
| 255 // ticks, optimize it now. | 202 // ticks, optimize it now. |
| 256 Optimize(function, "hot and stable"); | 203 function->Optimize("hot and stable"); |
| 257 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { | 204 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { |
| 258 Optimize(function, "not much type info but very hot"); | 205 function->Optimize("not much type info but very hot"); |
| 259 } else { | 206 } else { |
| 260 shared_code->set_profiler_ticks(ticks + 1); | 207 shared_code->set_profiler_ticks(ticks + 1); |
| 261 if (FLAG_trace_opt_verbose) { | 208 if (FLAG_trace_opt_verbose) { |
| 262 PrintF("[not yet optimizing "); | 209 PrintF("[not yet optimizing "); |
| 263 function->PrintName(); | 210 function->PrintName(); |
| 264 PrintF(", not enough type info: %d/%d (%d%%)]\n", | 211 PrintF(", not enough type info: %d/%d (%d%%)]\n", |
| 265 typeinfo, total, percentage); | 212 typeinfo, total, percentage); |
| 266 } | 213 } |
| 267 } | 214 } |
| 268 } else if (!any_ic_changed_ && | 215 } else if (!any_ic_changed_ && |
| 269 shared_code->instruction_size() < kMaxSizeEarlyOpt) { | 216 shared_code->instruction_size() < kMaxSizeEarlyOpt) { |
| 270 // If no IC was patched since the last tick and this function is very | 217 // If no IC was patched since the last tick and this function is very |
| 271 // small, optimistically optimize it now. | 218 // small, optimistically optimize it now. |
| 272 Optimize(function, "small function"); | 219 function->Optimize("small function"); |
| 273 } else { | 220 } else { |
| 274 shared_code->set_profiler_ticks(ticks + 1); | 221 shared_code->set_profiler_ticks(ticks + 1); |
| 275 } | 222 } |
| 276 } | 223 } |
| 277 any_ic_changed_ = false; | 224 any_ic_changed_ = false; |
| 278 } | 225 } |
| 279 | 226 |
| 280 | 227 |
| 281 } } // namespace v8::internal | 228 } } // namespace v8::internal |
| OLD | NEW |