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

Side by Side Diff: src/runtime-profiler.cc

Issue 6594073: Enable optimizing JSFunctions that are in new-space.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 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 | Annotate | Revision Log
« src/heap.cc ('K') | « src/runtime-profiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "runtime-profiler.h" 30 #include "runtime-profiler.h"
31 31
32 #include "assembler.h" 32 #include "assembler.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "compilation-cache.h" 34 #include "compilation-cache.h"
35 #include "deoptimizer.h" 35 #include "deoptimizer.h"
36 #include "execution.h" 36 #include "execution.h"
37 #include "global-handles.h" 37 #include "global-handles.h"
38 #include "mark-compact.h"
38 #include "scopeinfo.h" 39 #include "scopeinfo.h"
39 #include "top.h" 40 #include "top.h"
40 41
41 namespace v8 { 42 namespace v8 {
42 namespace internal { 43 namespace internal {
43 44
44 45
45 class PendingListNode : public Malloced { 46 class PendingListNode : public Malloced {
46 public: 47 public:
47 explicit PendingListNode(JSFunction* function); 48 explicit PendingListNode(JSFunction* function);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 94
94 static int sampler_threshold = kSamplerThresholdInit; 95 static int sampler_threshold = kSamplerThresholdInit;
95 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 96 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
96 97
97 static int sampler_ticks_until_threshold_adjustment = 98 static int sampler_ticks_until_threshold_adjustment =
98 kSamplerTicksBetweenThresholdAdjustment; 99 kSamplerTicksBetweenThresholdAdjustment;
99 100
100 // The ratio of ticks spent in JS code in percent. 101 // The ratio of ticks spent in JS code in percent.
101 static Atomic32 js_ratio; 102 static Atomic32 js_ratio;
102 103
103 // The JSFunctions in the sampler window are not GC safe. Old-space
104 // pointers are not cleared during mark-sweep collection and therefore
105 // the window might contain stale pointers. The window is updated on
106 // scavenges and (parts of it) cleared on mark-sweep and
107 // mark-sweep-compact.
108 static Object* sampler_window[kSamplerWindowSize] = { NULL, }; 104 static Object* sampler_window[kSamplerWindowSize] = { NULL, };
109 static int sampler_window_position = 0; 105 static int sampler_window_position = 0;
110 static int sampler_window_weight[kSamplerWindowSize] = { 0, }; 106 static int sampler_window_weight[kSamplerWindowSize] = { 0, };
111 107
112 108
113 // Support for pending 'optimize soon' requests. 109 // Support for pending 'optimize soon' requests.
114 static PendingListNode* optimize_soon_list = NULL; 110 static PendingListNode* optimize_soon_list = NULL;
115 111
116 112
117 PendingListNode::PendingListNode(JSFunction* function) : next_(NULL) { 113 PendingListNode::PendingListNode(JSFunction* function) : next_(NULL) {
118 function_ = GlobalHandles::Create(function); 114 function_ = GlobalHandles::Create(function);
119 start_ = OS::Ticks(); 115 start_ = OS::Ticks();
120 GlobalHandles::MakeWeak(function_.location(), this, &WeakCallback); 116 GlobalHandles::MakeWeak(function_.location(), this, &WeakCallback);
121 } 117 }
122 118
123 119
124 void PendingListNode::Destroy() { 120 void PendingListNode::Destroy() {
125 if (!IsValid()) return; 121 if (!IsValid()) return;
126 GlobalHandles::Destroy(function_.location()); 122 GlobalHandles::Destroy(function_.location());
127 function_= Handle<Object>::null(); 123 function_= Handle<Object>::null();
128 } 124 }
129 125
130 126
131 void PendingListNode::WeakCallback(v8::Persistent<v8::Value>, void* data) { 127 void PendingListNode::WeakCallback(v8::Persistent<v8::Value>, void* data) {
132 reinterpret_cast<PendingListNode*>(data)->Destroy(); 128 reinterpret_cast<PendingListNode*>(data)->Destroy();
133 } 129 }
134 130
135 131
136 static bool IsOptimizable(JSFunction* function) { 132 static bool IsOptimizable(JSFunction* function) {
137 if (Heap::InNewSpace(function)) return false;
138 Code* code = function->code(); 133 Code* code = function->code();
139 return code->kind() == Code::FUNCTION && code->optimizable(); 134 return code->kind() == Code::FUNCTION && code->optimizable();
140 } 135 }
141 136
142 137
143 static void Optimize(JSFunction* function, bool eager, int delay) { 138 static void Optimize(JSFunction* function, bool eager, int delay) {
144 ASSERT(IsOptimizable(function)); 139 ASSERT(IsOptimizable(function));
145 if (FLAG_trace_opt) { 140 if (FLAG_trace_opt) {
146 PrintF("[marking (%s) ", eager ? "eagerly" : "lazily"); 141 PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
147 function->PrintName(); 142 function->PrintName();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 196
202 197
203 static void ClearSampleBuffer() { 198 static void ClearSampleBuffer() {
204 for (int i = 0; i < kSamplerWindowSize; i++) { 199 for (int i = 0; i < kSamplerWindowSize; i++) {
205 sampler_window[i] = NULL; 200 sampler_window[i] = NULL;
206 sampler_window_weight[i] = 0; 201 sampler_window_weight[i] = 0;
207 } 202 }
208 } 203 }
209 204
210 205
211 static void ClearSampleBufferNewSpaceEntries() {
212 for (int i = 0; i < kSamplerWindowSize; i++) {
213 if (Heap::InNewSpace(sampler_window[i])) {
214 sampler_window[i] = NULL;
215 sampler_window_weight[i] = 0;
216 }
217 }
218 }
219
220
221 static int LookupSample(JSFunction* function) { 206 static int LookupSample(JSFunction* function) {
222 int weight = 0; 207 int weight = 0;
223 for (int i = 0; i < kSamplerWindowSize; i++) { 208 for (int i = 0; i < kSamplerWindowSize; i++) {
224 Object* sample = sampler_window[i]; 209 Object* sample = sampler_window[i];
225 if (sample != NULL) { 210 if (sample != NULL) {
226 if (function == sample) { 211 if (function == sample) {
227 weight += sampler_window_weight[i]; 212 weight += sampler_window_weight[i];
228 } 213 }
229 } 214 }
230 } 215 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 // Record state sample. 350 // Record state sample.
366 SamplerState state = Top::IsInJSState() 351 SamplerState state = Top::IsInJSState()
367 ? IN_JS_STATE 352 ? IN_JS_STATE
368 : IN_NON_JS_STATE; 353 : IN_NON_JS_STATE;
369 UpdateStateRatio(state); 354 UpdateStateRatio(state);
370 StackGuard::RequestRuntimeProfilerTick(); 355 StackGuard::RequestRuntimeProfilerTick();
371 #endif 356 #endif
372 } 357 }
373 358
374 359
375 void RuntimeProfiler::MarkCompactPrologue(bool is_compacting) {
376 if (is_compacting) {
377 // Clear all samples before mark-sweep-compact because every
378 // function might move.
379 ClearSampleBuffer();
380 } else {
381 // Clear only new space entries on mark-sweep since none of the
382 // old-space functions will move.
383 ClearSampleBufferNewSpaceEntries();
384 }
385 }
386
387
388 bool IsEqual(void* first, void* second) {
389 return first == second;
390 }
391
392
393 void RuntimeProfiler::Setup() { 360 void RuntimeProfiler::Setup() {
394 ClearSampleBuffer(); 361 ClearSampleBuffer();
395 // If the ticker hasn't already started, make sure to do so to get 362 // If the ticker hasn't already started, make sure to do so to get
396 // the ticks for the runtime profiler. 363 // the ticks for the runtime profiler.
397 if (IsEnabled()) Logger::EnsureTickerStarted(); 364 if (IsEnabled()) Logger::EnsureTickerStarted();
398 } 365 }
399 366
400 367
401 void RuntimeProfiler::Reset() { 368 void RuntimeProfiler::Reset() {
402 sampler_threshold = kSamplerThresholdInit; 369 sampler_threshold = kSamplerThresholdInit;
403 sampler_ticks_until_threshold_adjustment = 370 sampler_ticks_until_threshold_adjustment =
404 kSamplerTicksBetweenThresholdAdjustment; 371 kSamplerTicksBetweenThresholdAdjustment;
405 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 372 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
406 } 373 }
407 374
408 375
409 void RuntimeProfiler::TearDown() { 376 void RuntimeProfiler::TearDown() {
410 // Nothing to do. 377 // Nothing to do.
411 } 378 }
412 379
413 380
414 Object** RuntimeProfiler::SamplerWindowAddress() {
415 return sampler_window;
416 }
417
418
419 int RuntimeProfiler::SamplerWindowSize() { 381 int RuntimeProfiler::SamplerWindowSize() {
420 return kSamplerWindowSize; 382 return kSamplerWindowSize;
421 } 383 }
422 384
423 385
386 // Update the pointers in the sampler window after a GC.
387 void RuntimeProfiler::UpdateSamplesAfterScavenge() {
388 for (int i = 0; i < kSamplerWindowSize; i++) {
389 Object* function = sampler_window[i];
390 if (function != NULL && Heap::InNewSpace(function)) {
391 MapWord map_word = HeapObject::cast(function)->map_word();
392 if (map_word.IsForwardingAddress()) {
393 sampler_window[i] = map_word.ToForwardingAddress();
394 } else {
395 sampler_window[i] = NULL;
396 }
397 }
398 }
399 }
400
401
402 void RuntimeProfiler::RemoveDeadSamples() {
403 for (int i = 0; i < kSamplerWindowSize; i++) {
404 Object* function = sampler_window[i];
405 if (function != NULL && !HeapObject::cast(function)->IsMarked()) {
406 sampler_window[i] = NULL;
407 }
408 }
409 }
410
411
412 void RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) {
413 for (int i = 0; i < kSamplerWindowSize; i++) {
414 visitor->VisitPointer(&sampler_window[i]);
415 }
416 }
417
418
424 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() { 419 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
425 #ifdef ENABLE_LOGGING_AND_PROFILING 420 #ifdef ENABLE_LOGGING_AND_PROFILING
426 static const int kNonJSTicksThreshold = 100; 421 static const int kNonJSTicksThreshold = 100;
427 // We suspend the runtime profiler thread when not running 422 // We suspend the runtime profiler thread when not running
428 // JavaScript. If the CPU profiler is active we must not do this 423 // JavaScript. If the CPU profiler is active we must not do this
429 // because it samples both JavaScript and C++ code. 424 // because it samples both JavaScript and C++ code.
430 if (RuntimeProfiler::IsEnabled() && 425 if (RuntimeProfiler::IsEnabled() &&
431 !CpuProfiler::is_profiling() && 426 !CpuProfiler::is_profiling() &&
432 !(FLAG_prof && FLAG_prof_auto)) { 427 !(FLAG_prof && FLAG_prof_auto)) {
433 if (Top::IsInJSState()) { 428 if (Top::IsInJSState()) {
434 non_js_ticks_ = 0; 429 non_js_ticks_ = 0;
435 } else { 430 } else {
436 if (non_js_ticks_ < kNonJSTicksThreshold) { 431 if (non_js_ticks_ < kNonJSTicksThreshold) {
437 ++non_js_ticks_; 432 ++non_js_ticks_;
438 } else { 433 } else {
439 if (Top::WaitForJSState()) return true; 434 if (Top::WaitForJSState()) return true;
440 } 435 }
441 } 436 }
442 } 437 }
443 #endif 438 #endif
444 return false; 439 return false;
445 } 440 }
446 441
447 442
448 } } // namespace v8::internal 443 } } // namespace v8::internal
OLDNEW
« src/heap.cc ('K') | « src/runtime-profiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698