cpu-profiler.h revision 257744e915dfc84d6d07a6b2accf8402d9ffc708
16ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Copyright 2010 the V8 project authors. All rights reserved.
26ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Redistribution and use in source and binary forms, with or without
36ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// modification, are permitted provided that the following conditions are
46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// met:
56ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//
66ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//     * Redistributions of source code must retain the above copyright
76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       notice, this list of conditions and the following disclaimer.
86ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//     * Redistributions in binary form must reproduce the above
96ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       copyright notice, this list of conditions and the following
106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       disclaimer in the documentation and/or other materials provided
116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       with the distribution.
126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//     * Neither the name of Google Inc. nor the names of its
136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       contributors may be used to endorse or promote products derived
146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//       from this software without specific prior written permission.
156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//
166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_CPU_PROFILER_H_
296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define V8_CPU_PROFILER_H_
306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING
326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h"
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "atomicops.h"
356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "circular-queue.h"
36f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "unbound-queue.h"
376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
386ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 {
396ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal {
406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Forward declarations.
426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeEntry;
436ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMap;
446ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfile;
456ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfilesCollection;
460d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass HashMap;
476ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileGenerator;
48f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeclass TokenEnumerator;
496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CODE_EVENTS_TYPE_LIST(V)                                   \
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(CODE_CREATION,    CodeCreateEventRecord)                       \
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(CODE_MOVE,        CodeMoveEventRecord)                         \
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(CODE_DELETE,      CodeDeleteEventRecord)                       \
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)
556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
576ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeEventRecord {
586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DECLARE_TYPE(type, ignore) type,
606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  enum Type {
616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    NONE = 0,
626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    CODE_EVENTS_TYPE_LIST(DECLARE_TYPE)
636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    NUMBER_OF_TYPES
646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  };
656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef DECLARE_TYPE
666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Type type;
686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  unsigned order;
696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
726ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeCreateEventRecord : public CodeEventRecord {
736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Address start;
756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* entry;
766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  unsigned size;
7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address shared;
786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(void UpdateCodeMap(CodeMap* code_map));
806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
836ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMoveEventRecord : public CodeEventRecord {
846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Address from;
866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Address to;
876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(void UpdateCodeMap(CodeMap* code_map));
896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
926ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeDeleteEventRecord : public CodeEventRecord {
936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Address start;
956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(void UpdateCodeMap(CodeMap* code_map));
976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
10044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Address from;
103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Address to;
1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(void UpdateCodeMap(CodeMap* code_map));
1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass TickSampleEventRecord BASE_EMBEDDED {
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  TickSampleEventRecord()
1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      : filler(1) {
1137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    ASSERT(filler != SamplingCircularQueue::kClear);
1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // The first machine word of a TickSampleEventRecord must not ever
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // become equal to SamplingCircularQueue::kClear.  As both order and
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // TickSample's first field are not reliable in this sense (order
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // can overflow, TickSample can have all fields reset), we are
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // forced to use an artificial filler field.
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int filler;
1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  unsigned order;
1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TickSample sample;
1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static TickSampleEventRecord* cast(void* value) {
1266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return reinterpret_cast<TickSampleEventRecord*>(value);
1276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(static TickSampleEventRecord* init(void* value));
1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// This class implements both the profile events processor thread and
1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// methods called by event producers: VM and stack sampler threads.
1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfilerEventsProcessor : public Thread {
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ProfilerEventsProcessor(Isolate* isolate,
138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          ProfileGenerator* generator);
139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  virtual ~ProfilerEventsProcessor() {}
1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Thread control.
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  virtual void Run();
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void Stop() { running_ = false; }
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(bool running()) { return running_; }
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Events adding methods. Called by VM threads.
1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallbackCreateEvent(Logger::LogEventsAndTags tag,
1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           const char* prefix, String* name,
1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           Address start);
1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeCreateEvent(Logger::LogEventsAndTags tag,
1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       String* name,
1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       String* resource_name, int line_number,
153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                       Address start, unsigned size,
15444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                       Address shared);
1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeCreateEvent(Logger::LogEventsAndTags tag,
1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       const char* name,
1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       Address start, unsigned size);
1586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeCreateEvent(Logger::LogEventsAndTags tag,
1596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       int args_count,
1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                       Address start, unsigned size);
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeMoveEvent(Address from, Address to);
1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeDeleteEvent(Address from);
16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SharedFunctionInfoMoveEvent(Address from, Address to);
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RegExpCodeCreateEvent(Logger::LogEventsAndTags tag,
1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                             const char* prefix, String* name,
1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                             Address start, unsigned size);
1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Puts current stack into tick sample events buffer.
1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void AddCurrentStack();
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Tick sample events are filled directly in the buffer of the circular
1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // queue (because the structure is of fixed width, but usually not all
1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // stack frame entries are filled.) This method returns a pointer to the
1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // next record of the buffer.
1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(TickSample* TickSampleEvent());
1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  union CodeEventsContainer {
1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    CodeEventRecord generic;
1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DECLARE_CLASS(ignore, type) type type##_;
1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef DECLARE_TYPE
1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  };
1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Called from events processing thread (Run() method.)
1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool ProcessCodeEvent(unsigned* dequeue_order);
1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool ProcessTicks(unsigned dequeue_order);
1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  INLINE(static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag));
1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileGenerator* generator_;
1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool running_;
192f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  UnboundQueue<CodeEventsContainer> events_buffer_;
1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SamplingCircularQueue ticks_buffer_;
1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  UnboundQueue<TickSampleEventRecord> ticks_from_vm_buffer_;
1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  unsigned enqueue_order_;
1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} }  // namespace v8::internal
1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define PROFILE(isolate, Call)                                \
202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOG(isolate, Call);                                         \
203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  do {                                                        \
204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (v8::internal::CpuProfiler::is_profiling(isolate)) {   \
205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::internal::CpuProfiler::Call;                        \
206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }                                                         \
2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } while (false)
2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else
20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define PROFILE(isolate, Call) LOG(isolate, Call)
2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif  // ENABLE_LOGGING_AND_PROFILING
2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 {
2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal {
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// TODO(isolates): isolatify this class.
2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfiler {
2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void Setup();
2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void TearDown();
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_LOGGING_AND_PROFILING
2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void StartProfiling(const char* title);
2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void StartProfiling(String* title);
2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static CpuProfile* StopProfiling(const char* title);
227f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  static CpuProfile* StopProfiling(Object* security_token, String* title);
2286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static int GetProfilesCount();
229f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  static CpuProfile* GetProfile(Object* security_token, int index);
230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  static CpuProfile* FindProfile(Object* security_token, unsigned uid);
23144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void DeleteAllProfiles();
23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void DeleteProfile(CpuProfile* profile);
23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static bool HasDetachedProfiles();
2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Invoked from stack sampler (thread or signal handler.)
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static TickSample* TickSampleEvent(Isolate* isolate);
2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Must be called via PROFILE macro, otherwise will crash when
2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // profiling is not enabled.
2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CallbackEvent(String* name, Address entry_point);
2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              Code* code, const char* comment);
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              Code* code, String* name);
2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                              Code* code,
247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                              SharedFunctionInfo *shared,
248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                              String* name);
249e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
250e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                              Code* code,
251e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                              SharedFunctionInfo *shared,
2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              String* source, int line);
2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              Code* code, int args_count);
255f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static void CodeMovingGCEvent() {}
2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeMoveEvent(Address from, Address to);
2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void CodeDeleteEvent(Address from);
2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void GetterCallbackEvent(String* name, Address entry_point);
2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void RegExpCodeCreateEvent(Code* code, String* source);
2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static void SetterCallbackEvent(String* name, Address entry_point);
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void SharedFunctionInfoMoveEvent(Address from, Address to);
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): this doesn't have to use atomics anymore.
2646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
26544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static INLINE(bool is_profiling(Isolate* isolate)) {
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuProfiler* profiler = isolate->cpu_profiler();
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return profiler != NULL && NoBarrier_Load(&profiler->is_profiling_);
2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CpuProfiler();
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ~CpuProfiler();
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void StartCollectingProfile(const char* title);
2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void StartCollectingProfile(String* title);
2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void StartProcessorIfNotStarted();
2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CpuProfile* StopCollectingProfile(const char* title);
277f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CpuProfile* StopCollectingProfile(Object* security_token, String* title);
278756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void StopProcessorIfLastProfile(const char* title);
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void StopProcessor();
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ResetProfiles();
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CpuProfilesCollection* profiles_;
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  unsigned next_profile_uid_;
284f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  TokenEnumerator* token_enumerator_;
2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileGenerator* generator_;
2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfilerEventsProcessor* processor_;
2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int saved_logging_nesting_;
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool need_to_stop_sampler_;
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Atomic32 is_profiling_;
2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else
292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static INLINE(bool is_profiling(Isolate* isolate)) { return false; }
2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif  // ENABLE_LOGGING_AND_PROFILING
2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
2966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} }  // namespace v8::internal
3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif  // V8_CPU_PROFILER_H_
303