log.cc revision 3ef787dbeca8a5fb1086949cda830dccee07bfbd
1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdarg.h> 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h" 3380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "code-stubs.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 35d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "global-handles.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "log.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "platform.h" 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h" 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sliding state window. Updates counters to keep track of the last 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// window of kBufferSize states. This is useful to track where we 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// spent our time. 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SlidingStateWindow { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit SlidingStateWindow(Isolate* isolate); 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~SlidingStateWindow(); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AddState(StateTag state); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 256; 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Counters* counters_; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int current_index_; 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_full_; 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte buffer_[kBufferSize]; 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IncrementStateCounter(StateTag state) { 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block counters_->state_counters(state)->Increment(); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void DecrementStateCounter(StateTag state) { 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block counters_->state_counters(state)->Decrement(); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Profiler samples pc and sp values for the main thread. 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Each sample is appended to a circular buffer. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An independent thread removes data and writes it to the log. 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This design minimizes the time spent in the sampler. 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Profiler: public Thread { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit Profiler(Isolate* isolate); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Engage(); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Disengage(); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Inserts collected profiling data into buffer. 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Insert(TickSample* sample) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (paused_) 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Succ(head_) == tail_) { 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow_ = true; 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[head_] = *sample; 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block head_ = Succ(head_); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_semaphore_->Signal(); // Tell we have an element. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Waits for a signal and removes profiling data. 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Remove(TickSample* sample) { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_semaphore_->Wait(); // Wait for an element. 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *sample = buffer_[tail_]; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool result = overflow_; 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tail_ = Succ(tail_); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow_ = false; 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Pause and Resume TickSample data collection. 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool paused() const { return paused_; } 11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void pause() { paused_ = true; } 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void resume() { paused_ = false; } 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the next index in the cyclic buffer. 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int Succ(int index) { return (index + 1) % kBufferSize; } 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate* isolate_; 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Cyclic buffer for communicating profiling samples 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // between the signal handler and the worker thread. 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 128; 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample buffer_[kBufferSize]; // Buffer storage. 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int head_; // Index to the buffer head. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int tail_; // Index to the buffer tail. 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool overflow_; // Tell whether a buffer overflow has occurred. 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Semaphore* buffer_semaphore_; // Sempahore used for buffer synchronization. 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Tells whether profiler is engaged, that is, processing thread is stated. 135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool engaged_; 136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether worker thread should continue running. 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool running_; 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether we are currently recording tick samples. 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool paused_; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StackTracer implementation 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 14844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid StackTracer::Trace(Isolate* isolate, TickSample* sample) { 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate->IsInitialized()); 15044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Avoid collecting traces while doing GC. 1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (sample->state == GC) return; 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15444f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Address js_entry_sp = 15544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::js_entry_sp(isolate->thread_local_top()); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (js_entry_sp == 0) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Not executing JS now. 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Address callback = isolate->external_callback(); 16244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (callback != NULL) { 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block sample->external_callback = callback; 16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block sample->has_external_callback = true; 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Sample potential return address value for frameless invocation of 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // stubs (we'll figure out later, if this value makes sense). 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block sample->tos = Memory::Address_at(sample->sp); 16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block sample->has_external_callback = false; 170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block SafeStackTraceFrameIterator it(isolate, 17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block sample->fp, sample->sp, 174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke sample->sp, js_entry_sp); 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int i = 0; 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!it.done() && i < TickSample::kMaxFramesCount) { 177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sample->stack[i++] = it.frame()->pc(); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Advance(); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sample->frames_count = i; 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Ticker used to provide ticks to the profiler and the sliding state 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// window. 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Ticker: public Sampler { 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 1908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Ticker(Isolate* isolate, int interval): 19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Sampler(isolate, interval), 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch window_(NULL), 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch profiler_(NULL) {} 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~Ticker() { if (IsActive()) Stop(); } 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch virtual void Tick(TickSample* sample) { 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (profiler_) profiler_->Insert(sample); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (window_) window_->AddState(sample->state); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetWindow(SlidingStateWindow* window) { 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block window_ = window; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsActive()) Start(); 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ClearWindow() { 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block window_ = NULL; 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!profiler_ && IsActive() && !RuntimeProfiler::IsEnabled()) Stop(); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetProfiler(Profiler* profiler) { 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(profiler_ == NULL); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = profiler; 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch IncreaseProfilingDepth(); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!FLAG_prof_lazy && !IsActive()) Start(); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ClearProfiler() { 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DecreaseProfilingDepth(); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = NULL; 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!window_ && IsActive() && !RuntimeProfiler::IsEnabled()) Stop(); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang protected: 2268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang virtual void DoSampleStack(TickSample* sample) { 22744f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackTracer::Trace(isolate(), sample); 2288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 2298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SlidingStateWindow* window_; 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Profiler* profiler_; 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SlidingStateWindow implementation. 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 23944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockSlidingStateWindow::SlidingStateWindow(Isolate* isolate) 24044f0eee88ff00398ff7f715fab053374d808c90dSteve Block : counters_(isolate->counters()), current_index_(0), is_full_(false) { 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kBufferSize; i++) { 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[i] = static_cast<byte>(OTHER); 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->logger()->ticker_->SetWindow(this); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSlidingStateWindow::~SlidingStateWindow() { 24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->ticker_->ClearWindow(); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SlidingStateWindow::AddState(StateTag state) { 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_full_) { 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DecrementStateCounter(static_cast<StateTag>(buffer_[current_index_])); 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (current_index_ == kBufferSize - 1) { 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_full_ = true; 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[current_index_] = static_cast<byte>(state); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IncrementStateCounter(state); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(kBufferSize)); 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_index_ = (current_index_ + 1) & (kBufferSize - 1); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Profiler implementation. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 26944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockProfiler::Profiler(Isolate* isolate) 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : Thread("v8:Profiler"), 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate_(isolate), 2729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block head_(0), 273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tail_(0), 274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block overflow_(false), 275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block buffer_semaphore_(OS::CreateSemaphore(0)), 276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block engaged_(false), 27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block running_(false), 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block paused_(false) { 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Engage() { 283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (engaged_) return; 284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block engaged_ = true; 285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // TODO(mnaganov): This is actually "Chromium" mode. Flags need to be revised. 287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // http://code.google.com/p/v8/issues/detail?id=487 288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!FLAG_prof_lazy) { 289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block OS::LogSharedLibraryAddresses(); 290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start thread processing the profiler buffer. 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running_ = true; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Start(); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register to get ticks. 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->ticker_->SetProfiler(this); 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->ProfilerBeginEvent(); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Disengage() { 304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!engaged_) return; 305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stop receiving ticks. 30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->ticker_->ClearProfiler(); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Terminate the worker thread by setting running_ to false, 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // inserting a fake element in the queue and then wait for 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the thread to terminate. 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running_ = false; 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample sample; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reset 'paused_' flag, otherwise semaphore may not be signalled. 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block resume(); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Insert(&sample); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Join(); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOG(ISOLATE, UncheckedStringEvent("profiler", "end")); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Run() { 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample sample; 3258defd9ff6930b4e24729971a61cf7469daf119beSteve Block bool overflow = Remove(&sample); 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (running_) { 3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LOG(isolate_, TickEvent(&sample, overflow)); 3288defd9ff6930b4e24729971a61cf7469daf119beSteve Block overflow = Remove(&sample); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Low-level profiling event structures. 334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstruct LowLevelCodeCreateStruct { 336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char kTag = 'C'; 337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t name_size; 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address code_address; 340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t code_size; 341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstruct LowLevelCodeMoveStruct { 345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char kTag = 'M'; 346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address from_address; 348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address to_address; 349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 350257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 351257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstruct LowLevelCodeDeleteStruct { 353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char kTag = 'D'; 354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address address; 356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstruct LowLevelSnapshotPositionStruct { 360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char kTag = 'P'; 361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Address address; 363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int32_t position; 364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic const char kCodeMovingGCTag = 'G'; 368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Logger class implementation. 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass Logger::NameMap { 375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NameMap() : impl_(&PointerEquals) {} 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ~NameMap() { 379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { 380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch DeleteArray(static_cast<const char*>(p->value)); 381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Insert(Address code_address, const char* name, int name_size) { 385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* entry = FindOrCreateEntry(code_address); 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (entry->value == NULL) { 387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch entry->value = CopyName(name, name_size); 388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* Lookup(Address code_address) { 392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* entry = FindEntry(code_address); 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; 394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Remove(Address code_address) { 397257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* entry = FindEntry(code_address); 3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (entry != NULL) { 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DeleteArray(static_cast<char*>(entry->value)); 4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RemoveEntry(entry); 4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Move(Address from, Address to) { 405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (from == to) return; 406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* from_entry = FindEntry(from); 407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(from_entry != NULL); 408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void* value = from_entry->value; 409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RemoveEntry(from_entry); 410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* to_entry = FindOrCreateEntry(to); 411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(to_entry->value == NULL); 412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch to_entry->value = value; 413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static bool PointerEquals(void* lhs, void* rhs) { 417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return lhs == rhs; 418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static char* CopyName(const char* name, int name_size) { 421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch char* result = NewArray<char>(name_size + 1); 422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (int i = 0; i < name_size; ++i) { 423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch char c = name[i]; 424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (c == '\0') c = ' '; 425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result[i] = c; 426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result[name_size] = '\0'; 428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return result; 429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* FindOrCreateEntry(Address code_address) { 432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return impl_.Lookup(code_address, ComputePointerHash(code_address), true); 433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap::Entry* FindEntry(Address code_address) { 436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return impl_.Lookup(code_address, ComputePointerHash(code_address), false); 437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 438257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void RemoveEntry(HashMap::Entry* entry) { 440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch impl_.Remove(entry->key, entry->hash); 441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 442257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HashMap impl_; 444257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch DISALLOW_COPY_AND_ASSIGN(NameMap); 446257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 448257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass Logger::NameBuffer { 450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NameBuffer() { Reset(); } 452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Reset() { 454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_pos_ = 0; 455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AppendString(String* str) { 458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (str == NULL) return; 459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (str->HasOnlyAsciiChars()) { 460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_); 461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length); 462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_pos_ += utf8_length; 463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int uc16_length = Min(str->length(), kUtf16BufferSize); 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch String::WriteToFlat(str, utf16_buffer, 0, uc16_length); 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int previous = unibrow::Utf16::kNoPreviousCharacter; 468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uc16 c = utf16_buffer[i]; 470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (c <= String::kMaxAsciiCharCodeU) { 471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_buffer_[utf8_pos_++] = static_cast<char>(c); 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int char_length = unibrow::Utf8::Length(c, previous); 474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (utf8_pos_ + char_length > kUtf8BufferSize) break; 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); 476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_pos_ += char_length; 477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch previous = c; 479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AppendBytes(const char* bytes, int size) { 483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch size = Min(size, kUtf8BufferSize - utf8_pos_); 484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch memcpy(utf8_buffer_ + utf8_pos_, bytes, size); 485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_pos_ += size; 486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AppendBytes(const char* bytes) { 489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch AppendBytes(bytes, StrLength(bytes)); 490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AppendByte(char c) { 493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (utf8_pos_ >= kUtf8BufferSize) return; 494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_buffer_[utf8_pos_++] = c; 495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void AppendInt(int n) { 498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); 499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int size = OS::SNPrintF(buffer, "%d", n); 500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { 501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch utf8_pos_ += size; 502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* get() { return utf8_buffer_; } 506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int size() const { return utf8_pos_; } 507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kUtf8BufferSize = 512; 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kUtf16BufferSize = 128; 511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int utf8_pos_; 513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch char utf8_buffer_[kUtf8BufferSize]; 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uc16 utf16_buffer[kUtf16BufferSize]; 515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 51844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockLogger::Logger() 51944f0eee88ff00398ff7f715fab053374d808c90dSteve Block : ticker_(NULL), 52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block profiler_(NULL), 52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block sliding_state_window_(NULL), 52244f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_events_(NULL), 52344f0eee88ff00398ff7f715fab053374d808c90dSteve Block logging_nesting_(0), 52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block cpu_profiler_nesting_(0), 52544f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_(new Log(this)), 526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_(new NameBuffer), 527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch address_to_name_map_(NULL), 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_initialized_(false), 52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block last_address_(NULL), 53044f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_sp_(NULL), 53144f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_function_(NULL), 53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_to_(NULL), 53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_code_(NULL) { 53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 53544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 53744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockLogger::~Logger() { 538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch delete address_to_name_map_; 539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch delete name_buffer_; 54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete log_; 54144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_EVENT(ignore1, name) name, 54544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_EVENT 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ProfilerBeginEvent() { 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::StringEvent(const char* name, const char* value) { 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_log) UncheckedStringEvent(name, value); 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::UncheckedStringEvent(const char* name, const char* value) { 56544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,\"%s\"\n", name, value); 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::IntEvent(const char* name, int value) { 5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (FLAG_log) UncheckedIntEvent(name, value); 5746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 5756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 577f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid Logger::IntPtrTEvent(const char* name, intptr_t value) { 578f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (FLAG_log) UncheckedIntPtrTEvent(name, value); 579f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 580f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 581f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 5826ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Logger::UncheckedIntEvent(const char* name, int value) { 58344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 58444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%d\n", name, value); 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { 59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 59244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 593f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value); 594f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch msg.WriteToLogFile(); 595f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 596f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 597f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HandleEvent(const char* name, Object** location) { 59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_handles) return; 60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,0x%" V8PRIxPTR "\n", name, location); 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ApiEvent is private so all the calls come from the Logger class. It is the 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// caller's responsibility to ensure that log is enabled and that 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FLAG_log_api is true. 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiEvent(const char* format, ...) { 61044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(log_->IsEnabled() && FLAG_log_api); 61144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_list ap; 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_start(ap, format); 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendVA(format, ap); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_end(ap); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiNamedSecurityCheck(Object* key) { 62144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key->IsString()) { 623589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,\"%s\"\n", *str); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (key->IsUndefined()) { 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,undefined\n"); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,['no-name']\n"); 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SharedLibraryEvent(const char* library_path, 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t start, 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t end) { 63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_prof) return; 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block library_path, 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start, 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SharedLibraryEvent(const wchar_t* library_path, 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t start, 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t end) { 65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_prof) return; 65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block library_path, 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start, 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end); 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::LogRegExpSource(Handle<JSRegExp> regexp) { 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Prints "/" + re.source + "/" + 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"") 66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> source = GetProperty(regexp, "source"); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!source->IsString()) { 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("no source"); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (regexp->TypeTag()) { 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case JSRegExp::ATOM: 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('a'); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('/'); 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(*Handle<String>::cast(source), false); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('/'); 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // global flag 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> global = GetProperty(regexp, "global"); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (global->IsTrue()) { 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('g'); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ignorecase flag 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase"); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ignorecase->IsTrue()) { 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('i'); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // multiline flag 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> multiline = GetProperty(regexp, "multiline"); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (multiline->IsTrue()) { 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('m'); 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { 70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_regexp) return; 70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("regexp-compile,"); 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogRegExpSource(regexp); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(in_cache ? ",hit\n" : ",miss\n"); 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::LogRuntime(Vector<const char> format, JSArray* args) { 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_runtime) return; 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < format.length(); i++) { 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char c = format[i]; 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == '%' && i <= format.length() - 2) { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT('0' <= format[i] && format[i] <= '9'); 7215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe = args->GetElement(format[i] - '0'); 7225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* obj; 7235913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe->ToObject(&obj)) { 7245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck msg.Append("<exception>"); 7255913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck continue; 7265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (format[i]) { 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 's': 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(String::cast(obj), false); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'S': 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(String::cast(obj), true); 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'r': 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj))); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'x': 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("0x%x", Smi::cast(obj)->value()); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'i': 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%i", Smi::cast(obj)->value()); 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(c); 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiIndexedSecurityCheck(uint32_t index) { 75744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,%u\n", index); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiNamedPropertyAccess(const char* tag, 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* name) { 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(name->IsString()); 76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = holder->class_name(); 768589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> class_name = 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 770589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> property_name = 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 77244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name); 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiIndexedPropertyAccess(const char* tag, 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t index) { 77844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = holder->class_name(); 780589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> class_name = 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index); 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiObjectAccess(const char* tag, JSObject* object) { 78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = object->class_name(); 788589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> class_name = 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 79044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ApiEvent("api,%s,\"%s\"\n", tag, *class_name); 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiEntryCall(const char* name) { 79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_api) return; 79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ApiEvent("api,%s\n", name); 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::NewEvent(const char* name, void* object, size_t size) { 80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log) return; 80244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object, 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static_cast<unsigned int>(size)); 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DeleteEvent(const char* name, void* object) { 81044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log) return; 81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Logger::NewEventStatic(const char* name, void* object, size_t size) { 81844f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->NewEvent(name, object, size); 81944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 82244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Logger::DeleteEventStatic(const char* name, void* object) { 82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->DeleteEvent(name, object); 82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 826d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::CallbackEventInternal(const char* prefix, const char* name, 827d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address entry_point) { 82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 82944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 830d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append("%s,%s,", 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CALLBACK_TAG]); 833d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.AppendAddress(entry_point); 834d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append(",1,\"%s%s\"", prefix, name); 835d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append('\n'); 836d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.WriteToLogFile(); 837d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 838d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 839d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 840d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::CallbackEvent(String* name, Address entry_point) { 84144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 842589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = 843d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 844d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("", *str, entry_point); 845d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 846d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 847d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 848d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::GetterCallbackEvent(String* name, Address entry_point) { 84944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 850589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = 851d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 852d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("get ", *str, entry_point); 853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 854d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 855d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 856d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::SetterCallbackEvent(String* name, Address entry_point) { 85744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 858589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = 859d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 860d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("set ", *str, entry_point); 861d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 862d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 863d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code, 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* comment) { 867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[tag]); 871257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(comment); 873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 875257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 88144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,%s,", 883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[tag]); 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 886e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.Append(",%d,\"", code->ExecutableSize()); 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (const char* p = comment; *p != '\0'; p++) { 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*p == '"') { 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\\'); 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(*p); 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code* code, 901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String* name) { 902257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 904257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 905257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[tag]); 906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendString(name); 908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LogMessageBuilder msg(this); 917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append("%s,%s,", 918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kLogEventsNames[tag]); 920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.AppendAddress(code->address()); 921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append(",%d,\"", code->ExecutableSize()); 922257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.AppendDetailed(name, false); 923257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append('"'); 924257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append('\n'); 925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.WriteToLogFile(); 926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 929e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// ComputeMarker must only be used when SharedFunctionInfo is known. 930e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic const char* ComputeMarker(Code* code) { 931e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch switch (code->kind()) { 932e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case Code::FUNCTION: return code->optimizable() ? "~" : ""; 933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case Code::OPTIMIZED_FUNCTION: return "*"; 934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch default: return ""; 935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 940e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code* code, 941e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SharedFunctionInfo* shared, 942e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String* name) { 943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[tag]); 947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(ComputeMarker(code)); 949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendString(name); 950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 95844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (code == Isolate::Current()->builtins()->builtin( 95944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLazyCompile)) 96044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 96244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 963589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,%s,", 966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[tag]); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); 970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.AppendAddress(shared->address()); 971e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.Append(",%s", ComputeMarker(code)); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Although, it is possible to extract source and line from 978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// the SharedFunctionInfo object, we left it to caller 979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// to leave logging functions free from heap allocations. 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code* code, 982e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SharedFunctionInfo* shared, 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* source, int line) { 984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[tag]); 988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(ComputeMarker(code)); 990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendString(shared->DebugName()); 991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(' '); 992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendString(source); 993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendInt(line); 995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 997257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 1000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 1001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 100344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1004589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> name = 1005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1006589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> sourcestr = 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,%s,", 1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 1010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[tag]); 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 1012e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.Append(",%d,\"%s %s:%d\",", 1013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->ExecutableSize(), 1014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *name, 1015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *sourcestr, 1016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch line); 1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.AppendAddress(shared->address()); 1018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch msg.Append(",%s", ComputeMarker(code)); 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { 1025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 1026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 1027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 1028257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[tag]); 1029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 1030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendInt(args_count); 1031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 1033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 1034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 1036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 1037257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 103944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,%s,", 1041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 1042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[tag]); 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count); 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1050f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid Logger::CodeMovingGCEvent() { 1051257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled() || !FLAG_ll_prof) return; 1052257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag)); 1053f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch OS::SignalCodeMovingGC(); 1054f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 1055f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1056f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::RegExpCodeCreateEvent(Code* code, String* source) { 1058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 1059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof || Serializer::enabled()) { 1060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->Reset(); 1061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]); 1062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendByte(':'); 1063257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch name_buffer_->AppendString(source); 1064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) { 1066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); 1067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled()) { 1069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); 1070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_code) return; 107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", 1074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[CODE_CREATION_EVENT], 1075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kLogEventsNames[REG_EXP_TAG]); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"", code->ExecutableSize()); 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(source, false); 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\"'); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeMoveEvent(Address from, Address to) { 1086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 1087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to); 1088257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled() && address_to_name_map_ != NULL) { 1089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch address_to_name_map_->Move(from, to); 1090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MoveEventInternal(CODE_MOVE_EVENT, from, to); 1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::CodeDeleteEvent(Address from) { 1096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 1097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from); 1098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled() && address_to_name_map_ != NULL) { 1099257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch address_to_name_map_->Remove(from); 1100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeleteEventInternal(CODE_DELETE_EVENT, from); 1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::SnapshotPositionEvent(Address addr, int pos) { 1106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled()) return; 1107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos); 1108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (Serializer::enabled() && address_to_name_map_ != NULL) { 1109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* code_name = address_to_name_map_->Lookup(addr); 1110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (code_name == NULL) return; // Not a code object. 1111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LogMessageBuilder msg(this); 1112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append("%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); 1113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (const char* p = code_name; *p != '\0'; ++p) { 1114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (*p == '"') msg.Append('\\'); 1115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append(*p); 1116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.Append("\"\n"); 1118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch msg.WriteToLogFile(); 1119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!FLAG_log_snapshot_positions) return; 112144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(addr); 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append(",%d", pos); 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append('\n'); 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.WriteToLogFile(); 1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 113044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { 113144f0eee88ff00398ff7f715fab053374d808c90dSteve Block MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::MoveEventInternal(LogEventsAndTags event, 1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Address from, 1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Address to) { 113844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 113944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,", kLogEventsNames[event]); 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(from); 1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append(','); 1143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.AppendAddress(to); 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1146eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::DeleteEventInternal(LogEventsAndTags event, Address from) { 115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_code) return; 115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,", kLogEventsNames[event]); 1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(from); 1154e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke msg.Append('\n'); 1155e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke msg.WriteToLogFile(); 1156eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 1157e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ResourceEvent(const char* name, const char* tag) { 116044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log) return; 116144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", name, tag); 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t sec, usec; 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (OS::GetUserTime(&sec, &usec) != -1) { 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%d,%d,", sec, usec); 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%.0f", OS::TimeCurrentMillis()); 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SuspectReadEvent(String* name, Object* obj) { 117644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_suspect) return; 117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name = obj->IsJSObject() 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ? JSObject::cast(obj)->class_name() 118044f0eee88ff00398ff7f715fab053374d808c90dSteve Block : HEAP->empty_string(); 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("suspect-read,"); 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(class_name); 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(name); 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleBeginEvent(const char* space, const char* kind) { 119344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_gc) return; 119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Using non-relative system time in order to be able to synchronize with 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // external memory profiling events (e.g. DOM memory size). 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space, kind, OS::TimeCurrentMillis()); 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleEndEvent(const char* space, const char* kind) { 120444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_gc) return; 120544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { 121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log_gc) return; 121344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 12163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 12173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DebugTag(const char* call_site_tag) { 122044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log) return; 122144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("debug-tag,%s\n", call_site_tag); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { 122844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_log) return; 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StringBuilder s(parameter.length() + 1); 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < parameter.length(); ++i) { 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block s.AddCharacter(static_cast<char>(parameter[i])); 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* parameter_string = s.Finalize(); 123444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("debug-queue-event,%s,%15.3f,%s\n", 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_type, 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::TimeCurrentMillis(), 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parameter_string); 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(parameter_string); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::TickEvent(TickSample* sample, bool overflow) { 124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled() || !FLAG_prof) return; 124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block LogMessageBuilder msg(this); 1247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.Append("%s,", kLogEventsNames[TICK_EVENT]); 1248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.AppendAddress(sample->pc); 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 1250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.AppendAddress(sample->sp); 125144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (sample->has_external_callback) { 125244f0eee88ff00398ff7f715fab053374d808c90dSteve Block msg.Append(",1,"); 125344f0eee88ff00398ff7f715fab053374d808c90dSteve Block msg.AppendAddress(sample->external_callback); 125444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 125544f0eee88ff00398ff7f715fab053374d808c90dSteve Block msg.Append(",0,"); 125644f0eee88ff00398ff7f715fab053374d808c90dSteve Block msg.AppendAddress(sample->tos); 125744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d", static_cast<int>(sample->state)); 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (overflow) { 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",overflow"); 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < sample->frames_count; ++i) { 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 1264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch msg.AppendAddress(sample->stack[i]); 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Logger::IsProfilerPaused() { 12723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return profiler_ == NULL || profiler_->paused(); 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Logger::PauseProfiler() { 127744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 12783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (profiler_ != NULL) { 1279402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // It is OK to have negative nesting. 1280402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (--cpu_profiler_nesting_ == 0) { 1281402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->pause(); 1282402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (FLAG_prof_lazy) { 1283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!FLAG_sliding_state_window && !RuntimeProfiler::IsEnabled()) { 1284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ticker_->Stop(); 1285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1286402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_code = false; 128744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOG(ISOLATE, UncheckedStringEvent("profiler", "pause")); 1288402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 12896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block --logging_nesting_; 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Logger::ResumeProfiler() { 129644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!log_->IsEnabled()) return; 12973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (profiler_ != NULL) { 1298402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (cpu_profiler_nesting_++ == 0) { 12996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ++logging_nesting_; 1300402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (FLAG_prof_lazy) { 1301402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->Engage(); 130244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOG(ISOLATE, UncheckedStringEvent("profiler", "resume")); 1303402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_code = true; 1304402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LogCompiledFunctions(); 1305402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LogAccessorCallbacks(); 1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!FLAG_sliding_state_window && !ticker_->IsActive()) { 1307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ticker_->Start(); 1308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1309402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 1310402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->resume(); 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function can be called when Log's mutex is acquired, 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// either from main or Profiler's thread. 131844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Logger::LogFailure() { 13193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PauseProfiler(); 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Logger::IsProfilerSamplerActive() { 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ticker_->IsActive(); 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor { 1329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 1330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis, 1331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code>* code_objects, 1332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* count) 1333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : sfis_(sfis), code_objects_(code_objects), count_(count) { } 1334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void EnterContext(Context* context) {} 1336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void LeaveContext(Context* context) {} 1337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void VisitFunction(JSFunction* function) { 13393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared()); 13403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* maybe_script = sfi->script(); 13413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (maybe_script->IsScript() 13423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch && !Script::cast(maybe_script)->HasValidSource()) return; 1343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (sfis_ != NULL) { 13443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch sfis_[*count_] = Handle<SharedFunctionInfo>(sfi); 1345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (code_objects_ != NULL) { 1347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); 1348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_objects_[*count_] = Handle<Code>(function->code()); 1349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *count_ = *count_ + 1; 1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<SharedFunctionInfo>* sfis_; 1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code>* code_objects_; 1356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* count_; 1357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 1358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis, 1361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code>* code_objects) { 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 13633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block AssertNoAllocation no_alloc; 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int compiled_funcs_count = 0; 1365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Iterate the heap to find shared function info objects and record 1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the unoptimized code for them. 1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!obj->IsSharedFunctionInfo()) continue; 13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); 13713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (sfi->is_compiled() 13723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block && (!sfi->script()->IsScript() 13733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block || Script::cast(sfi->script())->HasValidSource())) { 1374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (sfis != NULL) { 13753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); 1376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (code_objects != NULL) { 1378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_objects[compiled_funcs_count] = Handle<Code>(sfi->code()); 1379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 13803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ++compiled_funcs_count; 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 13823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Iterate all optimized functions in all contexts. 1385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EnumerateOptimizedFunctionsVisitor visitor(sfis, 1386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_objects, 1387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &compiled_funcs_count); 1388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Deoptimizer::VisitAllOptimizedFunctions(&visitor); 1389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return compiled_funcs_count; 13913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1394d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::LogCodeObject(Object* object) { 1395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (FLAG_log_code || FLAG_ll_prof) { 1396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Code* code_object = Code::cast(object); 1397d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block LogEventsAndTags tag = Logger::STUB_TAG; 1398d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* description = "Unknown code from the snapshot"; 1399d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block switch (code_object->kind()) { 1400d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::FUNCTION: 1401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Code::OPTIMIZED_FUNCTION: 1402d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; // We log this later using LogCompiledFunctions. 1403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Code::UNARY_OP_IC: // fall through 1404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Code::BINARY_OP_IC: // fall through 1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case Code::COMPARE_IC: // fall through 140669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case Code::TO_BOOLEAN_IC: // fall through 1407d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::STUB: 140880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen description = 140980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true); 14103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (description == NULL) 14113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu description = "A stub from the snapshot"; 1412d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::STUB_TAG; 1413d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1414d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::BUILTIN: 1415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A builtin from the snapshot"; 1416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::BUILTIN_TAG; 1417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::KEYED_LOAD_IC: 1419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A keyed load IC from the snapshot"; 1420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::KEYED_LOAD_IC_TAG; 1421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1422d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::LOAD_IC: 1423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A load IC from the snapshot"; 1424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::LOAD_IC_TAG; 1425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1426d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::STORE_IC: 1427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A store IC from the snapshot"; 1428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::STORE_IC_TAG; 1429d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::KEYED_STORE_IC: 1431d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A keyed store IC from the snapshot"; 1432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::KEYED_STORE_IC_TAG; 1433d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1434d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::CALL_IC: 1435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A call IC from the snapshot"; 1436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::CALL_IC_TAG; 1437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 14387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch case Code::KEYED_CALL_IC: 14397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch description = "A keyed call IC from the snapshot"; 14407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch tag = Logger::KEYED_CALL_IC_TAG; 14417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break; 1442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 144344f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description)); 1444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1448f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid Logger::LogCodeInfo() { 1449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!log_->IsEnabled() || !FLAG_ll_prof) return; 1450f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#if V8_TARGET_ARCH_IA32 1451f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char arch[] = "ia32"; 1452f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#elif V8_TARGET_ARCH_X64 1453f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char arch[] = "x64"; 1454f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#elif V8_TARGET_ARCH_ARM 1455f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char arch[] = "arm"; 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#elif V8_TARGET_ARCH_MIPS 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char arch[] = "mips"; 1458f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#else 1459f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char arch[] = "unknown"; 1460f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#endif 1461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteBytes(arch, sizeof(arch)); 1462f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 1463f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1464f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::RegisterSnapshotCodeName(Code* code, 1466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* name, 1467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int name_size) { 1468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(Serializer::enabled()); 1469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (address_to_name_map_ == NULL) { 1470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch address_to_name_map_ = new NameMap; 1471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch address_to_name_map_->Insert(code->address(), name, name_size); 1473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::LowLevelCodeCreateEvent(Code* code, 1477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* name, 1478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int name_size) { 1479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (log_->ll_output_handle_ == NULL) return; 1480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeCreateStruct event; 1481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.name_size = name_size; 1482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.code_address = code->instruction_start(); 1483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(event.code_address == code->address() + Code::kHeaderSize); 1484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.code_size = code->instruction_size(); 1485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteStruct(event); 1486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteBytes(name, name_size); 1487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteBytes( 1488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reinterpret_cast<const char*>(code->instruction_start()), 1489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->instruction_size()); 1490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::LowLevelCodeMoveEvent(Address from, Address to) { 1494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (log_->ll_output_handle_ == NULL) return; 1495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeMoveStruct event; 1496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.from_address = from + Code::kHeaderSize; 1497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.to_address = to + Code::kHeaderSize; 1498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteStruct(event); 1499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::LowLevelCodeDeleteEvent(Address from) { 1503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (log_->ll_output_handle_ == NULL) return; 1504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelCodeDeleteStruct event; 1505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.address = from + Code::kHeaderSize; 1506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteStruct(event); 1507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) { 1511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (log_->ll_output_handle_ == NULL) return; 1512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelSnapshotPositionStruct event; 1513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.address = addr + Code::kHeaderSize; 1514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch event.position = pos; 1515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LowLevelLogWriteStruct(event); 1516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Logger::LowLevelLogWriteBytes(const char* bytes, int size) { 1520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_); 1521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(static_cast<size_t>(size) == rv); 15225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck USE(rv); 1523f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 1524f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1525f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 15263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Logger::LogCodeObjects() { 15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "Logger::LogCodeObjects"); 152985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch HeapIterator iterator; 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AssertNoAllocation no_alloc; 15313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 15323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (obj->IsCode()) LogCodeObject(obj); 15333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 15343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 15353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 15363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, 1538589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<Code> code) { 1539589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<String> func_name(shared->DebugName()); 1540589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (shared->script()->IsScript()) { 1541589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<Script> script(Script::cast(shared->script())); 1542589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (script->name()->IsString()) { 1543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<String> script_name(String::cast(script->name())); 1544589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int line_num = GetScriptLineNumber(script, shared->start_position()); 1545589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (line_num > 0) { 1546589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PROFILE(ISOLATE, 1547589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CodeCreateEvent( 1548589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), 1549589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *code, *shared, 1550589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *script_name, line_num + 1)); 1551589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 1552589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Can't distinguish eval and script here, so always use Script. 1553589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PROFILE(ISOLATE, 1554589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CodeCreateEvent( 1555589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 1556589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *code, *shared, *script_name)); 1557589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1558589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 1559589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PROFILE(ISOLATE, 1560589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CodeCreateEvent( 1561589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), 1562589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *code, *shared, *func_name)); 1563589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1564589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else if (shared->IsApiFunction()) { 1565589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // API function. 1566589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch FunctionTemplateInfo* fun_data = shared->get_api_func_data(); 1567589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Object* raw_call_data = fun_data->call_code(); 1568589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!raw_call_data->IsUndefined()) { 1569589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 1570589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Object* callback_obj = call_data->callback(); 1571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Address entry_point = v8::ToCData<Address>(callback_obj); 1572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point)); 1573589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1574589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 1575589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PROFILE(ISOLATE, 1576589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CodeCreateEvent( 1577589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name)); 1578589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1579589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 1580589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1581589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 15823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Logger::LogCompiledFunctions() { 15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, 15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "Logger::LogCompiledFunctions"); 15853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope scope; 1586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); 158725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); 1588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); 1589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EnumerateCompiledFunctions(sfis.start(), code_objects.start()); 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // During iteration, there can be heap allocation due to 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetScriptLineNumber call. 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < compiled_funcs_count; ++i) { 159444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (*code_objects[i] == Isolate::Current()->builtins()->builtin( 159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLazyCompile)) 159644f0eee88ff00398ff7f715fab053374d808c90dSteve Block continue; 1597589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LogExistingFunction(sfis[i], code_objects[i]); 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1601d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1602d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::LogAccessorCallbacks() { 16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, 16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "Logger::LogAccessorCallbacks"); 160585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch HeapIterator iterator; 16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AssertNoAllocation no_alloc; 1607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 1608d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!obj->IsAccessorInfo()) continue; 1609d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block AccessorInfo* ai = AccessorInfo::cast(obj); 1610d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!ai->name()->IsString()) continue; 1611d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block String* name = String::cast(ai->name()); 1612d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address getter_entry = v8::ToCData<Address>(ai->getter()); 1613d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (getter_entry != 0) { 16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(ISOLATE, GetterCallbackEvent(name, getter_entry)); 1615d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1616d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address setter_entry = v8::ToCData<Address>(ai->setter()); 1617d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (setter_entry != 0) { 16183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(ISOLATE, SetterCallbackEvent(name, setter_entry)); 1619d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1620d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1621d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1622d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Logger::SetUp() { 162544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Tests and EnsureInitialize() can call this twice in a row. It's harmless. 162644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_initialized_) return true; 162744f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_initialized_ = true; 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1629f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // --ll-prof implies --log-code and --log-snapshot-positions. 1630f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (FLAG_ll_prof) { 1631f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch FLAG_log_snapshot_positions = true; 1632f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1633f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --prof_lazy controls --log-code, implies --noprof_auto. 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_prof_lazy) { 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_code = false; 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_prof_auto = false; 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): this assert introduces cyclic dependency (logger 164144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // -> thread local top -> heap -> logger). 164244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // ASSERT(VMState::is_outermost_external()); 164344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 164444f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_->Initialize(); 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1646f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (FLAG_ll_prof) LogCodeInfo(); 1647f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 164844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 16493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ticker_ = new Ticker(isolate, kSamplingIntervalMs); 16503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { 165244f0eee88ff00398ff7f715fab053374d808c90dSteve Block sliding_state_window_ = new SlidingStateWindow(isolate); 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api 165644f0eee88ff00398ff7f715fab053374d808c90dSteve Block || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect 1657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof; 165844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (start_logging) { 16606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block logging_nesting_ = 1; 16616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_prof) { 166444f0eee88ff00398ff7f715fab053374d808c90dSteve Block profiler_ = new Profiler(isolate); 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!FLAG_prof_auto) { 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_->pause(); 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 16686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block logging_nesting_ = 1; 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1670d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!FLAG_prof_lazy) { 1671d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block profiler_->Engage(); 1672d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockSampler* Logger::sampler() { 168044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ticker_; 168144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 168244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 168344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Logger::EnsureTickerStarted() { 1685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(ticker_ != NULL); 1686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!ticker_->IsActive()) ticker_->Start(); 1687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Logger::EnsureTickerStopped() { 1691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (ticker_ != NULL && ticker_->IsActive()) ticker_->Stop(); 1692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 16953fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochFILE* Logger::TearDown() { 16963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!is_initialized_) return NULL; 169744f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_initialized_ = false; 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stop the profiler before closing the file. 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (profiler_ != NULL) { 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_->Disengage(); 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete profiler_; 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = NULL; 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete sliding_state_window_; 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sliding_state_window_ = NULL; 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete ticker_; 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ticker_ = NULL; 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return log_->Close(); 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::EnableSlidingStateWindow() { 17173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the ticker is NULL, Logger::SetUp has not been called yet. In 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that case, we set the sliding_state_window flag so that the 17193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // sliding window computation will be started when Logger::SetUp is 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // called. 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ticker_ == NULL) { 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_sliding_state_window = true; 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Otherwise, if the sliding state window computation has not been 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // started we do it now. 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (sliding_state_window_ == NULL) { 172844f0eee88ff00398ff7f715fab053374d808c90dSteve Block sliding_state_window_ = new SlidingStateWindow(Isolate::Current()); 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Protects the state below. 17333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic LazyMutex active_samplers_mutex = LAZY_MUTEX_INITIALIZER; 173444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 173544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockList<Sampler*>* SamplerRegistry::active_samplers_ = NULL; 173644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 173744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 173844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void* param) { 17393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ScopedLock lock(active_samplers_mutex.Pointer()); 174044f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; 174144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ActiveSamplersExist() && i < active_samplers_->length(); 174244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ++i) { 174344f0eee88ff00398ff7f715fab053374d808c90dSteve Block func(active_samplers_->at(i), param); 174444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 174544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ActiveSamplersExist(); 174644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 174744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 174844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 174944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void ComputeCpuProfiling(Sampler* sampler, void* flag_ptr) { 175044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool* flag = reinterpret_cast<bool*>(flag_ptr); 175144f0eee88ff00398ff7f715fab053374d808c90dSteve Block *flag |= sampler->IsProfiling(); 175244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 175344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 175444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 175544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockSamplerRegistry::State SamplerRegistry::GetState() { 175644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool flag = false; 175744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!IterateActiveSamplers(&ComputeCpuProfiling, &flag)) { 175844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return HAS_NO_SAMPLERS; 175944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 176044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return flag ? HAS_CPU_PROFILING_SAMPLERS : HAS_SAMPLERS; 176144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 176244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 176344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 176444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid SamplerRegistry::AddActiveSampler(Sampler* sampler) { 176544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(sampler->IsActive()); 17663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ScopedLock lock(active_samplers_mutex.Pointer()); 176744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (active_samplers_ == NULL) { 176844f0eee88ff00398ff7f715fab053374d808c90dSteve Block active_samplers_ = new List<Sampler*>; 176944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 177044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!active_samplers_->Contains(sampler)); 177144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 177244f0eee88ff00398ff7f715fab053374d808c90dSteve Block active_samplers_->Add(sampler); 177344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 177444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 177544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 177644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { 177744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(sampler->IsActive()); 17783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ScopedLock lock(active_samplers_mutex.Pointer()); 177944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(active_samplers_ != NULL); 178044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool removed = active_samplers_->RemoveElement(sampler); 178144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(removed); 178244f0eee88ff00398ff7f715fab053374d808c90dSteve Block USE(removed); 178344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 178444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1786