log.cc revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 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" 33d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "global-handles.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "log.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sliding state window. Updates counters to keep track of the last 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// window of kBufferSize states. This is useful to track where we 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// spent our time. 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SlidingStateWindow { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SlidingStateWindow(); 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~SlidingStateWindow(); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AddState(StateTag state); 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 256; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int current_index_; 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_full_; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte buffer_[kBufferSize]; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IncrementStateCounter(StateTag state) { 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::state_counters[state].Increment(); 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void DecrementStateCounter(StateTag state) { 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counters::state_counters[state].Decrement(); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Profiler samples pc and sp values for the main thread. 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Each sample is appended to a circular buffer. 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An independent thread removes data and writes it to the log. 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This design minimizes the time spent in the sampler. 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Profiler: public Thread { 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Profiler(); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Engage(); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Disengage(); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Inserts collected profiling data into buffer. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Insert(TickSample* sample) { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (paused_) 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Succ(head_) == tail_) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow_ = true; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[head_] = *sample; 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block head_ = Succ(head_); 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_semaphore_->Signal(); // Tell we have an element. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Waits for a signal and removes profiling data. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Remove(TickSample* sample) { 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_semaphore_->Wait(); // Wait for an element. 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *sample = buffer_[tail_]; 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool result = overflow_; 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tail_ = Succ(tail_); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow_ = false; 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Pause and Resume TickSample data collection. 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool paused() { return paused_; } 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void pause() { paused_ = true; } 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void resume() { paused_ = false; } 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the next index in the cyclic buffer. 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int Succ(int index) { return (index + 1) % kBufferSize; } 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Cyclic buffer for communicating profiling samples 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // between the signal handler and the worker thread. 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 128; 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample buffer_[kBufferSize]; // Buffer storage. 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int head_; // Index to the buffer head. 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int tail_; // Index to the buffer tail. 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool overflow_; // Tell whether a buffer overflow has occurred. 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Semaphore* buffer_semaphore_; // Sempahore used for buffer synchronization. 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Tells whether profiler is engaged, that is, processing thread is stated. 130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool engaged_; 131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether worker thread should continue running. 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool running_; 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether we are currently recording tick samples. 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool paused_; 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Profiler::paused_ = false; 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StackTracer implementation 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackTracer::Trace(TickSample* sample) { 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block sample->function = NULL; 1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block sample->frames_count = 0; 1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (sample->state == GC) return; 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Address js_entry_sp = Top::js_entry_sp(Top::GetCurrentThread()); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (js_entry_sp == 0) { 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Not executing JS now. 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const Address functionAddr = 158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke sample->fp + JavaScriptFrameConstants::kFunctionOffset; 159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (SafeStackFrameIterator::IsWithinBounds(sample->sp, js_entry_sp, 160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke functionAddr)) { 161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke sample->function = Memory::Address_at(functionAddr) - kHeapObjectTag; 162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int i = 0; 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const Address callback = VMState::external_callback(); 166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (callback != NULL) { 167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block sample->stack[i++] = callback; 168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 169d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SafeStackTraceFrameIterator it(sample->fp, sample->sp, 171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke sample->sp, js_entry_sp); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!it.done() && i < TickSample::kMaxFramesCount) { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sample->stack[i++] = it.frame()->pc(); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Advance(); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sample->frames_count = i; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Ticker used to provide ticks to the profiler and the sliding state 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// window. 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Ticker: public Sampler { 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit Ticker(int interval): 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Sampler(interval, FLAG_prof), window_(NULL), profiler_(NULL) {} 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~Ticker() { if (IsActive()) Stop(); } 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SampleStack(TickSample* sample) { 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackTracer::Trace(sample); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Tick(TickSample* sample) { 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (profiler_) profiler_->Insert(sample); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (window_) window_->AddState(sample->state); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetWindow(SlidingStateWindow* window) { 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block window_ = window; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsActive()) Start(); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ClearWindow() { 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block window_ = NULL; 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!profiler_ && IsActive()) Stop(); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetProfiler(Profiler* profiler) { 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = profiler; 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!FLAG_prof_lazy && !IsActive()) Start(); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ClearProfiler() { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = NULL; 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!window_ && IsActive()) Stop(); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SlidingStateWindow* window_; 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Profiler* profiler_; 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SlidingStateWindow implementation. 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) { 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kBufferSize; i++) { 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[i] = static_cast<byte>(OTHER); 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ticker_->SetWindow(this); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSlidingStateWindow::~SlidingStateWindow() { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ticker_->ClearWindow(); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SlidingStateWindow::AddState(StateTag state) { 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_full_) { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DecrementStateCounter(static_cast<StateTag>(buffer_[current_index_])); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (current_index_ == kBufferSize - 1) { 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_full_ = true; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[current_index_] = static_cast<byte>(state); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IncrementStateCounter(state); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(kBufferSize)); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_index_ = (current_index_ + 1) & (kBufferSize - 1); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Profiler implementation. 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 258d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockProfiler::Profiler() 259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block : head_(0), 260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tail_(0), 261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block overflow_(false), 262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block buffer_semaphore_(OS::CreateSemaphore(0)), 263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block engaged_(false), 264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block running_(false) { 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Engage() { 269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (engaged_) return; 270d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block engaged_ = true; 271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // TODO(mnaganov): This is actually "Chromium" mode. Flags need to be revised. 273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // http://code.google.com/p/v8/issues/detail?id=487 274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!FLAG_prof_lazy) { 275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block OS::LogSharedLibraryAddresses(); 276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start thread processing the profiler buffer. 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running_ = true; 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Start(); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register to get ticks. 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ticker_->SetProfiler(this); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ProfilerBeginEvent(); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::LogAliases(); 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Disengage() { 291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!engaged_) return; 292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stop receiving ticks. 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ticker_->ClearProfiler(); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Terminate the worker thread by setting running_ to false, 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // inserting a fake element in the queue and then wait for 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the thread to terminate. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running_ = false; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample sample; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reset 'paused_' flag, otherwise semaphore may not be signalled. 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block resume(); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Insert(&sample); 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Join(); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LOG(UncheckedStringEvent("profiler", "end")); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Profiler::Run() { 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TickSample sample; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool overflow = Logger::profiler_->Remove(&sample); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (running_) { 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LOG(TickEvent(&sample, overflow)); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block overflow = Logger::profiler_->Remove(&sample); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Logger class implementation. 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTicker* Logger::ticker_ = NULL; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockProfiler* Logger::profiler_ = NULL; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSlidingStateWindow* Logger::sliding_state_window_ = NULL; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char** Logger::log_events_ = NULL; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCompressionHelper* Logger::compression_helper_ = NULL; 3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint Logger::logging_nesting_ = 0; 329402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuint Logger::cpu_profiler_nesting_ = 0; 330402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuint Logger::heap_profiler_nesting_ = 0; 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name, 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT) 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_LONG_EVENT 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name, 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LOG_EVENTS_AND_TAGS_LIST(DECLARE_SHORT_EVENT) 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_SHORT_EVENT 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ProfilerBeginEvent() { 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled()) return; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("profiler,\"compression\",%d\n", kCompressionWindowSize); 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::LogAliases() { 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_compress_log) return; 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < NUMBER_OF_LOG_EVENTS; ++i) { 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("alias,%s,%s\n", 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kCompressedLogEventsNames[i], kLongLogEventsNames[i]); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_LOGGING_AND_PROFILING 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::StringEvent(const char* name, const char* value) { 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_log) UncheckedStringEvent(name, value); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::UncheckedStringEvent(const char* name, const char* value) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled()) return; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,\"%s\"\n", name, value); 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::IntEvent(const char* name, int value) { 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (FLAG_log) UncheckedIntEvent(name, value); 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Logger::UncheckedIntEvent(const char* name, int value) { 3956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!Log::IsEnabled()) return; 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%d\n", name, value); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HandleEvent(const char* name, Object** location) { 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_handles) return; 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,0x%" V8PRIxPTR "\n", name, location); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ApiEvent is private so all the calls come from the Logger class. It is the 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// caller's responsibility to ensure that log is enabled and that 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FLAG_log_api is true. 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiEvent(const char* format, ...) { 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Log::IsEnabled() && FLAG_log_api); 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_list ap; 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_start(ap, format); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendVA(format, ap); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_end(ap); 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiNamedSecurityCheck(Object* key) { 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key->IsString()) { 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> str = 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,\"%s\"\n", *str); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (key->IsUndefined()) { 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,undefined\n"); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,['no-name']\n"); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SharedLibraryEvent(const char* library_path, 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t start, 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t end) { 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_prof) return; 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block library_path, 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start, 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SharedLibraryEvent(const wchar_t* library_path, 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t start, 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t end) { 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_prof) return; 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block library_path, 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start, 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::LogRegExpSource(Handle<JSRegExp> regexp) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Prints "/" + re.source + "/" + 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"") 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> source = GetProperty(regexp, "source"); 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!source->IsString()) { 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("no source"); 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (regexp->TypeTag()) { 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case JSRegExp::ATOM: 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('a'); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('/'); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(*Handle<String>::cast(source), false); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('/'); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // global flag 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> global = GetProperty(regexp, "global"); 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (global->IsTrue()) { 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('g'); 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ignorecase flag 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase"); 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ignorecase->IsTrue()) { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('i'); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // multiline flag 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> multiline = GetProperty(regexp, "multiline"); 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (multiline->IsTrue()) { 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('m'); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_LOGGING_AND_PROFILING 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_regexp) return; 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("regexp-compile,"); 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogRegExpSource(regexp); 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(in_cache ? ",hit\n" : ",miss\n"); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::LogRuntime(Vector<const char> format, JSArray* args) { 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_runtime) return; 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < format.length(); i++) { 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char c = format[i]; 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == '%' && i <= format.length() - 2) { 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT('0' <= format[i] && format[i] <= '9'); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* obj = args->GetElement(format[i] - '0'); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (format[i]) { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 's': 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(String::cast(obj), false); 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'S': 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(String::cast(obj), true); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'r': 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj))); 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'x': 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("0x%x", Smi::cast(obj)->value()); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'i': 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%i", Smi::cast(obj)->value()); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(c); 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiIndexedSecurityCheck(uint32_t index) { 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ApiEvent("api,check-security,%u\n", index); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiNamedPropertyAccess(const char* tag, 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* name) { 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(name->IsString()); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = holder->class_name(); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> class_name = 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> property_name = 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiIndexedPropertyAccess(const char* tag, 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t index) { 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = holder->class_name(); 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> class_name = 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiObjectAccess(const char* tag, JSObject* object) { 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name_obj = object->class_name(); 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> class_name = 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ApiEvent("api,%s,\"%s\"\n", tag, *class_name); 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ApiEntryCall(const char* name) { 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_api) return; 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::ApiEvent("api,%s\n", name); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::NewEvent(const char* name, void* object, size_t size) { 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log) return; 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object, 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static_cast<unsigned int>(size)); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DeleteEvent(const char* name, void* object) { 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log) return; 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A class that contains all common code dealing with record compression. 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompressionHelper { 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit CompressionHelper(int window_size) 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : compressor_(window_size), repeat_count_(0) { } 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Handles storing message in compressor, retrieving the previous one and 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prefixing it with repeat count, if needed. 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns true if message needs to be written to log. 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool HandleMessage(LogMessageBuilder* msg) { 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!msg->StoreInCompressor(&compressor_)) { 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Current message repeats the previous one, don't write it. 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++repeat_count_; 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (repeat_count_ == 0) { 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return msg->RetrieveCompressedPrevious(&compressor_); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(prefix_, "%s,%d,", 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Logger::log_events_[Logger::REPEAT_META_EVENT], 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block repeat_count_ + 1); 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block repeat_count_ = 0; 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return msg->RetrieveCompressedPrevious(&compressor_, prefix_.start()); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogRecordCompressor compressor_; 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int repeat_count_; 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, 20> prefix_; 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_LOGGING_AND_PROFILING 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 683d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 684d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::CallbackEventInternal(const char* prefix, const char* name, 685d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address entry_point) { 686d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 687d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block LogMessageBuilder msg; 688d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append("%s,%s,", 689d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]); 690d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.AppendAddress(entry_point); 691d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append(",1,\"%s%s\"", prefix, name); 692d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (FLAG_compress_log) { 693d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(compression_helper_ != NULL); 694d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!compression_helper_->HandleMessage(&msg)) return; 695d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 696d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.Append('\n'); 697d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block msg.WriteToLogFile(); 698d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 699d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 700d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 701d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 702d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::CallbackEvent(String* name, Address entry_point) { 703d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 704d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 705d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SmartPointer<char> str = 706d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 707d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("", *str, entry_point); 708d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 709d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 710d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 711d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 712d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::GetterCallbackEvent(String* name, Address entry_point) { 713d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 714d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 715d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SmartPointer<char> str = 716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("get ", *str, entry_point); 718d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 719d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 720d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 721d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 722d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::SetterCallbackEvent(String* name, Address entry_point) { 723d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 725d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SmartPointer<char> str = 726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 727d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallbackEventInternal("set ", *str, entry_point); 728d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 729d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 730d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 731d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code, 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* comment) { 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"", code->ExecutableSize()); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (const char* p = comment; *p != '\0'; p++) { 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*p == '"') { 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\\'); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(*p); 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name) { 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> str = 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"%s\"", code->ExecutableSize(), *str); 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code, String* name, 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* source, int line) { 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> str = 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<char> sourcestr = 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"%s %s:%d\"", 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->ExecutableSize(), *str, *sourcestr, line); 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count); 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::RegExpCodeCreateEvent(Code* code, String* source) { 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block log_events_[CODE_CREATION_EVENT], log_events_[REG_EXP_TAG]); 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(code->address()); 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d,\"", code->ExecutableSize()); 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendDetailed(source, false); 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\"'); 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::CodeMoveEvent(Address from, Address to) { 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 840d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MoveEventInternal(CODE_MOVE_EVENT, from, to); 841d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 842d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::CodeDeleteEvent(Address from) { 846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 847d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeleteEventInternal(CODE_DELETE_EVENT, from); 848d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 849d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 850d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 851d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 852d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::SnapshotPositionEvent(Address addr, int pos) { 853d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 854d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!Log::IsEnabled() || !FLAG_log_snapshot_positions) return; 855d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LogMessageBuilder msg; 856d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append("%s,", log_events_[SNAPSHOT_POSITION_EVENT]); 857d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(addr); 858d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append(",%d", pos); 859d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_compress_log) { 860d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(compression_helper_ != NULL); 861d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!compression_helper_->HandleMessage(&msg)) return; 862d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append('\n'); 864d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.WriteToLogFile(); 865d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 866d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 867d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 868d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::FunctionCreateEvent(JSFunction* function) { 870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static Address prev_code = NULL; 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 874d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append("%s,", log_events_[FUNCTION_CREATION_EVENT]); 875d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(function->address()); 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 877d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(function->code()->address(), prev_code); 878d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke prev_code = function->code()->address(); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::FunctionMoveEvent(Address from, Address to) { 890888f6729be6a6f6fbe246cb5a9f122e2dbe455b7Leon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 891d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MoveEventInternal(FUNCTION_MOVE_EVENT, from, to); 892d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 893d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 894d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 895d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 896d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::FunctionDeleteEvent(Address from) { 897d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 898d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeleteEventInternal(FUNCTION_DELETE_EVENT, from); 899d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 900d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 901d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::MoveEventInternal(LogEventsAndTags event, 905d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Address from, 906d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Address to) { 907d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static Address prev_to_ = NULL; 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_code) return; 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append("%s,", log_events_[event]); 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(from); 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append(','); 913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(to, prev_to_); 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke prev_to_ = to; 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 921eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 925e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef ENABLE_LOGGING_AND_PROFILING 926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::DeleteEventInternal(LogEventsAndTags event, Address from) { 927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!Log::IsEnabled() || !FLAG_log_code) return; 928e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LogMessageBuilder msg; 929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append("%s,", log_events_[event]); 930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(from); 931e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (FLAG_compress_log) { 932e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(compression_helper_ != NULL); 933e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (!compression_helper_->HandleMessage(&msg)) return; 934e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 935e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke msg.Append('\n'); 936e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke msg.WriteToLogFile(); 937eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 939e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 940e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::ResourceEvent(const char* name, const char* tag) { 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log) return; 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,%s,", name, tag); 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t sec, usec; 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (OS::GetUserTime(&sec, &usec) != -1) { 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%d,%d,", sec, usec); 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%.0f", OS::TimeCurrentMillis()); 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::SuspectReadEvent(String* name, Object* obj) { 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_suspect) return; 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* class_name = obj->IsJSObject() 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ? JSObject::cast(obj)->class_name() 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : Heap::empty_string(); 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("suspect-read,"); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(class_name); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(name); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('"'); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleBeginEvent(const char* space, const char* kind) { 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Using non-relative system time in order to be able to synchronize with 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // external memory profiling events (e.g. DOM memory size). 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space, kind, OS::TimeCurrentMillis()); 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleStats(const char* space, const char* kind, 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int capacity, int used) { 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-stats,\"%s\",\"%s\",%d,%d\n", 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space, kind, capacity, used); 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleEndEvent(const char* space, const char* kind) { 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleJSConstructorEvent(const char* constructor, 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int number, int bytes) { 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes); 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::HeapSampleJSRetainersEvent( 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* constructor, const char* event) { 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Event starts with comma, so we don't have it in the format string. 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* event_text = "heap-js-ret-item,%s"; 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We take placeholder strings into account, but it's OK to be conservative. 1041d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int event_text_len = StrLength(event_text); 1042d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const int cons_len = StrLength(constructor); 1043d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const int event_len = StrLength(event); 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos = 0; 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Retainer lists can be long. We may need to split them into multiple events. 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(event_text, constructor); 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int to_write = event_len - pos; 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (to_write > Log::kMessageBufferSize - (cons_len + event_text_len)) { 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int cut_pos = pos + Log::kMessageBufferSize - (cons_len + event_text_len); 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(cut_pos < event_len); 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (cut_pos > pos && event[cut_pos] != ',') --cut_pos; 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event[cut_pos] != ',') { 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Crash in debug mode, skip in release mode. 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(false); 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append a piece of event that fits, without trailing comma. 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendStringPart(event + pos, cut_pos - pos); 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Start next piece with comma. 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos = cut_pos; 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s", event + pos); 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos += event_len; 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (pos < event_len); 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Logger::HeapSampleJSProducerEvent(const char* constructor, 10753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Address* stack) { 10763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING 10773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!Log::IsEnabled() || !FLAG_log_gc) return; 10783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block LogMessageBuilder msg; 10793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block msg.Append("heap-js-prod-item,%s", constructor); 10803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block while (*stack != NULL) { 10813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block msg.Append(",0x%" V8PRIxPTR, *stack++); 10823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 10833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block msg.Append("\n"); 10843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block msg.WriteToLogFile(); 10853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif 10863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 10873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DebugTag(const char* call_site_tag) { 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log) return; 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("debug-tag,%s\n", call_site_tag); 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_log) return; 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StringBuilder s(parameter.length() + 1); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < parameter.length(); ++i) { 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block s.AddCharacter(static_cast<char>(parameter[i])); 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* parameter_string = s.Finalize(); 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("debug-queue-event,%s,%15.3f,%s\n", 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_type, 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::TimeCurrentMillis(), 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parameter_string); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(parameter_string); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::TickEvent(TickSample* sample, bool overflow) { 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled() || !FLAG_prof) return; 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Address prev_sp = NULL; 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static Address prev_function = NULL; 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder msg; 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append("%s,", log_events_[TICK_EVENT]); 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Address prev_addr = sample->pc; 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(prev_addr); 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(sample->sp, prev_sp); 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke prev_sp = sample->sp; 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.Append(','); 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke msg.AppendAddress(sample->function, prev_function); 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke prev_function = sample->function; 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",%d", static_cast<int>(sample->state)); 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (overflow) { 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(",overflow"); 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < sample->frames_count; ++i) { 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append(','); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.AppendAddress(sample->stack[i], prev_addr); 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prev_addr = sample->stack[i]; 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(compression_helper_ != NULL); 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!compression_helper_->HandleMessage(&msg)) return; 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.Append('\n'); 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block msg.WriteToLogFile(); 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Logger::GetActiveProfilerModules() { 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result = PROFILER_MODULE_NONE; 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!profiler_->paused()) { 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result |= PROFILER_MODULE_CPU; 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_log_gc) { 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result |= PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS; 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Logger::PauseProfiler(int flags, int tag) { 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled()) return; 1165402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (flags & PROFILER_MODULE_CPU) { 1166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // It is OK to have negative nesting. 1167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (--cpu_profiler_nesting_ == 0) { 1168402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->pause(); 1169402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (FLAG_prof_lazy) { 1170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (!FLAG_sliding_state_window) ticker_->Stop(); 1171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_code = false; 1172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // Must be the same message as Log::kDynamicBufferSeal. 1173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LOG(UncheckedStringEvent("profiler", "pause")); 1174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 11756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block --logging_nesting_; 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1178402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (flags & 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { 1180402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (--heap_profiler_nesting_ == 0) { 1181402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_gc = false; 11826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block --logging_nesting_; 1183402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 1184402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 1185402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (tag != 0) { 11866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block UncheckedIntEvent("close-tag", tag); 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1191402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid Logger::ResumeProfiler(int flags, int tag) { 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Log::IsEnabled()) return; 1193402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (tag != 0) { 11946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block UncheckedIntEvent("open-tag", tag); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1196402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (flags & PROFILER_MODULE_CPU) { 1197402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (cpu_profiler_nesting_++ == 0) { 11986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ++logging_nesting_; 1199402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (FLAG_prof_lazy) { 1200402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->Engage(); 1201402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LOG(UncheckedStringEvent("profiler", "resume")); 1202402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_code = true; 1203402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LogCompiledFunctions(); 1204402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LogFunctionObjects(); 1205402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu LogAccessorCallbacks(); 1206402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (!FLAG_sliding_state_window) ticker_->Start(); 1207402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 1208402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu profiler_->resume(); 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1211402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (flags & 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { 1213402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (heap_profiler_nesting_++ == 0) { 12146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ++logging_nesting_; 1215402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu FLAG_log_gc = true; 1216402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function can be called when Log's mutex is acquired, 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// either from main or Profiler's thread. 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::StopLoggingAndProfiling() { 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::stop(); 1225402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu PauseProfiler(PROFILER_MODULE_CPU, 0); 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Logger::IsProfilerSamplerActive() { 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ticker_->IsActive(); 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) { 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Log::GetLogLines(from_pos, dest_buf, max_size); 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis) { 12403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block AssertNoAllocation no_alloc; 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int compiled_funcs_count = 0; 12423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HeapIterator iterator; 1243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 12443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!obj->IsSharedFunctionInfo()) continue; 12453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); 12463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (sfi->is_compiled() 12473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block && (!sfi->script()->IsScript() 12483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block || Script::cast(sfi->script())->HasValidSource())) { 12493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (sfis != NULL) 12503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); 12513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ++compiled_funcs_count; 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 12533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 12543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return compiled_funcs_count; 12553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::LogCodeObject(Object* object) { 1259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (FLAG_log_code) { 1260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Code* code_object = Code::cast(object); 1261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block LogEventsAndTags tag = Logger::STUB_TAG; 1262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* description = "Unknown code from the snapshot"; 1263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block switch (code_object->kind()) { 1264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::FUNCTION: 1265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; // We log this later using LogCompiledFunctions. 12666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::BINARY_OP_IC: 12676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // fall through 1268d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::STUB: 12693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu description = CodeStub::MajorName(code_object->major_key(), true); 12703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (description == NULL) 12713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu description = "A stub from the snapshot"; 1272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::STUB_TAG; 1273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::BUILTIN: 1275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A builtin from the snapshot"; 1276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::BUILTIN_TAG; 1277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::KEYED_LOAD_IC: 1279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A keyed load IC from the snapshot"; 1280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::KEYED_LOAD_IC_TAG; 1281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::LOAD_IC: 1283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A load IC from the snapshot"; 1284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::LOAD_IC_TAG; 1285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::STORE_IC: 1287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A store IC from the snapshot"; 1288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::STORE_IC_TAG; 1289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::KEYED_STORE_IC: 1291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A keyed store IC from the snapshot"; 1292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::KEYED_STORE_IC_TAG; 1293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case Code::CALL_IC: 1295d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block description = "A call IC from the snapshot"; 1296d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block tag = Logger::CALL_IC_TAG; 1297d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 1298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 12996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent(tag, code_object, description)); 1300d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1301d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 13043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Logger::LogCodeObjects() { 13053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu AssertNoAllocation no_alloc; 13063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu HeapIterator iterator; 13073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 13083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (obj->IsCode()) LogCodeObject(obj); 13093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 13103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 13113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 13133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Logger::LogCompiledFunctions() { 13143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope scope; 13153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int compiled_funcs_count = EnumerateCompiledFunctions(NULL); 13163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Handle<SharedFunctionInfo>* sfis = 13173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block NewArray< Handle<SharedFunctionInfo> >(compiled_funcs_count); 13183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block EnumerateCompiledFunctions(sfis); 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // During iteration, there can be heap allocation due to 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetScriptLineNumber call. 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < compiled_funcs_count; ++i) { 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared = sfis[i]; 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name(String::cast(shared->name())); 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> func_name(name->length() > 0 ? 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *name : shared->inferred_name()); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (shared->script()->IsScript()) { 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script(Script::cast(shared->script())); 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script->name()->IsString()) { 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> script_name(String::cast(script->name())); 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line_num = GetScriptLineNumber(script, shared->start_position()); 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (line_num > 0) { 13336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent( 13346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), 13356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->code(), *func_name, 13366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block *script_name, line_num + 1)); 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 13386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Can't distinguish eval and script here, so always use Script. 13396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent( 13406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 13416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->code(), *script_name)); 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } else { 13446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent( 13456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), 13466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block shared->code(), *func_name)); 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 13486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (shared->IsApiFunction()) { 1349d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // API function. 13506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block FunctionTemplateInfo* fun_data = shared->get_api_func_data(); 1351d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object* raw_call_data = fun_data->call_code(); 1352d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!raw_call_data->IsUndefined()) { 1353d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 1354d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object* callback_obj = call_data->callback(); 1355d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address entry_point = v8::ToCData<Address>(callback_obj); 13566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CallbackEvent(*func_name, entry_point)); 1357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } else { 13596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(CodeCreateEvent( 1360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(sfis); 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid Logger::LogFunctionObjects() { 1369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke AssertNoAllocation no_alloc; 1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke HeapIterator iterator; 1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 1372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!obj->IsJSFunction()) continue; 1373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke JSFunction* jsf = JSFunction::cast(obj); 1374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!jsf->is_compiled()) continue; 13756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(FunctionCreateEvent(jsf)); 1376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Logger::LogAccessorCallbacks() { 1381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block AssertNoAllocation no_alloc; 1382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block HeapIterator iterator; 1383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 1384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!obj->IsAccessorInfo()) continue; 1385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block AccessorInfo* ai = AccessorInfo::cast(obj); 1386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!ai->name()->IsString()) continue; 1387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block String* name = String::cast(ai->name()); 1388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address getter_entry = v8::ToCData<Address>(ai->getter()); 1389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (getter_entry != 0) { 13906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(GetterCallbackEvent(name, getter_entry)); 1391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1392d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address setter_entry = v8::ToCData<Address>(ai->setter()); 1393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (setter_entry != 0) { 13946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block PROFILE(SetterCallbackEvent(name, setter_entry)); 1395d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1397d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1398d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Logger::Setup() { 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --log-all enables all the log flags. 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_log_all) { 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_runtime = true; 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_api = true; 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_code = true; 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_gc = true; 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_suspect = true; 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_handles = true; 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_regexp = true; 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --prof implies --log-code. 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_prof) FLAG_log_code = true; 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --prof_lazy controls --log-code, implies --noprof_auto. 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_prof_lazy) { 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_log_code = false; 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_prof_auto = false; 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block || FLAG_log_regexp || FLAG_log_state_changes; 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool open_log_file = start_logging || FLAG_prof_lazy; 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we're logging anything, we need to open the log file. 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (open_log_file) { 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strcmp(FLAG_logfile, "-") == 0) { 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::OpenStdout(); 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(FLAG_logfile, "*") == 0) { 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::OpenMemoryBuffer(); 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strchr(FLAG_logfile, '%') != NULL) { 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there's a '%' in the log file name we have to expand 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // placeholders. 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapStringAllocator allocator; 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StringStream stream(&allocator); 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (const char* p = FLAG_logfile; *p; p++) { 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*p == '%') { 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block p++; 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (*p) { 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\0': 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there's a % at the end of the string we back up 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // one character so we can escape the loop properly. 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block p--; 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 't': { 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %t expands to the current time in milliseconds. 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double time = OS::TimeCurrentMillis(); 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream.Add("%.0f", FmtElm(time)); 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '%': 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %% expands (contracts really) to %. 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream.Put('%'); 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All other %'s expand to themselves. 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream.Put('%'); 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream.Put(*p); 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream.Put(*p); 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartPointer<const char> expanded = stream.ToCString(); 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::OpenFile(*expanded); 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::OpenFile(FLAG_logfile); 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(VMState::is_outermost_external()); 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ticker_ = new Ticker(kSamplingIntervalMs); 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sliding_state_window_ = new SlidingStateWindow(); 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block log_events_ = FLAG_compress_log ? 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kCompressedLogEventsNames : kLongLogEventsNames; 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_compress_log) { 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block compression_helper_ = new CompressionHelper(kCompressionWindowSize); 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (start_logging) { 14926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block logging_nesting_ = 1; 14936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_prof) { 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = new Profiler(); 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!FLAG_prof_auto) { 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_->pause(); 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 15006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block logging_nesting_ = 1; 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1502d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!FLAG_prof_lazy) { 1503d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block profiler_->Engage(); 1504d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder::set_write_failure_handler(StopLoggingAndProfiling); 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::TearDown() { 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LogMessageBuilder::set_write_failure_handler(NULL); 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stop the profiler before closing the file. 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (profiler_ != NULL) { 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_->Disengage(); 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete profiler_; 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block profiler_ = NULL; 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete compression_helper_; 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block compression_helper_ = NULL; 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete sliding_state_window_; 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sliding_state_window_ = NULL; 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete ticker_; 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ticker_ = NULL; 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::Close(); 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Logger::EnableSlidingStateWindow() { 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the ticker is NULL, Logger::Setup has not been called yet. In 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that case, we set the sliding_state_window flag so that the 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sliding window computation will be started when Logger::Setup is 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // called. 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ticker_ == NULL) { 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_sliding_state_window = true; 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Otherwise, if the sliding state window computation has not been 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // started we do it now. 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (sliding_state_window_ == NULL) { 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sliding_state_window_ = new SlidingStateWindow(); 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1561