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