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