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