blob: b353f548fb78b88d212b24b86391ccc08fb9c655 [file] [log] [blame]
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdarg.h>
29
30#include "v8.h"
31
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +000032#include "bootstrapper.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000033#include "code-stubs.h"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000034#include "cpu-profiler.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "deoptimizer.h"
ager@chromium.org01beca72009-11-24 14:29:16 +000036#include "global-handles.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037#include "log.h"
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000038#include "log-utils.h"
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000039#include "macro-assembler.h"
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000040#include "platform.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000041#include "runtime-profiler.h"
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +000042#include "serialize.h"
43#include "string-stream.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000044#include "vm-state-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
jkummerow@chromium.org10480472013-07-17 08:22:15 +000049
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000050#define DECLARE_EVENT(ignore1, name) name,
51static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
53};
54#undef DECLARE_EVENT
55
56
danno@chromium.orgd3c42102013-08-01 16:58:23 +000057#define CALL_LISTENERS(Call) \
58for (int i = 0; i < listeners_.length(); ++i) { \
59 listeners_[i]->Call; \
60}
61
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +000062#define PROFILER_LOG(Call) \
63 do { \
64 CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \
65 if (cpu_profiler->is_profiling()) { \
66 cpu_profiler->Call; \
67 } \
68 } while (false);
69
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000070// ComputeMarker must only be used when SharedFunctionInfo is known.
71static const char* ComputeMarker(Code* code) {
72 switch (code->kind()) {
73 case Code::FUNCTION: return code->optimizable() ? "~" : "";
74 case Code::OPTIMIZED_FUNCTION: return "*";
75 default: return "";
76 }
77}
78
79
danno@chromium.orgd3c42102013-08-01 16:58:23 +000080class CodeEventLogger::NameBuffer {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000081 public:
danno@chromium.orgd3c42102013-08-01 16:58:23 +000082 NameBuffer() { Reset(); }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000083
danno@chromium.orgd3c42102013-08-01 16:58:23 +000084 void Reset() {
85 utf8_pos_ = 0;
86 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000087
danno@chromium.orgd3c42102013-08-01 16:58:23 +000088 void Init(Logger::LogEventsAndTags tag) {
89 Reset();
90 AppendBytes(kLogEventsNames[tag]);
91 AppendByte(':');
92 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +000093
danno@chromium.orgd3c42102013-08-01 16:58:23 +000094 void AppendName(Name* name) {
95 if (name->IsString()) {
96 AppendString(String::cast(name));
97 } else {
98 Symbol* symbol = Symbol::cast(name);
99 AppendBytes("symbol(");
100 if (!symbol->name()->IsUndefined()) {
101 AppendBytes("\"");
102 AppendString(String::cast(symbol->name()));
103 AppendBytes("\" ");
104 }
105 AppendBytes("hash ");
106 AppendHex(symbol->Hash());
107 AppendByte(')');
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000108 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000109 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000110
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000111 void AppendString(String* str) {
112 if (str == NULL) return;
113 int uc16_length = Min(str->length(), kUtf16BufferSize);
114 String::WriteToFlat(str, utf16_buffer, 0, uc16_length);
115 int previous = unibrow::Utf16::kNoPreviousCharacter;
116 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
117 uc16 c = utf16_buffer[i];
118 if (c <= unibrow::Utf8::kMaxOneByteChar) {
119 utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000120 } else {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000121 int char_length = unibrow::Utf8::Length(c, previous);
122 if (utf8_pos_ + char_length > kUtf8BufferSize) break;
123 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous);
124 utf8_pos_ += char_length;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000125 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000126 previous = c;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000127 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000128 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000129
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000130 void AppendBytes(const char* bytes, int size) {
131 size = Min(size, kUtf8BufferSize - utf8_pos_);
132 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
133 utf8_pos_ += size;
134 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000135
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000136 void AppendBytes(const char* bytes) {
137 AppendBytes(bytes, StrLength(bytes));
138 }
139
140 void AppendByte(char c) {
141 if (utf8_pos_ >= kUtf8BufferSize) return;
142 utf8_buffer_[utf8_pos_++] = c;
143 }
144
145 void AppendInt(int n) {
146 Vector<char> buffer(utf8_buffer_ + utf8_pos_,
147 kUtf8BufferSize - utf8_pos_);
148 int size = OS::SNPrintF(buffer, "%d", n);
149 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000150 utf8_pos_ += size;
151 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000152 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000153
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000154 void AppendHex(uint32_t n) {
155 Vector<char> buffer(utf8_buffer_ + utf8_pos_,
156 kUtf8BufferSize - utf8_pos_);
157 int size = OS::SNPrintF(buffer, "%x", n);
158 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
159 utf8_pos_ += size;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000160 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000161 }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000162
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000163 const char* get() { return utf8_buffer_; }
164 int size() const { return utf8_pos_; }
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000165
166 private:
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000167 static const int kUtf8BufferSize = 512;
168 static const int kUtf16BufferSize = 128;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000169
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000170 int utf8_pos_;
171 char utf8_buffer_[kUtf8BufferSize];
172 uc16 utf16_buffer[kUtf16BufferSize];
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000173};
174
175
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000176CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { }
177
178CodeEventLogger::~CodeEventLogger() { delete name_buffer_; }
179
180
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000181void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
182 Code* code,
183 const char* comment) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000184 name_buffer_->Init(tag);
185 name_buffer_->AppendBytes(comment);
186 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000187}
188
189
190void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
191 Code* code,
192 Name* name) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000193 name_buffer_->Init(tag);
194 name_buffer_->AppendName(name);
195 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000196}
197
198
199void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000200 Code* code,
201 SharedFunctionInfo* shared,
202 CompilationInfo* info,
203 Name* name) {
204 name_buffer_->Init(tag);
205 name_buffer_->AppendBytes(ComputeMarker(code));
206 name_buffer_->AppendName(name);
207 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000208}
209
210
211void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000212 Code* code,
213 SharedFunctionInfo* shared,
214 CompilationInfo* info,
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +0000215 Name* source, int line, int column) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000216 name_buffer_->Init(tag);
217 name_buffer_->AppendBytes(ComputeMarker(code));
218 name_buffer_->AppendString(shared->DebugName());
219 name_buffer_->AppendByte(' ');
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000220 if (source->IsString()) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000221 name_buffer_->AppendString(String::cast(source));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000222 } else {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000223 name_buffer_->AppendBytes("symbol(hash ");
224 name_buffer_->AppendHex(Name::cast(source)->Hash());
225 name_buffer_->AppendByte(')');
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000226 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000227 name_buffer_->AppendByte(':');
228 name_buffer_->AppendInt(line);
229 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000230}
231
232
233void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
234 Code* code,
235 int args_count) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000236 name_buffer_->Init(tag);
237 name_buffer_->AppendInt(args_count);
238 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000239}
240
241
242void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000243 name_buffer_->Init(Logger::REG_EXP_TAG);
244 name_buffer_->AppendString(source);
245 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000246}
247
248
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000249// Low-level logging support.
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000250#define LL_LOG(Call) if (ll_logger_) ll_logger_->Call;
251
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000252class LowLevelLogger : public CodeEventLogger {
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000253 public:
254 explicit LowLevelLogger(const char* file_name);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000255 virtual ~LowLevelLogger();
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000256
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000257 virtual void CodeMoveEvent(Address from, Address to);
258 virtual void CodeDeleteEvent(Address from);
259 virtual void SnapshotPositionEvent(Address addr, int pos);
260 virtual void CodeMovingGCEvent();
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000261
262 private:
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000263 virtual void LogRecordedBuffer(Code* code,
264 SharedFunctionInfo* shared,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000265 const char* name,
266 int length);
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000267
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000268 // Low-level profiling event structures.
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000269 struct CodeCreateStruct {
270 static const char kTag = 'C';
271
272 int32_t name_size;
273 Address code_address;
274 int32_t code_size;
275 };
276
277
278 struct CodeMoveStruct {
279 static const char kTag = 'M';
280
281 Address from_address;
282 Address to_address;
283 };
284
285
286 struct CodeDeleteStruct {
287 static const char kTag = 'D';
288
289 Address address;
290 };
291
292
293 struct SnapshotPositionStruct {
294 static const char kTag = 'P';
295
296 Address address;
297 int32_t position;
298 };
299
300
301 static const char kCodeMovingGCTag = 'G';
302
303
304 // Extension added to V8 log file name to get the low-level log name.
305 static const char kLogExt[];
306
307 // File buffer size of the low-level log. We don't use the default to
308 // minimize the associated overhead.
309 static const int kLogBufferSize = 2 * MB;
310
311 void LogCodeInfo();
312 void LogWriteBytes(const char* bytes, int size);
313
314 template <typename T>
315 void LogWriteStruct(const T& s) {
316 char tag = T::kTag;
317 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
318 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
319 }
320
321 FILE* ll_output_handle_;
322};
323
324const char LowLevelLogger::kLogExt[] = ".ll";
325
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000326LowLevelLogger::LowLevelLogger(const char* name)
327 : ll_output_handle_(NULL) {
328 // Open the low-level log file.
329 size_t len = strlen(name);
330 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
331 OS::MemCopy(ll_name.start(), name, len);
332 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt));
333 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
334 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize);
335
336 LogCodeInfo();
337}
338
339
340LowLevelLogger::~LowLevelLogger() {
341 fclose(ll_output_handle_);
342 ll_output_handle_ = NULL;
343}
344
345
346void LowLevelLogger::LogCodeInfo() {
347#if V8_TARGET_ARCH_IA32
348 const char arch[] = "ia32";
349#elif V8_TARGET_ARCH_X64
350 const char arch[] = "x64";
351#elif V8_TARGET_ARCH_ARM
352 const char arch[] = "arm";
353#elif V8_TARGET_ARCH_MIPS
354 const char arch[] = "mips";
355#else
356 const char arch[] = "unknown";
357#endif
358 LogWriteBytes(arch, sizeof(arch));
359}
360
361
362void LowLevelLogger::LogRecordedBuffer(Code* code,
363 SharedFunctionInfo*,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000364 const char* name,
365 int length) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000366 CodeCreateStruct event;
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000367 event.name_size = length;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000368 event.code_address = code->instruction_start();
369 ASSERT(event.code_address == code->address() + Code::kHeaderSize);
370 event.code_size = code->instruction_size();
371 LogWriteStruct(event);
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000372 LogWriteBytes(name, length);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000373 LogWriteBytes(
374 reinterpret_cast<const char*>(code->instruction_start()),
375 code->instruction_size());
376}
377
378
379void LowLevelLogger::CodeMoveEvent(Address from, Address to) {
380 CodeMoveStruct event;
381 event.from_address = from + Code::kHeaderSize;
382 event.to_address = to + Code::kHeaderSize;
383 LogWriteStruct(event);
384}
385
386
387void LowLevelLogger::CodeDeleteEvent(Address from) {
388 CodeDeleteStruct event;
389 event.address = from + Code::kHeaderSize;
390 LogWriteStruct(event);
391}
392
393
394void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) {
395 SnapshotPositionStruct event;
396 event.address = addr + Code::kHeaderSize;
397 event.position = pos;
398 LogWriteStruct(event);
399}
400
401
402void LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
403 size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
404 ASSERT(static_cast<size_t>(size) == rv);
405 USE(rv);
406}
407
408
409void LowLevelLogger::CodeMovingGCEvent() {
410 const char tag = kCodeMovingGCTag;
411
412 LogWriteBytes(&tag, sizeof(tag));
413}
414
415
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000416#define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000417
418
419class JitLogger : public CodeEventLogger {
420 public:
421 explicit JitLogger(JitCodeEventHandler code_event_handler);
422
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000423 virtual void CodeMoveEvent(Address from, Address to);
424 virtual void CodeDeleteEvent(Address from);
425 virtual void AddCodeLinePosInfoEvent(
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000426 void* jit_handler_data,
427 int pc_offset,
428 int position,
429 JitCodeEvent::PositionType position_type);
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000430
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000431 void* StartCodePosInfoEvent();
432 void EndCodePosInfoEvent(Code* code, void* jit_handler_data);
433
434 private:
435 virtual void LogRecordedBuffer(Code* code,
436 SharedFunctionInfo* shared,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000437 const char* name,
438 int length);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000439
440 JitCodeEventHandler code_event_handler_;
441};
442
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000443
444JitLogger::JitLogger(JitCodeEventHandler code_event_handler)
445 : code_event_handler_(code_event_handler) {
446}
447
448
449void JitLogger::LogRecordedBuffer(Code* code,
450 SharedFunctionInfo* shared,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000451 const char* name,
452 int length) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000453 JitCodeEvent event;
454 memset(&event, 0, sizeof(event));
455 event.type = JitCodeEvent::CODE_ADDED;
456 event.code_start = code->instruction_start();
457 event.code_len = code->instruction_size();
458 Handle<Script> script_handle;
459 if (shared && shared->script()->IsScript()) {
460 script_handle = Handle<Script>(Script::cast(shared->script()));
461 }
462 event.script = ToApiHandle<v8::Script>(script_handle);
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000463 event.name.str = name;
464 event.name.len = length;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000465 code_event_handler_(&event);
466}
467
468
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +0000469void JitLogger::CodeMoveEvent(Address from, Address to) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000470 Code* from_code = Code::cast(HeapObject::FromAddress(from));
471
472 JitCodeEvent event;
473 event.type = JitCodeEvent::CODE_MOVED;
474 event.code_start = from_code->instruction_start();
475 event.code_len = from_code->instruction_size();
476
477 // Calculate the header size.
478 const size_t header_size =
479 from_code->instruction_start() - reinterpret_cast<byte*>(from_code);
480
481 // Calculate the new start address of the instructions.
482 event.new_code_start =
483 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size;
484
485 code_event_handler_(&event);
486}
487
488
489void JitLogger::CodeDeleteEvent(Address from) {
490 Code* from_code = Code::cast(HeapObject::FromAddress(from));
491
492 JitCodeEvent event;
493 event.type = JitCodeEvent::CODE_REMOVED;
494 event.code_start = from_code->instruction_start();
495 event.code_len = from_code->instruction_size();
496
497 code_event_handler_(&event);
498}
499
500void JitLogger::AddCodeLinePosInfoEvent(
501 void* jit_handler_data,
502 int pc_offset,
503 int position,
504 JitCodeEvent::PositionType position_type) {
505 JitCodeEvent event;
506 memset(&event, 0, sizeof(event));
507 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO;
508 event.user_data = jit_handler_data;
509 event.line_info.offset = pc_offset;
510 event.line_info.pos = position;
511 event.line_info.position_type = position_type;
512
513 code_event_handler_(&event);
514}
515
516
517void* JitLogger::StartCodePosInfoEvent() {
518 JitCodeEvent event;
519 memset(&event, 0, sizeof(event));
520 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING;
521
522 code_event_handler_(&event);
523 return event.user_data;
524}
525
526
527void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) {
528 JitCodeEvent event;
529 memset(&event, 0, sizeof(event));
530 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING;
531 event.code_start = code->instruction_start();
532 event.user_data = jit_handler_data;
533
534 code_event_handler_(&event);
535}
536
537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538// The Profiler samples pc and sp values for the main thread.
539// Each sample is appended to a circular buffer.
540// An independent thread removes data and writes it to the log.
541// This design minimizes the time spent in the sampler.
542//
543class Profiler: public Thread {
544 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000545 explicit Profiler(Isolate* isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000546 void Engage();
547 void Disengage();
548
549 // Inserts collected profiling data into buffer.
550 void Insert(TickSample* sample) {
iposva@chromium.org245aa852009-02-10 00:49:54 +0000551 if (paused_)
552 return;
553
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000554 if (Succ(head_) == tail_) {
555 overflow_ = true;
556 } else {
557 buffer_[head_] = *sample;
558 head_ = Succ(head_);
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000559 buffer_semaphore_.Signal(); // Tell we have an element.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000560 }
561 }
562
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000563 virtual void Run();
564
565 // Pause and Resume TickSample data collection.
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000566 void pause() { paused_ = true; }
567 void resume() { paused_ = false; }
568
569 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000570 // Waits for a signal and removes profiling data.
571 bool Remove(TickSample* sample) {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000572 buffer_semaphore_.Wait(); // Wait for an element.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000573 *sample = buffer_[tail_];
574 bool result = overflow_;
575 tail_ = Succ(tail_);
576 overflow_ = false;
577 return result;
578 }
579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580 // Returns the next index in the cyclic buffer.
581 int Succ(int index) { return (index + 1) % kBufferSize; }
582
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000583 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000584 // Cyclic buffer for communicating profiling samples
585 // between the signal handler and the worker thread.
586 static const int kBufferSize = 128;
587 TickSample buffer_[kBufferSize]; // Buffer storage.
588 int head_; // Index to the buffer head.
589 int tail_; // Index to the buffer tail.
590 bool overflow_; // Tell whether a buffer overflow has occurred.
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000591 // Sempahore used for buffer synchronization.
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000592 Semaphore buffer_semaphore_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000593
ager@chromium.org3811b432009-10-28 14:53:37 +0000594 // Tells whether profiler is engaged, that is, processing thread is stated.
595 bool engaged_;
596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000597 // Tells whether worker thread should continue running.
598 bool running_;
iposva@chromium.org245aa852009-02-10 00:49:54 +0000599
600 // Tells whether we are currently recording tick samples.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000601 bool paused_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602};
603
604
605//
606// Ticker used to provide ticks to the profiler and the sliding state
607// window.
608//
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000609class Ticker: public Sampler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000611 Ticker(Isolate* isolate, int interval):
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000612 Sampler(isolate, interval),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000613 profiler_(NULL) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614
615 ~Ticker() { if (IsActive()) Stop(); }
616
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000617 virtual void Tick(TickSample* sample) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618 if (profiler_) profiler_->Insert(sample);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619 }
620
621 void SetProfiler(Profiler* profiler) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622 ASSERT(profiler_ == NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623 profiler_ = profiler;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000624 IncreaseProfilingDepth();
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000625 if (!IsActive()) Start();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626 }
627
628 void ClearProfiler() {
629 profiler_ = NULL;
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +0000630 if (IsActive()) Stop();
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000631 DecreaseProfilingDepth();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632 }
633
634 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000635 Profiler* profiler_;
636};
637
638
639//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640// Profiler implementation.
641//
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000642Profiler::Profiler(Isolate* isolate)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000643 : Thread("v8:Profiler"),
644 isolate_(isolate),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000645 head_(0),
ager@chromium.org3811b432009-10-28 14:53:37 +0000646 tail_(0),
647 overflow_(false),
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000648 buffer_semaphore_(0),
ager@chromium.org3811b432009-10-28 14:53:37 +0000649 engaged_(false),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000650 running_(false),
651 paused_(false) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000652}
653
654
655void Profiler::Engage() {
ager@chromium.org3811b432009-10-28 14:53:37 +0000656 if (engaged_) return;
657 engaged_ = true;
658
dslomov@chromium.orge97852d2013-09-12 09:02:59 +0000659 OS::LogSharedLibraryAddresses(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660
661 // Start thread processing the profiler buffer.
662 running_ = true;
663 Start();
664
665 // Register to get ticks.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000666 Logger* logger = isolate_->logger();
667 logger->ticker_->SetProfiler(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000669 logger->ProfilerBeginEvent();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670}
671
672
673void Profiler::Disengage() {
ager@chromium.org3811b432009-10-28 14:53:37 +0000674 if (!engaged_) return;
675
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000676 // Stop receiving ticks.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000677 isolate_->logger()->ticker_->ClearProfiler();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678
679 // Terminate the worker thread by setting running_ to false,
680 // inserting a fake element in the queue and then wait for
681 // the thread to terminate.
682 running_ = false;
683 TickSample sample;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000684 // Reset 'paused_' flag, otherwise semaphore may not be signalled.
685 resume();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000686 Insert(&sample);
687 Join();
688
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000689 LOG(isolate_, UncheckedStringEvent("profiler", "end"));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690}
691
692
693void Profiler::Run() {
694 TickSample sample;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +0000695 bool overflow = Remove(&sample);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696 while (running_) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000697 LOG(isolate_, TickEvent(&sample, overflow));
fschneider@chromium.org40b9da32010-06-28 11:29:21 +0000698 overflow = Remove(&sample);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000699 }
700}
701
702
703//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704// Logger class implementation.
705//
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000706
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000707Logger::Logger(Isolate* isolate)
708 : isolate_(isolate),
709 ticker_(NULL),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000710 profiler_(NULL),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000711 log_events_(NULL),
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000712 is_logging_(false),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000713 log_(new Log(this)),
jkummerow@chromium.org10480472013-07-17 08:22:15 +0000714 ll_logger_(NULL),
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000715 jit_logger_(NULL),
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000716 listeners_(5),
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000717 is_initialized_(false) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000718}
719
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000720
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000721Logger::~Logger() {
722 delete log_;
723}
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000724
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000725
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000726void Logger::addCodeEventListener(CodeEventListener* listener) {
727 ASSERT(!hasCodeEventListener(listener));
728 listeners_.Add(listener);
729}
730
731
732void Logger::removeCodeEventListener(CodeEventListener* listener) {
733 ASSERT(hasCodeEventListener(listener));
734 listeners_.RemoveElement(listener);
735}
736
737
738bool Logger::hasCodeEventListener(CodeEventListener* listener) {
739 return listeners_.Contains(listener);
740}
741
742
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000743void Logger::ProfilerBeginEvent() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000744 if (!log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000745 Log::MessageBuilder msg(log_);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000746 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs);
747 msg.WriteToLogFile();
748}
749
ager@chromium.org381abbb2009-02-25 13:23:22 +0000750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000751void Logger::StringEvent(const char* name, const char* value) {
ager@chromium.org6f10e412009-02-13 10:11:16 +0000752 if (FLAG_log) UncheckedStringEvent(name, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753}
754
755
ager@chromium.org6f10e412009-02-13 10:11:16 +0000756void Logger::UncheckedStringEvent(const char* name, const char* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000757 if (!log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000758 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000759 msg.Append("%s,\"%s\"\n", name, value);
760 msg.WriteToLogFile();
ager@chromium.org6f10e412009-02-13 10:11:16 +0000761}
ager@chromium.org6f10e412009-02-13 10:11:16 +0000762
763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000764void Logger::IntEvent(const char* name, int value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000765 if (FLAG_log) UncheckedIntEvent(name, value);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000766}
767
768
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000769void Logger::IntPtrTEvent(const char* name, intptr_t value) {
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000770 if (FLAG_log) UncheckedIntPtrTEvent(name, value);
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000771}
772
773
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000774void Logger::UncheckedIntEvent(const char* name, int value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000775 if (!log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000776 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000777 msg.Append("%s,%d\n", name, value);
778 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779}
780
781
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000782void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000783 if (!log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000784 Log::MessageBuilder msg(log_);
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000785 msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
786 msg.WriteToLogFile();
787}
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000788
789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790void Logger::HandleEvent(const char* name, Object** location) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 if (!log_->IsEnabled() || !FLAG_log_handles) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000792 Log::MessageBuilder msg(log_);
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000793 msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000794 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795}
796
797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000798// ApiEvent is private so all the calls come from the Logger class. It is the
ager@chromium.org9085a012009-05-11 19:22:57 +0000799// caller's responsibility to ensure that log is enabled and that
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800// FLAG_log_api is true.
801void Logger::ApiEvent(const char* format, ...) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000802 ASSERT(log_->IsEnabled() && FLAG_log_api);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000803 Log::MessageBuilder msg(log_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 va_list ap;
805 va_start(ap, format);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000806 msg.AppendVA(format, ap);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000807 va_end(ap);
808 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810
811
812void Logger::ApiNamedSecurityCheck(Object* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000813 if (!log_->IsEnabled() || !FLAG_log_api) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814 if (key->IsString()) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000815 SmartArrayPointer<char> str =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
817 ApiEvent("api,check-security,\"%s\"\n", *str);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000818 } else if (key->IsSymbol()) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000819 Symbol* symbol = Symbol::cast(key);
820 if (symbol->name()->IsUndefined()) {
821 ApiEvent("api,check-security,symbol(hash %x)\n",
822 Symbol::cast(key)->Hash());
823 } else {
824 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
825 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
826 ApiEvent("api,check-security,symbol(\"%s\" hash %x)\n",
827 *str,
828 Symbol::cast(key)->Hash());
829 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 } else if (key->IsUndefined()) {
831 ApiEvent("api,check-security,undefined\n");
832 } else {
833 ApiEvent("api,check-security,['no-name']\n");
834 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000835}
836
837
838void Logger::SharedLibraryEvent(const char* library_path,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000839 uintptr_t start,
840 uintptr_t end) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000841 if (!log_->IsEnabled() || !FLAG_prof) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000842 Log::MessageBuilder msg(log_);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000843 msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
844 library_path,
845 start,
846 end);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000847 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000848}
849
850
851void Logger::SharedLibraryEvent(const wchar_t* library_path,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000852 uintptr_t start,
853 uintptr_t end) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000854 if (!log_->IsEnabled() || !FLAG_prof) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000855 Log::MessageBuilder msg(log_);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000856 msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
857 library_path,
858 start,
859 end);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000860 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861}
862
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000863
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +0000864void Logger::CodeDeoptEvent(Code* code) {
865 if (!log_->IsEnabled()) return;
866 ASSERT(FLAG_log_internal_timer_events);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000867 Log::MessageBuilder msg(log_);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000868 int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +0000869 msg.Append("code-deopt,%ld,%d\n", since_epoch, code->CodeSize());
870 msg.WriteToLogFile();
871}
872
873
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000874void Logger::TimerEvent(StartEnd se, const char* name) {
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000875 if (!log_->IsEnabled()) return;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000876 ASSERT(FLAG_log_internal_timer_events);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000877 Log::MessageBuilder msg(log_);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000878 int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000879 const char* format = (se == START) ? "timer-event-start,\"%s\",%ld\n"
880 : "timer-event-end,\"%s\",%ld\n";
881 msg.Append(format, name, since_epoch);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000882 msg.WriteToLogFile();
883}
884
885
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000886void Logger::EnterExternal(Isolate* isolate) {
887 LOG(isolate, TimerEvent(START, TimerEventScope::v8_external));
888 ASSERT(isolate->current_vm_state() == JS);
889 isolate->set_current_vm_state(EXTERNAL);
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000890}
891
892
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000893void Logger::LeaveExternal(Isolate* isolate) {
894 LOG(isolate, TimerEvent(END, TimerEventScope::v8_external));
895 ASSERT(isolate->current_vm_state() == EXTERNAL);
896 isolate->set_current_vm_state(JS);
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000897}
898
899
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000900void Logger::TimerEventScope::LogTimerEvent(StartEnd se) {
901 LOG(isolate_, TimerEvent(se, name_));
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000902}
903
904
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000905const char* Logger::TimerEventScope::v8_recompile_synchronous =
906 "V8.RecompileSynchronous";
rossberg@chromium.org92597162013-08-23 13:28:00 +0000907const char* Logger::TimerEventScope::v8_recompile_concurrent =
908 "V8.RecompileConcurrent";
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000909const char* Logger::TimerEventScope::v8_compile_full_code =
910 "V8.CompileFullCode";
911const char* Logger::TimerEventScope::v8_execute = "V8.Execute";
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000912const char* Logger::TimerEventScope::v8_external = "V8.External";
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000913
914
ager@chromium.org236ad962008-09-25 09:45:57 +0000915void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000916 // Prints "/" + re.source + "/" +
917 // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000918 Log::MessageBuilder msg(log_);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000919
920 Handle<Object> source = GetProperty(regexp, "source");
921 if (!source->IsString()) {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000922 msg.Append("no source");
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000923 return;
924 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000925
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000926 switch (regexp->TypeTag()) {
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000927 case JSRegExp::ATOM:
ager@chromium.org381abbb2009-02-25 13:23:22 +0000928 msg.Append('a');
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000929 break;
930 default:
931 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000932 }
ager@chromium.org381abbb2009-02-25 13:23:22 +0000933 msg.Append('/');
934 msg.AppendDetailed(*Handle<String>::cast(source), false);
935 msg.Append('/');
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000936
937 // global flag
938 Handle<Object> global = GetProperty(regexp, "global");
939 if (global->IsTrue()) {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000940 msg.Append('g');
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000941 }
942 // ignorecase flag
943 Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");
944 if (ignorecase->IsTrue()) {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000945 msg.Append('i');
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000946 }
947 // multiline flag
948 Handle<Object> multiline = GetProperty(regexp, "multiline");
949 if (multiline->IsTrue()) {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000950 msg.Append('m');
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000951 }
ager@chromium.org381abbb2009-02-25 13:23:22 +0000952
953 msg.WriteToLogFile();
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000954}
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000955
956
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000957void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000958 if (!log_->IsEnabled() || !FLAG_log_regexp) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000959 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000960 msg.Append("regexp-compile,");
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000961 LogRegExpSource(regexp);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000962 msg.Append(in_cache ? ",hit\n" : ",miss\n");
963 msg.WriteToLogFile();
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000964}
965
966
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000967void Logger::LogRuntime(Vector<const char> format,
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000968 JSArray* args) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000969 if (!log_->IsEnabled() || !FLAG_log_runtime) return;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000970 HandleScope scope(isolate_);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000971 Log::MessageBuilder msg(log_);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000972 for (int i = 0; i < format.length(); i++) {
973 char c = format[i];
974 if (c == '%' && i <= format.length() - 2) {
975 i++;
976 ASSERT('0' <= format[i] && format[i] <= '9');
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000977 MaybeObject* maybe = args->GetElement(isolate_, format[i] - '0');
lrn@chromium.org303ada72010-10-27 09:33:13 +0000978 Object* obj;
979 if (!maybe->ToObject(&obj)) {
980 msg.Append("<exception>");
981 continue;
982 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000983 i++;
984 switch (format[i]) {
985 case 's':
ager@chromium.org381abbb2009-02-25 13:23:22 +0000986 msg.AppendDetailed(String::cast(obj), false);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000987 break;
988 case 'S':
ager@chromium.org381abbb2009-02-25 13:23:22 +0000989 msg.AppendDetailed(String::cast(obj), true);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000990 break;
991 case 'r':
992 Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj)));
993 break;
994 case 'x':
ager@chromium.org381abbb2009-02-25 13:23:22 +0000995 msg.Append("0x%x", Smi::cast(obj)->value());
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000996 break;
997 case 'i':
ager@chromium.org381abbb2009-02-25 13:23:22 +0000998 msg.Append("%i", Smi::cast(obj)->value());
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000999 break;
1000 default:
1001 UNREACHABLE();
1002 }
1003 } else {
ager@chromium.org381abbb2009-02-25 13:23:22 +00001004 msg.Append(c);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001005 }
1006 }
ager@chromium.org381abbb2009-02-25 13:23:22 +00001007 msg.Append('\n');
1008 msg.WriteToLogFile();
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001009}
1010
1011
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001012void Logger::ApiIndexedSecurityCheck(uint32_t index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001013 if (!log_->IsEnabled() || !FLAG_log_api) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001014 ApiEvent("api,check-security,%u\n", index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001015}
1016
1017
1018void Logger::ApiNamedPropertyAccess(const char* tag,
1019 JSObject* holder,
1020 Object* name) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00001021 ASSERT(name->IsName());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001022 if (!log_->IsEnabled() || !FLAG_log_api) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001023 String* class_name_obj = holder->class_name();
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001024 SmartArrayPointer<char> class_name =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001025 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001026 if (name->IsString()) {
1027 SmartArrayPointer<char> property_name =
1028 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1029 ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
1030 } else {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001031 Symbol* symbol = Symbol::cast(name);
1032 uint32_t hash = symbol->Hash();
1033 if (symbol->name()->IsUndefined()) {
1034 ApiEvent("api,%s,\"%s\",symbol(hash %x)\n", tag, *class_name, hash);
1035 } else {
1036 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
1037 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1038 ApiEvent("api,%s,\"%s\",symbol(\"%s\" hash %x)\n",
1039 tag, *class_name, *str, hash);
1040 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001041 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042}
1043
1044void Logger::ApiIndexedPropertyAccess(const char* tag,
1045 JSObject* holder,
1046 uint32_t index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001047 if (!log_->IsEnabled() || !FLAG_log_api) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048 String* class_name_obj = holder->class_name();
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001049 SmartArrayPointer<char> class_name =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001050 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001051 ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052}
1053
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001054
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001056 if (!log_->IsEnabled() || !FLAG_log_api) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001057 String* class_name_obj = object->class_name();
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001058 SmartArrayPointer<char> class_name =
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001059 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001060 ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061}
1062
1063
1064void Logger::ApiEntryCall(const char* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001065 if (!log_->IsEnabled() || !FLAG_log_api) return;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001066 ApiEvent("api,%s\n", name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067}
1068
1069
1070void Logger::NewEvent(const char* name, void* object, size_t size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001071 if (!log_->IsEnabled() || !FLAG_log) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001072 Log::MessageBuilder msg(log_);
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00001073 msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
ager@chromium.org381abbb2009-02-25 13:23:22 +00001074 static_cast<unsigned int>(size));
1075 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001076}
1077
1078
1079void Logger::DeleteEvent(const char* name, void* object) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001080 if (!log_->IsEnabled() || !FLAG_log) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001081 Log::MessageBuilder msg(log_);
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00001082 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001083 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001084}
1085
1086
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001087void Logger::NewEventStatic(const char* name, void* object, size_t size) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001088 Isolate::Current()->logger()->NewEvent(name, object, size);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001089}
1090
1091
1092void Logger::DeleteEventStatic(const char* name, void* object) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001093 Isolate::Current()->logger()->DeleteEvent(name, object);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001094}
1095
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001096
ulan@chromium.org750145a2013-03-07 15:14:13 +00001097void Logger::CallbackEventInternal(const char* prefix, Name* name,
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001098 Address entry_point) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001099 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001100 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001101 msg.Append("%s,%s,-2,",
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001102 kLogEventsNames[CODE_CREATION_EVENT],
1103 kLogEventsNames[CALLBACK_TAG]);
ager@chromium.org01beca72009-11-24 14:29:16 +00001104 msg.AppendAddress(entry_point);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001105 if (name->IsString()) {
1106 SmartArrayPointer<char> str =
1107 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1108 msg.Append(",1,\"%s%s\"", prefix, *str);
1109 } else {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001110 Symbol* symbol = Symbol::cast(name);
1111 if (symbol->name()->IsUndefined()) {
1112 msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash());
1113 } else {
1114 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
1115 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1116 msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash());
1117 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001118 }
ager@chromium.org01beca72009-11-24 14:29:16 +00001119 msg.Append('\n');
1120 msg.WriteToLogFile();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001121}
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001122
1123
ulan@chromium.org750145a2013-03-07 15:14:13 +00001124void Logger::CallbackEvent(Name* name, Address entry_point) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001125 PROFILER_LOG(CallbackEvent(name, entry_point));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001126 CallbackEventInternal("", name, entry_point);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001127}
1128
1129
ulan@chromium.org750145a2013-03-07 15:14:13 +00001130void Logger::GetterCallbackEvent(Name* name, Address entry_point) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001131 PROFILER_LOG(GetterCallbackEvent(name, entry_point));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001132 CallbackEventInternal("get ", name, entry_point);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001133}
1134
1135
ulan@chromium.org750145a2013-03-07 15:14:13 +00001136void Logger::SetterCallbackEvent(Name* name, Address entry_point) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001137 PROFILER_LOG(SetterCallbackEvent(name, entry_point));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001138 CallbackEventInternal("set ", name, entry_point);
ager@chromium.org01beca72009-11-24 14:29:16 +00001139}
1140
1141
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001142static void AppendCodeCreateHeader(Log::MessageBuilder* msg,
1143 Logger::LogEventsAndTags tag,
1144 Code* code) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001145 ASSERT(msg);
1146 msg->Append("%s,%s,%d,",
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001147 kLogEventsNames[Logger::CODE_CREATION_EVENT],
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001148 kLogEventsNames[tag],
1149 code->kind());
1150 msg->AppendAddress(code->address());
1151 msg->Append(",%d,", code->ExecutableSize());
1152}
1153
1154
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001155void Logger::CodeCreateEvent(LogEventsAndTags tag,
1156 Code* code,
1157 const char* comment) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001158 PROFILER_LOG(CodeCreateEvent(tag, code, comment));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001159
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001160 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001161 CALL_LISTENERS(CodeCreateEvent(tag, code, comment));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001162
1163 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001164 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001165 AppendCodeCreateHeader(&msg, tag, code);
1166 msg.AppendDoubleQuotedString(comment);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001167 msg.Append('\n');
1168 msg.WriteToLogFile();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001169}
1170
1171
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001172void Logger::CodeCreateEvent(LogEventsAndTags tag,
1173 Code* code,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001174 Name* name) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001175 PROFILER_LOG(CodeCreateEvent(tag, code, name));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001176
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001177 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001178 CALL_LISTENERS(CodeCreateEvent(tag, code, name));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001179
1180 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001181 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001182 AppendCodeCreateHeader(&msg, tag, code);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001183 if (name->IsString()) {
1184 msg.Append('"');
1185 msg.AppendDetailed(String::cast(name), false);
1186 msg.Append('"');
1187 } else {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001188 msg.AppendSymbolName(Symbol::cast(name));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001189 }
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001190 msg.Append('\n');
1191 msg.WriteToLogFile();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001192}
1193
1194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001195void Logger::CodeCreateEvent(LogEventsAndTags tag,
1196 Code* code,
1197 SharedFunctionInfo* shared,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001198 CompilationInfo* info,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001199 Name* name) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001200 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001201
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001202 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001203 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001204
1205 if (!FLAG_log_code || !log_->IsEnabled()) return;
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00001206 if (code == isolate_->builtins()->builtin(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001207 Builtins::kLazyCompile))
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001208 return;
1209
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001210 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001211 AppendCodeCreateHeader(&msg, tag, code);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001212 if (name->IsString()) {
1213 SmartArrayPointer<char> str =
1214 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1215 msg.Append("\"%s\"", *str);
1216 } else {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001217 msg.AppendSymbolName(Symbol::cast(name));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001218 }
1219 msg.Append(',');
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001220 msg.AppendAddress(shared->address());
1221 msg.Append(",%s", ComputeMarker(code));
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001222 msg.Append('\n');
1223 msg.WriteToLogFile();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001224}
1225
1226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227// Although, it is possible to extract source and line from
1228// the SharedFunctionInfo object, we left it to caller
1229// to leave logging functions free from heap allocations.
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001230void Logger::CodeCreateEvent(LogEventsAndTags tag,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001231 Code* code,
1232 SharedFunctionInfo* shared,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001233 CompilationInfo* info,
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001234 Name* source, int line, int column) {
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +00001235 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001236
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001237 if (!is_logging_code_events()) return;
mvstanton@chromium.orgdd6d9ee2013-10-11 10:35:37 +00001238 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line,
1239 column));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001240
1241 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001242 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001243 AppendCodeCreateHeader(&msg, tag, code);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001244 SmartArrayPointer<char> name =
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001245 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001246 msg.Append("\"%s ", *name);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001247 if (source->IsString()) {
1248 SmartArrayPointer<char> sourcestr =
1249 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1250 msg.Append("%s", *sourcestr);
1251 } else {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001252 msg.AppendSymbolName(Symbol::cast(source));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001253 }
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001254 msg.Append(":%d:%d\",", line, column);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001255 msg.AppendAddress(shared->address());
1256 msg.Append(",%s", ComputeMarker(code));
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001257 msg.Append('\n');
1258 msg.WriteToLogFile();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001259}
1260
1261
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001262void Logger::CodeCreateEvent(LogEventsAndTags tag,
1263 Code* code,
1264 int args_count) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001265 PROFILER_LOG(CodeCreateEvent(tag, code, args_count));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001266
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001267 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001268 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001269
1270 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001271 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001272 AppendCodeCreateHeader(&msg, tag, code);
1273 msg.Append("\"args_count: %d\"", args_count);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001274 msg.Append('\n');
1275 msg.WriteToLogFile();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001276}
1277
1278
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001279void Logger::CodeMovingGCEvent() {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001280 PROFILER_LOG(CodeMovingGCEvent());
1281
1282 if (!is_logging_code_events()) return;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001283 if (!log_->IsEnabled() || !FLAG_ll_prof) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001284 CALL_LISTENERS(CodeMovingGCEvent());
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001285 OS::SignalCodeMovingGC();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001286}
1287
1288
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001289void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001290 PROFILER_LOG(RegExpCodeCreateEvent(code, source));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001291
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001292 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001293 CALL_LISTENERS(RegExpCodeCreateEvent(code, source));
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001294
1295 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001296 Log::MessageBuilder msg(log_);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001297 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code);
1298 msg.Append('"');
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001299 msg.AppendDetailed(source, false);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001300 msg.Append('"');
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001301 msg.Append('\n');
1302 msg.WriteToLogFile();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001303}
1304
1305
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001306void Logger::CodeMoveEvent(Address from, Address to) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001307 PROFILER_LOG(CodeMoveEvent(from, to));
1308
1309 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001310 CALL_LISTENERS(CodeMoveEvent(from, to));
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001311 MoveEventInternal(CODE_MOVE_EVENT, from, to);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001312}
1313
1314
1315void Logger::CodeDeleteEvent(Address from) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001316 PROFILER_LOG(CodeDeleteEvent(from));
1317
1318 if (!is_logging_code_events()) return;
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001319 CALL_LISTENERS(CodeDeleteEvent(from));
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001320
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001321 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001322 Log::MessageBuilder msg(log_);
1323 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]);
1324 msg.AppendAddress(from);
1325 msg.Append('\n');
1326 msg.WriteToLogFile();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001327}
1328
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001329
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001330void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
1331 int pc_offset,
1332 int position) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001333 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1334 pc_offset,
1335 position,
1336 JitCodeEvent::POSITION));
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001337}
1338
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001339
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001340void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data,
1341 int pc_offset,
1342 int position) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001343 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1344 pc_offset,
1345 position,
1346 JitCodeEvent::STATEMENT_POSITION));
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001347}
1348
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001349
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001350void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001351 if (jit_logger_ != NULL) {
1352 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent());
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001353 }
1354}
1355
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001356
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001357void Logger::CodeEndLinePosInfoRecordEvent(Code* code,
1358 void* jit_handler_data) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001359 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data));
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001360}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001361
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001362
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001363void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
1364 if (code_name == NULL) return; // Not a code object.
1365 Log::MessageBuilder msg(log_);
1366 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
1367 msg.AppendDoubleQuotedString(code_name);
1368 msg.Append("\n");
1369 msg.WriteToLogFile();
1370}
1371
1372
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001373void Logger::SnapshotPositionEvent(Address addr, int pos) {
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001374 if (!log_->IsEnabled()) return;
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001375 LL_LOG(SnapshotPositionEvent(addr, pos));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001376 if (!FLAG_log_snapshot_positions) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001377 Log::MessageBuilder msg(log_);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001378 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001379 msg.AppendAddress(addr);
1380 msg.Append(",%d", pos);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001381 msg.Append('\n');
1382 msg.WriteToLogFile();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001383}
1384
1385
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001386void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001387 PROFILER_LOG(SharedFunctionInfoMoveEvent(from, to));
1388
1389 if (!is_logging_code_events()) return;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001390 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001391}
1392
1393
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001394void Logger::MoveEventInternal(LogEventsAndTags event,
1395 Address from,
1396 Address to) {
yangguo@chromium.orgc73d55b2013-07-24 08:18:28 +00001397 if (!FLAG_log_code || !log_->IsEnabled()) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001398 Log::MessageBuilder msg(log_);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001399 msg.Append("%s,", kLogEventsNames[event]);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001400 msg.AppendAddress(from);
1401 msg.Append(',');
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001402 msg.AppendAddress(to);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001403 msg.Append('\n');
ager@chromium.org381abbb2009-02-25 13:23:22 +00001404 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001405}
1406
1407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408void Logger::ResourceEvent(const char* name, const char* tag) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001409 if (!log_->IsEnabled() || !FLAG_log) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001410 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001411 msg.Append("%s,%s,", name, tag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001412
1413 uint32_t sec, usec;
1414 if (OS::GetUserTime(&sec, &usec) != -1) {
ager@chromium.org381abbb2009-02-25 13:23:22 +00001415 msg.Append("%d,%d,", sec, usec);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416 }
ager@chromium.org381abbb2009-02-25 13:23:22 +00001417 msg.Append("%.0f", OS::TimeCurrentMillis());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418
ager@chromium.org381abbb2009-02-25 13:23:22 +00001419 msg.Append('\n');
1420 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001421}
1422
1423
ulan@chromium.org750145a2013-03-07 15:14:13 +00001424void Logger::SuspectReadEvent(Name* name, Object* obj) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001425 if (!log_->IsEnabled() || !FLAG_log_suspect) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001426 Log::MessageBuilder msg(log_);
ager@chromium.org8bb60582008-12-11 12:02:20 +00001427 String* class_name = obj->IsJSObject()
1428 ? JSObject::cast(obj)->class_name()
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001429 : isolate_->heap()->empty_string();
ager@chromium.org381abbb2009-02-25 13:23:22 +00001430 msg.Append("suspect-read,");
1431 msg.Append(class_name);
1432 msg.Append(',');
ulan@chromium.org750145a2013-03-07 15:14:13 +00001433 if (name->IsString()) {
1434 msg.Append('"');
1435 msg.Append(String::cast(name));
1436 msg.Append('"');
1437 } else {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001438 msg.AppendSymbolName(Symbol::cast(name));
ulan@chromium.org750145a2013-03-07 15:14:13 +00001439 }
ager@chromium.org381abbb2009-02-25 13:23:22 +00001440 msg.Append('\n');
1441 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442}
1443
1444
1445void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001446 if (!log_->IsEnabled() || !FLAG_log_gc) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001447 Log::MessageBuilder msg(log_);
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001448 // Using non-relative system time in order to be able to synchronize with
1449 // external memory profiling events (e.g. DOM memory size).
1450 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
1451 space, kind, OS::TimeCurrentMillis());
1452 msg.WriteToLogFile();
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001453}
1454
1455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001457 if (!log_->IsEnabled() || !FLAG_log_gc) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001458 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001459 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
1460 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461}
1462
1463
1464void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001465 if (!log_->IsEnabled() || !FLAG_log_gc) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001466 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001467 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
1468 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469}
1470
1471
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001472void Logger::DebugTag(const char* call_site_tag) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001473 if (!log_->IsEnabled() || !FLAG_log) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001474 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001475 msg.Append("debug-tag,%s\n", call_site_tag);
1476 msg.WriteToLogFile();
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001477}
1478
1479
1480void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001481 if (!log_->IsEnabled() || !FLAG_log) return;
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001482 StringBuilder s(parameter.length() + 1);
1483 for (int i = 0; i < parameter.length(); ++i) {
1484 s.AddCharacter(static_cast<char>(parameter[i]));
1485 }
1486 char* parameter_string = s.Finalize();
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001487 Log::MessageBuilder msg(log_);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001488 msg.Append("debug-queue-event,%s,%15.3f,%s\n",
1489 event_type,
1490 OS::TimeCurrentMillis(),
1491 parameter_string);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001492 DeleteArray(parameter_string);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001493 msg.WriteToLogFile();
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001494}
1495
1496
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001497void Logger::TickEvent(TickSample* sample, bool overflow) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001498 if (!log_->IsEnabled() || !FLAG_prof) return;
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001499 Log::MessageBuilder msg(log_);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001500 msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
1501 msg.AppendAddress(sample->pc);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001502 msg.Append(",%ld", static_cast<int>(timer_.Elapsed().InMicroseconds()));
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00001503 if (sample->has_external_callback) {
1504 msg.Append(",1,");
1505 msg.AppendAddress(sample->external_callback);
1506 } else {
1507 msg.Append(",0,");
1508 msg.AppendAddress(sample->tos);
1509 }
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001510 msg.Append(",%d", static_cast<int>(sample->state));
ager@chromium.org381abbb2009-02-25 13:23:22 +00001511 if (overflow) {
1512 msg.Append(",overflow");
1513 }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001514 for (int i = 0; i < sample->frames_count; ++i) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001515 msg.Append(',');
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001516 msg.AppendAddress(sample->stack[i]);
ager@chromium.org381abbb2009-02-25 13:23:22 +00001517 }
1518 msg.Append('\n');
1519 msg.WriteToLogFile();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001520}
iposva@chromium.org245aa852009-02-10 00:49:54 +00001521
1522
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001523void Logger::StopProfiler() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001524 if (!log_->IsEnabled()) return;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001525 if (profiler_ != NULL) {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001526 profiler_->pause();
1527 is_logging_ = false;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001528 }
iposva@chromium.org245aa852009-02-10 00:49:54 +00001529}
ager@chromium.org9085a012009-05-11 19:22:57 +00001530
1531
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +00001532// This function can be called when Log's mutex is acquired,
1533// either from main or Profiler's thread.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001534void Logger::LogFailure() {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001535 StopProfiler();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +00001536}
1537
1538
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
1540 public:
1541 EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis,
1542 Handle<Code>* code_objects,
1543 int* count)
1544 : sfis_(sfis), code_objects_(code_objects), count_(count) { }
1545
1546 virtual void EnterContext(Context* context) {}
1547 virtual void LeaveContext(Context* context) {}
1548
1549 virtual void VisitFunction(JSFunction* function) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00001550 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared());
1551 Object* maybe_script = sfi->script();
1552 if (maybe_script->IsScript()
1553 && !Script::cast(maybe_script)->HasValidSource()) return;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554 if (sfis_ != NULL) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00001555 sfis_[*count_] = Handle<SharedFunctionInfo>(sfi);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556 }
1557 if (code_objects_ != NULL) {
1558 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
1559 code_objects_[*count_] = Handle<Code>(function->code());
1560 }
1561 *count_ = *count_ + 1;
1562 }
1563
1564 private:
1565 Handle<SharedFunctionInfo>* sfis_;
1566 Handle<Code>* code_objects_;
1567 int* count_;
1568};
1569
1570
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001571static int EnumerateCompiledFunctions(Heap* heap,
1572 Handle<SharedFunctionInfo>* sfis,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573 Handle<Code>* code_objects) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001574 HeapIterator iterator(heap);
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001575 DisallowHeapAllocation no_gc;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001576 int compiled_funcs_count = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577
1578 // Iterate the heap to find shared function info objects and record
1579 // the unoptimized code for them.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001580 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00001581 if (!obj->IsSharedFunctionInfo()) continue;
1582 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
1583 if (sfi->is_compiled()
1584 && (!sfi->script()->IsScript()
1585 || Script::cast(sfi->script())->HasValidSource())) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 if (sfis != NULL) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00001587 sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588 }
1589 if (code_objects != NULL) {
1590 code_objects[compiled_funcs_count] = Handle<Code>(sfi->code());
1591 }
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00001592 ++compiled_funcs_count;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001593 }
1594 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595
1596 // Iterate all optimized functions in all contexts.
1597 EnumerateOptimizedFunctionsVisitor visitor(sfis,
1598 code_objects,
1599 &compiled_funcs_count);
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001600 Deoptimizer::VisitAllOptimizedFunctions(heap->isolate(), &visitor);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00001602 return compiled_funcs_count;
1603}
1604
1605
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001606void Logger::LogCodeObject(Object* object) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001607 Code* code_object = Code::cast(object);
1608 LogEventsAndTags tag = Logger::STUB_TAG;
1609 const char* description = "Unknown code from the snapshot";
1610 switch (code_object->kind()) {
1611 case Code::FUNCTION:
1612 case Code::OPTIMIZED_FUNCTION:
1613 return; // We log this later using LogCompiledFunctions.
jkummerow@chromium.org25b0e212013-10-04 15:38:52 +00001614 case Code::BINARY_OP_IC: {
1615 BinaryOpStub stub(code_object->extended_extra_ic_state());
1616 description = stub.GetName().Detach();
1617 tag = Logger::STUB_TAG;
1618 break;
1619 }
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001620 case Code::COMPARE_IC: // fall through
1621 case Code::COMPARE_NIL_IC: // fall through
1622 case Code::TO_BOOLEAN_IC: // fall through
1623 case Code::STUB:
1624 description =
1625 CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true);
1626 if (description == NULL)
1627 description = "A stub from the snapshot";
1628 tag = Logger::STUB_TAG;
1629 break;
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001630 case Code::REGEXP:
1631 description = "Regular expression code";
1632 tag = Logger::REG_EXP_TAG;
1633 break;
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001634 case Code::BUILTIN:
1635 description = "A builtin from the snapshot";
1636 tag = Logger::BUILTIN_TAG;
1637 break;
jkummerow@chromium.org32aa03c2013-10-01 08:21:50 +00001638 case Code::HANDLER:
1639 description = "An IC handler from the snapshot";
1640 tag = Logger::HANDLER_TAG;
1641 break;
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001642 case Code::KEYED_LOAD_IC:
1643 description = "A keyed load IC from the snapshot";
1644 tag = Logger::KEYED_LOAD_IC_TAG;
1645 break;
1646 case Code::LOAD_IC:
1647 description = "A load IC from the snapshot";
1648 tag = Logger::LOAD_IC_TAG;
1649 break;
1650 case Code::STORE_IC:
1651 description = "A store IC from the snapshot";
1652 tag = Logger::STORE_IC_TAG;
1653 break;
1654 case Code::KEYED_STORE_IC:
1655 description = "A keyed store IC from the snapshot";
1656 tag = Logger::KEYED_STORE_IC_TAG;
1657 break;
1658 case Code::CALL_IC:
1659 description = "A call IC from the snapshot";
1660 tag = Logger::CALL_IC_TAG;
1661 break;
1662 case Code::KEYED_CALL_IC:
1663 description = "A keyed call IC from the snapshot";
1664 tag = Logger::KEYED_CALL_IC_TAG;
1665 break;
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001666 case Code::NUMBER_OF_KINDS:
1667 break;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001668 }
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001669 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001670}
1671
1672
ager@chromium.org5c838252010-02-19 08:53:10 +00001673void Logger::LogCodeObjects() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001674 Heap* heap = isolate_->heap();
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001675 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001676 "Logger::LogCodeObjects");
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001677 HeapIterator iterator(heap);
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001678 DisallowHeapAllocation no_gc;
ager@chromium.org5c838252010-02-19 08:53:10 +00001679 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1680 if (obj->IsCode()) LogCodeObject(obj);
1681 }
1682}
1683
1684
lrn@chromium.org34e60782011-09-15 07:25:40 +00001685void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
1686 Handle<Code> code) {
1687 Handle<String> func_name(shared->DebugName());
1688 if (shared->script()->IsScript()) {
1689 Handle<Script> script(Script::cast(shared->script()));
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001690 int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001691 int column_num =
1692 GetScriptColumnNumber(script, shared->start_position()) + 1;
lrn@chromium.org34e60782011-09-15 07:25:40 +00001693 if (script->name()->IsString()) {
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001694 Handle<String> script_name(String::cast(script->name()));
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001695 if (line_num > 0) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001696 PROFILE(isolate_,
lrn@chromium.org34e60782011-09-15 07:25:40 +00001697 CodeCreateEvent(
1698 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001699 *code, *shared, NULL,
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001700 *script_name, line_num, column_num));
lrn@chromium.org34e60782011-09-15 07:25:40 +00001701 } else {
1702 // Can't distinguish eval and script here, so always use Script.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001703 PROFILE(isolate_,
lrn@chromium.org34e60782011-09-15 07:25:40 +00001704 CodeCreateEvent(
1705 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001706 *code, *shared, NULL, *script_name));
lrn@chromium.org34e60782011-09-15 07:25:40 +00001707 }
1708 } else {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001709 PROFILE(isolate_,
lrn@chromium.org34e60782011-09-15 07:25:40 +00001710 CodeCreateEvent(
1711 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001712 *code, *shared, NULL,
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001713 isolate_->heap()->empty_string(), line_num, column_num));
lrn@chromium.org34e60782011-09-15 07:25:40 +00001714 }
1715 } else if (shared->IsApiFunction()) {
1716 // API function.
1717 FunctionTemplateInfo* fun_data = shared->get_api_func_data();
1718 Object* raw_call_data = fun_data->call_code();
1719 if (!raw_call_data->IsUndefined()) {
1720 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1721 Object* callback_obj = call_data->callback();
1722 Address entry_point = v8::ToCData<Address>(callback_obj);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001723 PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
lrn@chromium.org34e60782011-09-15 07:25:40 +00001724 }
1725 } else {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001726 PROFILE(isolate_,
lrn@chromium.org34e60782011-09-15 07:25:40 +00001727 CodeCreateEvent(
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001728 Logger::LAZY_COMPILE_TAG, *code, *shared, NULL, *func_name));
lrn@chromium.org34e60782011-09-15 07:25:40 +00001729 }
1730}
1731
1732
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00001733void Logger::LogCompiledFunctions() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001734 Heap* heap = isolate_->heap();
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001735 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001736 "Logger::LogCompiledFunctions");
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001737 HandleScope scope(isolate_);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001738 const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001739 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001741 EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start());
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001742
1743 // During iteration, there can be heap allocation due to
1744 // GetScriptLineNumber call.
1745 for (int i = 0; i < compiled_funcs_count; ++i) {
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00001746 if (*code_objects[i] == isolate_->builtins()->builtin(
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001747 Builtins::kLazyCompile))
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001748 continue;
lrn@chromium.org34e60782011-09-15 07:25:40 +00001749 LogExistingFunction(sfis[i], code_objects[i]);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001750 }
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001751}
1752
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001753
1754void Logger::LogAccessorCallbacks() {
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001755 Heap* heap = isolate_->heap();
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001756 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001757 "Logger::LogAccessorCallbacks");
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001758 HeapIterator iterator(heap);
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001759 DisallowHeapAllocation no_gc;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001760 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001761 if (!obj->IsExecutableAccessorInfo()) continue;
1762 ExecutableAccessorInfo* ai = ExecutableAccessorInfo::cast(obj);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001763 if (!ai->name()->IsName()) continue;
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001764 Address getter_entry = v8::ToCData<Address>(ai->getter());
ulan@chromium.org750145a2013-03-07 15:14:13 +00001765 Name* name = Name::cast(ai->name());
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001766 if (getter_entry != 0) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001767 PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001768 }
1769 Address setter_entry = v8::ToCData<Address>(ai->setter());
1770 if (setter_entry != 0) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001771 PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001772 }
1773 }
1774}
1775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001777static void AddIsolateIdIfNeeded(Isolate* isolate, StringStream* stream) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00001778 if (isolate->IsDefaultIsolate() || !FLAG_logfile_per_isolate) return;
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001779 stream->Add("isolate-%p-", isolate);
1780}
1781
1782
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001783static SmartArrayPointer<const char> PrepareLogFileName(
1784 Isolate* isolate, const char* file_name) {
machenbach@chromium.org528ce022013-09-23 14:09:36 +00001785 if (strchr(file_name, '%') != NULL || !isolate->IsDefaultIsolate()) {
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001786 // If there's a '%' in the log file name we have to expand
1787 // placeholders.
1788 HeapStringAllocator allocator;
1789 StringStream stream(&allocator);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001790 AddIsolateIdIfNeeded(isolate, &stream);
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001791 for (const char* p = file_name; *p; p++) {
1792 if (*p == '%') {
1793 p++;
1794 switch (*p) {
1795 case '\0':
1796 // If there's a % at the end of the string we back up
1797 // one character so we can escape the loop properly.
1798 p--;
1799 break;
1800 case 'p':
1801 stream.Add("%d", OS::GetCurrentProcessId());
1802 break;
1803 case 't': {
1804 // %t expands to the current time in milliseconds.
1805 double time = OS::TimeCurrentMillis();
1806 stream.Add("%.0f", FmtElm(time));
1807 break;
1808 }
1809 case '%':
1810 // %% expands (contracts really) to %.
1811 stream.Put('%');
1812 break;
1813 default:
1814 // All other %'s expand to themselves.
1815 stream.Put('%');
1816 stream.Put(*p);
1817 break;
1818 }
1819 } else {
1820 stream.Put(*p);
1821 }
1822 }
1823 return SmartArrayPointer<const char>(stream.ToCString());
1824 }
1825 int length = StrLength(file_name);
1826 char* str = NewArray<char>(length + 1);
1827 OS::MemCopy(str, file_name, length);
1828 str[length] = '\0';
1829 return SmartArrayPointer<const char>(str);
1830}
1831
1832
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001833bool Logger::SetUp(Isolate* isolate) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001834 // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
1835 if (is_initialized_) return true;
1836 is_initialized_ = true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001838 // --ll-prof implies --log-code and --log-snapshot-positions.
1839 if (FLAG_ll_prof) {
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001840 FLAG_log_snapshot_positions = true;
1841 }
1842
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001843 SmartArrayPointer<const char> log_file_name =
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001844 PrepareLogFileName(isolate, FLAG_logfile);
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001845 log_->Initialize(*log_file_name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001847 if (FLAG_ll_prof) {
1848 ll_logger_ = new LowLevelLogger(*log_file_name);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001849 addCodeEventListener(ll_logger_);
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001850 }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001851
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001852 ticker_ = new Ticker(isolate, kSamplingIntervalMs);
1853
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001854 if (Log::InitLogAtStart()) {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001855 is_logging_ = true;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001856 }
ager@chromium.org3e875802009-06-29 08:26:34 +00001857
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001858 if (FLAG_prof) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001859 profiler_ = new Profiler(isolate);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001860 is_logging_ = true;
1861 profiler_->Engage();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862 }
1863
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001864 if (FLAG_log_internal_timer_events || FLAG_prof) timer_.Start();
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001865
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001866 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001867}
1868
1869
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001870void Logger::SetCodeEventHandler(uint32_t options,
1871 JitCodeEventHandler event_handler) {
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001872 if (jit_logger_) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001873 removeCodeEventListener(jit_logger_);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001874 delete jit_logger_;
1875 jit_logger_ = NULL;
1876 }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001877
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001878 if (event_handler) {
1879 jit_logger_ = new JitLogger(event_handler);
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001880 addCodeEventListener(jit_logger_);
1881 if (options & kJitCodeEventEnumExisting) {
1882 HandleScope scope(isolate_);
1883 LogCodeObjects();
1884 LogCompiledFunctions();
1885 }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001886 }
1887}
1888
1889
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001890Sampler* Logger::sampler() {
1891 return ticker_;
1892}
1893
1894
whesse@chromium.org030d38e2011-07-13 13:23:34 +00001895FILE* Logger::TearDown() {
1896 if (!is_initialized_) return NULL;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001897 is_initialized_ = false;
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +00001898
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001899 // Stop the profiler before closing the file.
1900 if (profiler_ != NULL) {
1901 profiler_->Disengage();
1902 delete profiler_;
1903 profiler_ = NULL;
1904 }
1905
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906 delete ticker_;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001907 ticker_ = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001909 if (ll_logger_) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001910 removeCodeEventListener(ll_logger_);
jkummerow@chromium.org10480472013-07-17 08:22:15 +00001911 delete ll_logger_;
1912 ll_logger_ = NULL;
1913 }
1914
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001915 if (jit_logger_) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +00001916 removeCodeEventListener(jit_logger_);
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +00001917 delete jit_logger_;
1918 jit_logger_ = NULL;
1919 }
1920
whesse@chromium.org030d38e2011-07-13 13:23:34 +00001921 return log_->Close();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922}
1923
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924} } // namespace v8::internal