Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Side by Side Diff: src/log.cc

Issue 139973004: A64: Synchronize with r15814. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/log.h ('k') | src/log-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 17 matching lines...) Expand all
28 #include <stdarg.h> 28 #include <stdarg.h>
29 29
30 #include "v8.h" 30 #include "v8.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "cpu-profiler.h" 34 #include "cpu-profiler.h"
35 #include "deoptimizer.h" 35 #include "deoptimizer.h"
36 #include "global-handles.h" 36 #include "global-handles.h"
37 #include "log.h" 37 #include "log.h"
38 #include "log-utils.h"
38 #include "macro-assembler.h" 39 #include "macro-assembler.h"
39 #include "platform.h" 40 #include "platform.h"
40 #include "runtime-profiler.h" 41 #include "runtime-profiler.h"
41 #include "serialize.h" 42 #include "serialize.h"
42 #include "string-stream.h" 43 #include "string-stream.h"
43 #include "vm-state-inl.h" 44 #include "vm-state-inl.h"
44 45
45 namespace v8 { 46 namespace v8 {
46 namespace internal { 47 namespace internal {
47 48
48 49
50 #define DECLARE_EVENT(ignore1, name) name,
51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
53 };
54 #undef DECLARE_EVENT
55
56
57 // ComputeMarker must only be used when SharedFunctionInfo is known.
58 static const char* ComputeMarker(Code* code) {
59 switch (code->kind()) {
60 case Code::FUNCTION: return code->optimizable() ? "~" : "";
61 case Code::OPTIMIZED_FUNCTION: return "*";
62 default: return "";
63 }
64 }
65
66
67 class CodeEventLogger {
68 public:
69 virtual ~CodeEventLogger() { }
70
71 void CodeCreateEvent(Logger::LogEventsAndTags tag,
72 Code* code,
73 const char* comment);
74 void CodeCreateEvent(Logger::LogEventsAndTags tag,
75 Code* code,
76 Name* name);
77 void CodeCreateEvent(Logger::LogEventsAndTags tag,
78 Code* code,
79 int args_count);
80 void CodeCreateEvent(Logger::LogEventsAndTags tag,
81 Code* code,
82 SharedFunctionInfo* shared,
83 CompilationInfo* info,
84 Name* name);
85 void CodeCreateEvent(Logger::LogEventsAndTags tag,
86 Code* code,
87 SharedFunctionInfo* shared,
88 CompilationInfo* info,
89 Name* source,
90 int line);
91 void RegExpCodeCreateEvent(Code* code, String* source);
92
93 protected:
94 class NameBuffer {
95 public:
96 NameBuffer() { Reset(); }
97
98 void Reset() {
99 utf8_pos_ = 0;
100 }
101
102 void Init(Logger::LogEventsAndTags tag) {
103 Reset();
104 AppendBytes(kLogEventsNames[tag]);
105 AppendByte(':');
106 }
107
108 void AppendName(Name* name) {
109 if (name->IsString()) {
110 AppendString(String::cast(name));
111 } else {
112 Symbol* symbol = Symbol::cast(name);
113 AppendBytes("symbol(");
114 if (!symbol->name()->IsUndefined()) {
115 AppendBytes("\"");
116 AppendString(String::cast(symbol->name()));
117 AppendBytes("\" ");
118 }
119 AppendBytes("hash ");
120 AppendHex(symbol->Hash());
121 AppendByte(')');
122 }
123 }
124
125 void AppendString(String* str) {
126 if (str == NULL) return;
127 int uc16_length = Min(str->length(), kUtf16BufferSize);
128 String::WriteToFlat(str, utf16_buffer, 0, uc16_length);
129 int previous = unibrow::Utf16::kNoPreviousCharacter;
130 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
131 uc16 c = utf16_buffer[i];
132 if (c <= unibrow::Utf8::kMaxOneByteChar) {
133 utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
134 } else {
135 int char_length = unibrow::Utf8::Length(c, previous);
136 if (utf8_pos_ + char_length > kUtf8BufferSize) break;
137 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous);
138 utf8_pos_ += char_length;
139 }
140 previous = c;
141 }
142 }
143
144 void AppendBytes(const char* bytes, int size) {
145 size = Min(size, kUtf8BufferSize - utf8_pos_);
146 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
147 utf8_pos_ += size;
148 }
149
150 void AppendBytes(const char* bytes) {
151 AppendBytes(bytes, StrLength(bytes));
152 }
153
154 void AppendByte(char c) {
155 if (utf8_pos_ >= kUtf8BufferSize) return;
156 utf8_buffer_[utf8_pos_++] = c;
157 }
158
159 void AppendInt(int n) {
160 Vector<char> buffer(utf8_buffer_ + utf8_pos_,
161 kUtf8BufferSize - utf8_pos_);
162 int size = OS::SNPrintF(buffer, "%d", n);
163 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
164 utf8_pos_ += size;
165 }
166 }
167
168 void AppendHex(uint32_t n) {
169 Vector<char> buffer(utf8_buffer_ + utf8_pos_,
170 kUtf8BufferSize - utf8_pos_);
171 int size = OS::SNPrintF(buffer, "%x", n);
172 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
173 utf8_pos_ += size;
174 }
175 }
176
177 const char* get() { return utf8_buffer_; }
178 int size() const { return utf8_pos_; }
179
180 private:
181 static const int kUtf8BufferSize = 512;
182 static const int kUtf16BufferSize = 128;
183
184 int utf8_pos_;
185 char utf8_buffer_[kUtf8BufferSize];
186 uc16 utf16_buffer[kUtf16BufferSize];
187 };
188
189 private:
190 virtual void LogRecordedBuffer(Code* code,
191 SharedFunctionInfo* shared,
192 NameBuffer* name_buffer) = 0;
193
194 NameBuffer name_buffer_;
195 };
196
197
198 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
199 Code* code,
200 const char* comment) {
201 name_buffer_.Init(tag);
202 name_buffer_.AppendBytes(comment);
203 LogRecordedBuffer(code, NULL, &name_buffer_);
204 }
205
206
207 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
208 Code* code,
209 Name* name) {
210 name_buffer_.Init(tag);
211 name_buffer_.AppendName(name);
212 LogRecordedBuffer(code, NULL, &name_buffer_);
213 }
214
215
216 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
217 Code* code,
218 SharedFunctionInfo* shared,
219 CompilationInfo* info,
220 Name* name) {
221 name_buffer_.Init(tag);
222 name_buffer_.AppendBytes(ComputeMarker(code));
223 name_buffer_.AppendName(name);
224 LogRecordedBuffer(code, shared, &name_buffer_);
225 }
226
227
228 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
229 Code* code,
230 SharedFunctionInfo* shared,
231 CompilationInfo* info,
232 Name* source, int line) {
233 name_buffer_.Init(tag);
234 name_buffer_.AppendBytes(ComputeMarker(code));
235 name_buffer_.AppendString(shared->DebugName());
236 name_buffer_.AppendByte(' ');
237 if (source->IsString()) {
238 name_buffer_.AppendString(String::cast(source));
239 } else {
240 name_buffer_.AppendBytes("symbol(hash ");
241 name_buffer_.AppendHex(Name::cast(source)->Hash());
242 name_buffer_.AppendByte(')');
243 }
244 name_buffer_.AppendByte(':');
245 name_buffer_.AppendInt(line);
246 LogRecordedBuffer(code, shared, &name_buffer_);
247 }
248
249
250 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
251 Code* code,
252 int args_count) {
253 name_buffer_.Init(tag);
254 name_buffer_.AppendInt(args_count);
255 LogRecordedBuffer(code, NULL, &name_buffer_);
256 }
257
258
259 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) {
260 name_buffer_.Init(Logger::REG_EXP_TAG);
261 name_buffer_.AppendString(source);
262 LogRecordedBuffer(code, NULL, &name_buffer_);
263 }
264
265
49 // Low-level logging support. 266 // Low-level logging support.
50 class LowLevelLogger { 267 class LowLevelLogger : public CodeEventLogger {
51 public: 268 public:
52 explicit LowLevelLogger(const char* file_name); 269 explicit LowLevelLogger(const char* file_name);
53 ~LowLevelLogger(); 270 virtual ~LowLevelLogger();
54 271
55 void CodeCreateEvent(Code* code, const char* name, int name_size);
56 void CodeMoveEvent(Address from, Address to); 272 void CodeMoveEvent(Address from, Address to);
57 void CodeDeleteEvent(Address from); 273 void CodeDeleteEvent(Address from);
58 void SnapshotPositionEvent(Address addr, int pos); 274 void SnapshotPositionEvent(Address addr, int pos);
59 void CodeMovingGCEvent(); 275 void CodeMovingGCEvent();
60 276
61 private: 277 private:
278 virtual void LogRecordedBuffer(Code* code,
279 SharedFunctionInfo* shared,
280 NameBuffer* name_buffer);
281
62 // Low-level profiling event structures. 282 // Low-level profiling event structures.
63
64 struct CodeCreateStruct { 283 struct CodeCreateStruct {
65 static const char kTag = 'C'; 284 static const char kTag = 'C';
66 285
67 int32_t name_size; 286 int32_t name_size;
68 Address code_address; 287 Address code_address;
69 int32_t code_size; 288 int32_t code_size;
70 }; 289 };
71 290
72 291
73 struct CodeMoveStruct { 292 struct CodeMoveStruct {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 char tag = T::kTag; 330 char tag = T::kTag;
112 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag)); 331 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
113 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s)); 332 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
114 } 333 }
115 334
116 FILE* ll_output_handle_; 335 FILE* ll_output_handle_;
117 }; 336 };
118 337
119 const char LowLevelLogger::kLogExt[] = ".ll"; 338 const char LowLevelLogger::kLogExt[] = ".ll";
120 339
340 LowLevelLogger::LowLevelLogger(const char* name)
341 : ll_output_handle_(NULL) {
342 // Open the low-level log file.
343 size_t len = strlen(name);
344 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
345 OS::MemCopy(ll_name.start(), name, len);
346 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt));
347 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
348 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize);
349
350 LogCodeInfo();
351 }
352
353
354 LowLevelLogger::~LowLevelLogger() {
355 fclose(ll_output_handle_);
356 ll_output_handle_ = NULL;
357 }
358
359
360 void LowLevelLogger::LogCodeInfo() {
361 #if V8_TARGET_ARCH_IA32
362 const char arch[] = "ia32";
363 #elif V8_TARGET_ARCH_X64
364 const char arch[] = "x64";
365 #elif V8_TARGET_ARCH_ARM
366 const char arch[] = "arm";
367 #elif V8_TARGET_ARCH_MIPS
368 const char arch[] = "mips";
369 #else
370 const char arch[] = "unknown";
371 #endif
372 LogWriteBytes(arch, sizeof(arch));
373 }
374
375
376 void LowLevelLogger::LogRecordedBuffer(Code* code,
377 SharedFunctionInfo*,
378 NameBuffer* name_buffer) {
379 CodeCreateStruct event;
380 event.name_size = name_buffer->size();
381 event.code_address = code->instruction_start();
382 ASSERT(event.code_address == code->address() + Code::kHeaderSize);
383 event.code_size = code->instruction_size();
384 LogWriteStruct(event);
385 LogWriteBytes(name_buffer->get(), name_buffer->size());
386 LogWriteBytes(
387 reinterpret_cast<const char*>(code->instruction_start()),
388 code->instruction_size());
389 }
390
391
392 void LowLevelLogger::CodeMoveEvent(Address from, Address to) {
393 CodeMoveStruct event;
394 event.from_address = from + Code::kHeaderSize;
395 event.to_address = to + Code::kHeaderSize;
396 LogWriteStruct(event);
397 }
398
399
400 void LowLevelLogger::CodeDeleteEvent(Address from) {
401 CodeDeleteStruct event;
402 event.address = from + Code::kHeaderSize;
403 LogWriteStruct(event);
404 }
405
406
407 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) {
408 SnapshotPositionStruct event;
409 event.address = addr + Code::kHeaderSize;
410 event.position = pos;
411 LogWriteStruct(event);
412 }
413
414
415 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
416 size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
417 ASSERT(static_cast<size_t>(size) == rv);
418 USE(rv);
419 }
420
421
422 void LowLevelLogger::CodeMovingGCEvent() {
423 const char tag = kCodeMovingGCTag;
424
425 LogWriteBytes(&tag, sizeof(tag));
426 }
427
428
121 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; 429 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call;
122 430
123 431
432 class CodeAddressMap: public CodeEventLogger {
433 public:
434 CodeAddressMap() { }
435 virtual ~CodeAddressMap() { }
436
437 void CodeMoveEvent(Address from, Address to) {
438 address_to_name_map_.Move(from, to);
439 }
440
441 void CodeDeleteEvent(Address from) {
442 address_to_name_map_.Remove(from);
443 }
444
445 const char* Lookup(Address address) {
446 return address_to_name_map_.Lookup(address);
447 }
448
449 private:
450 class NameMap {
451 public:
452 NameMap() : impl_(&PointerEquals) {}
453
454 ~NameMap() {
455 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
456 DeleteArray(static_cast<const char*>(p->value));
457 }
458 }
459
460 void Insert(Address code_address, const char* name, int name_size) {
461 HashMap::Entry* entry = FindOrCreateEntry(code_address);
462 if (entry->value == NULL) {
463 entry->value = CopyName(name, name_size);
464 }
465 }
466
467 const char* Lookup(Address code_address) {
468 HashMap::Entry* entry = FindEntry(code_address);
469 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
470 }
471
472 void Remove(Address code_address) {
473 HashMap::Entry* entry = FindEntry(code_address);
474 if (entry != NULL) {
475 DeleteArray(static_cast<char*>(entry->value));
476 RemoveEntry(entry);
477 }
478 }
479
480 void Move(Address from, Address to) {
481 if (from == to) return;
482 HashMap::Entry* from_entry = FindEntry(from);
483 ASSERT(from_entry != NULL);
484 void* value = from_entry->value;
485 RemoveEntry(from_entry);
486 HashMap::Entry* to_entry = FindOrCreateEntry(to);
487 ASSERT(to_entry->value == NULL);
488 to_entry->value = value;
489 }
490
491 private:
492 static bool PointerEquals(void* lhs, void* rhs) {
493 return lhs == rhs;
494 }
495
496 static char* CopyName(const char* name, int name_size) {
497 char* result = NewArray<char>(name_size + 1);
498 for (int i = 0; i < name_size; ++i) {
499 char c = name[i];
500 if (c == '\0') c = ' ';
501 result[i] = c;
502 }
503 result[name_size] = '\0';
504 return result;
505 }
506
507 HashMap::Entry* FindOrCreateEntry(Address code_address) {
508 return impl_.Lookup(code_address, ComputePointerHash(code_address), true);
509 }
510
511 HashMap::Entry* FindEntry(Address code_address) {
512 return impl_.Lookup(code_address,
513 ComputePointerHash(code_address),
514 false);
515 }
516
517 void RemoveEntry(HashMap::Entry* entry) {
518 impl_.Remove(entry->key, entry->hash);
519 }
520
521 HashMap impl_;
522
523 DISALLOW_COPY_AND_ASSIGN(NameMap);
524 };
525
526 virtual void LogRecordedBuffer(Code* code,
527 SharedFunctionInfo*,
528 NameBuffer* name_buffer) {
529 address_to_name_map_.Insert(code->address(),
530 name_buffer->get(),
531 name_buffer->size());
532 }
533
534 NameMap address_to_name_map_;
535 };
536
537
538 #define CODE_ADDRESS_MAP_LOG(Call)\
539 if (Serializer::enabled()) code_address_map_->Call;
540
541
542 class JitLogger : public CodeEventLogger {
543 public:
544 explicit JitLogger(JitCodeEventHandler code_event_handler);
545
546 void CodeMovedEvent(Address from, Address to);
547 void CodeDeleteEvent(Address from);
548 void AddCodeLinePosInfoEvent(
549 void* jit_handler_data,
550 int pc_offset,
551 int position,
552 JitCodeEvent::PositionType position_type);
553 void* StartCodePosInfoEvent();
554 void EndCodePosInfoEvent(Code* code, void* jit_handler_data);
555
556 private:
557 virtual void LogRecordedBuffer(Code* code,
558 SharedFunctionInfo* shared,
559 CodeEventLogger::NameBuffer* name_buffer);
560
561 JitCodeEventHandler code_event_handler_;
562 };
563
564 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call;
565
566
567 JitLogger::JitLogger(JitCodeEventHandler code_event_handler)
568 : code_event_handler_(code_event_handler) {
569 }
570
571
572 void JitLogger::LogRecordedBuffer(Code* code,
573 SharedFunctionInfo* shared,
574 CodeEventLogger::NameBuffer* name_buffer) {
575 JitCodeEvent event;
576 memset(&event, 0, sizeof(event));
577 event.type = JitCodeEvent::CODE_ADDED;
578 event.code_start = code->instruction_start();
579 event.code_len = code->instruction_size();
580 Handle<Script> script_handle;
581 if (shared && shared->script()->IsScript()) {
582 script_handle = Handle<Script>(Script::cast(shared->script()));
583 }
584 event.script = ToApiHandle<v8::Script>(script_handle);
585 event.name.str = name_buffer->get();
586 event.name.len = name_buffer->size();
587 code_event_handler_(&event);
588 }
589
590
591 void JitLogger::CodeMovedEvent(Address from, Address to) {
592 Code* from_code = Code::cast(HeapObject::FromAddress(from));
593
594 JitCodeEvent event;
595 event.type = JitCodeEvent::CODE_MOVED;
596 event.code_start = from_code->instruction_start();
597 event.code_len = from_code->instruction_size();
598
599 // Calculate the header size.
600 const size_t header_size =
601 from_code->instruction_start() - reinterpret_cast<byte*>(from_code);
602
603 // Calculate the new start address of the instructions.
604 event.new_code_start =
605 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size;
606
607 code_event_handler_(&event);
608 }
609
610
611 void JitLogger::CodeDeleteEvent(Address from) {
612 Code* from_code = Code::cast(HeapObject::FromAddress(from));
613
614 JitCodeEvent event;
615 event.type = JitCodeEvent::CODE_REMOVED;
616 event.code_start = from_code->instruction_start();
617 event.code_len = from_code->instruction_size();
618
619 code_event_handler_(&event);
620 }
621
622 void JitLogger::AddCodeLinePosInfoEvent(
623 void* jit_handler_data,
624 int pc_offset,
625 int position,
626 JitCodeEvent::PositionType position_type) {
627 JitCodeEvent event;
628 memset(&event, 0, sizeof(event));
629 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO;
630 event.user_data = jit_handler_data;
631 event.line_info.offset = pc_offset;
632 event.line_info.pos = position;
633 event.line_info.position_type = position_type;
634
635 code_event_handler_(&event);
636 }
637
638
639 void* JitLogger::StartCodePosInfoEvent() {
640 JitCodeEvent event;
641 memset(&event, 0, sizeof(event));
642 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING;
643
644 code_event_handler_(&event);
645 return event.user_data;
646 }
647
648
649 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) {
650 JitCodeEvent event;
651 memset(&event, 0, sizeof(event));
652 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING;
653 event.code_start = code->instruction_start();
654 event.user_data = jit_handler_data;
655
656 code_event_handler_(&event);
657 }
658
659
124 // The Profiler samples pc and sp values for the main thread. 660 // The Profiler samples pc and sp values for the main thread.
125 // Each sample is appended to a circular buffer. 661 // Each sample is appended to a circular buffer.
126 // An independent thread removes data and writes it to the log. 662 // An independent thread removes data and writes it to the log.
127 // This design minimizes the time spent in the sampler. 663 // This design minimizes the time spent in the sampler.
128 // 664 //
129 class Profiler: public Thread { 665 class Profiler: public Thread {
130 public: 666 public:
131 explicit Profiler(Isolate* isolate); 667 explicit Profiler(Isolate* isolate);
132 void Engage(); 668 void Engage();
133 void Disengage(); 669 void Disengage();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 LOG(isolate_, TickEvent(&sample, overflow)); 819 LOG(isolate_, TickEvent(&sample, overflow));
284 overflow = Remove(&sample); 820 overflow = Remove(&sample);
285 } 821 }
286 } 822 }
287 823
288 824
289 // 825 //
290 // Logger class implementation. 826 // Logger class implementation.
291 // 827 //
292 828
293 class Logger::NameMap {
294 public:
295 NameMap() : impl_(&PointerEquals) {}
296
297 ~NameMap() {
298 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
299 DeleteArray(static_cast<const char*>(p->value));
300 }
301 }
302
303 void Insert(Address code_address, const char* name, int name_size) {
304 HashMap::Entry* entry = FindOrCreateEntry(code_address);
305 if (entry->value == NULL) {
306 entry->value = CopyName(name, name_size);
307 }
308 }
309
310 const char* Lookup(Address code_address) {
311 HashMap::Entry* entry = FindEntry(code_address);
312 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
313 }
314
315 void Remove(Address code_address) {
316 HashMap::Entry* entry = FindEntry(code_address);
317 if (entry != NULL) {
318 DeleteArray(static_cast<char*>(entry->value));
319 RemoveEntry(entry);
320 }
321 }
322
323 void Move(Address from, Address to) {
324 if (from == to) return;
325 HashMap::Entry* from_entry = FindEntry(from);
326 ASSERT(from_entry != NULL);
327 void* value = from_entry->value;
328 RemoveEntry(from_entry);
329 HashMap::Entry* to_entry = FindOrCreateEntry(to);
330 ASSERT(to_entry->value == NULL);
331 to_entry->value = value;
332 }
333
334 private:
335 static bool PointerEquals(void* lhs, void* rhs) {
336 return lhs == rhs;
337 }
338
339 static char* CopyName(const char* name, int name_size) {
340 char* result = NewArray<char>(name_size + 1);
341 for (int i = 0; i < name_size; ++i) {
342 char c = name[i];
343 if (c == '\0') c = ' ';
344 result[i] = c;
345 }
346 result[name_size] = '\0';
347 return result;
348 }
349
350 HashMap::Entry* FindOrCreateEntry(Address code_address) {
351 return impl_.Lookup(code_address, ComputePointerHash(code_address), true);
352 }
353
354 HashMap::Entry* FindEntry(Address code_address) {
355 return impl_.Lookup(code_address, ComputePointerHash(code_address), false);
356 }
357
358 void RemoveEntry(HashMap::Entry* entry) {
359 impl_.Remove(entry->key, entry->hash);
360 }
361
362 HashMap impl_;
363
364 DISALLOW_COPY_AND_ASSIGN(NameMap);
365 };
366
367
368 class Logger::NameBuffer {
369 public:
370 NameBuffer() { Reset(); }
371
372 void Reset() {
373 utf8_pos_ = 0;
374 }
375
376 void AppendString(String* str) {
377 if (str == NULL) return;
378 int uc16_length = Min(str->length(), kUtf16BufferSize);
379 String::WriteToFlat(str, utf16_buffer, 0, uc16_length);
380 int previous = unibrow::Utf16::kNoPreviousCharacter;
381 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
382 uc16 c = utf16_buffer[i];
383 if (c <= unibrow::Utf8::kMaxOneByteChar) {
384 utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
385 } else {
386 int char_length = unibrow::Utf8::Length(c, previous);
387 if (utf8_pos_ + char_length > kUtf8BufferSize) break;
388 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous);
389 utf8_pos_ += char_length;
390 }
391 previous = c;
392 }
393 }
394
395 void AppendBytes(const char* bytes, int size) {
396 size = Min(size, kUtf8BufferSize - utf8_pos_);
397 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
398 utf8_pos_ += size;
399 }
400
401 void AppendBytes(const char* bytes) {
402 AppendBytes(bytes, StrLength(bytes));
403 }
404
405 void AppendByte(char c) {
406 if (utf8_pos_ >= kUtf8BufferSize) return;
407 utf8_buffer_[utf8_pos_++] = c;
408 }
409
410 void AppendInt(int n) {
411 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_);
412 int size = OS::SNPrintF(buffer, "%d", n);
413 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
414 utf8_pos_ += size;
415 }
416 }
417
418 void AppendHex(uint32_t n) {
419 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_);
420 int size = OS::SNPrintF(buffer, "%x", n);
421 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
422 utf8_pos_ += size;
423 }
424 }
425
426 const char* get() { return utf8_buffer_; }
427 int size() const { return utf8_pos_; }
428
429 private:
430 static const int kUtf8BufferSize = 512;
431 static const int kUtf16BufferSize = 128;
432
433 int utf8_pos_;
434 char utf8_buffer_[kUtf8BufferSize];
435 uc16 utf16_buffer[kUtf16BufferSize];
436 };
437
438
439 Logger::Logger(Isolate* isolate) 829 Logger::Logger(Isolate* isolate)
440 : isolate_(isolate), 830 : isolate_(isolate),
441 ticker_(NULL), 831 ticker_(NULL),
442 profiler_(NULL), 832 profiler_(NULL),
443 log_events_(NULL), 833 log_events_(NULL),
444 logging_nesting_(0), 834 logging_nesting_(0),
445 cpu_profiler_nesting_(0), 835 cpu_profiler_nesting_(0),
446 log_(new Log(this)), 836 log_(new Log(this)),
447 ll_logger_(NULL), 837 ll_logger_(NULL),
448 name_buffer_(new NameBuffer), 838 jit_logger_(NULL),
449 address_to_name_map_(NULL), 839 code_address_map_(new CodeAddressMap),
450 is_initialized_(false), 840 is_initialized_(false),
451 code_event_handler_(NULL),
452 last_address_(NULL), 841 last_address_(NULL),
453 prev_sp_(NULL), 842 prev_sp_(NULL),
454 prev_function_(NULL), 843 prev_function_(NULL),
455 prev_to_(NULL), 844 prev_to_(NULL),
456 prev_code_(NULL), 845 prev_code_(NULL),
457 epoch_(0) { 846 epoch_(0) {
458 } 847 }
459 848
460 849
461 Logger::~Logger() { 850 Logger::~Logger() {
462 delete address_to_name_map_; 851 delete code_address_map_;
463 delete name_buffer_;
464 delete log_; 852 delete log_;
465 } 853 }
466 854
467 855
468 void Logger::IssueCodeAddedEvent(Code* code,
469 Script* script,
470 const char* name,
471 size_t name_len) {
472 JitCodeEvent event;
473 memset(&event, 0, sizeof(event));
474 event.type = JitCodeEvent::CODE_ADDED;
475 event.code_start = code->instruction_start();
476 event.code_len = code->instruction_size();
477 Handle<Script> script_handle =
478 script != NULL ? Handle<Script>(script) : Handle<Script>();
479 event.script = ToApiHandle<v8::Script>(script_handle);
480 event.name.str = name;
481 event.name.len = name_len;
482
483 code_event_handler_(&event);
484 }
485
486
487 void Logger::IssueCodeMovedEvent(Address from, Address to) {
488 Code* from_code = Code::cast(HeapObject::FromAddress(from));
489
490 JitCodeEvent event;
491 event.type = JitCodeEvent::CODE_MOVED;
492 event.code_start = from_code->instruction_start();
493 event.code_len = from_code->instruction_size();
494
495 // Calculate the header size.
496 const size_t header_size =
497 from_code->instruction_start() - reinterpret_cast<byte*>(from_code);
498
499 // Calculate the new start address of the instructions.
500 event.new_code_start =
501 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size;
502
503 code_event_handler_(&event);
504 }
505
506
507 void Logger::IssueCodeRemovedEvent(Address from) {
508 Code* from_code = Code::cast(HeapObject::FromAddress(from));
509
510 JitCodeEvent event;
511 event.type = JitCodeEvent::CODE_REMOVED;
512 event.code_start = from_code->instruction_start();
513 event.code_len = from_code->instruction_size();
514
515 code_event_handler_(&event);
516 }
517
518 void Logger::IssueAddCodeLinePosInfoEvent(
519 void* jit_handler_data,
520 int pc_offset,
521 int position,
522 JitCodeEvent::PositionType position_type) {
523 JitCodeEvent event;
524 memset(&event, 0, sizeof(event));
525 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO;
526 event.user_data = jit_handler_data;
527 event.line_info.offset = pc_offset;
528 event.line_info.pos = position;
529 event.line_info.position_type = position_type;
530
531 code_event_handler_(&event);
532 }
533
534
535 void* Logger::IssueStartCodePosInfoEvent() {
536 JitCodeEvent event;
537 memset(&event, 0, sizeof(event));
538 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING;
539
540 code_event_handler_(&event);
541 return event.user_data;
542 }
543
544
545 void Logger::IssueEndCodePosInfoEvent(Code* code, void* jit_handler_data) {
546 JitCodeEvent event;
547 memset(&event, 0, sizeof(event));
548 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING;
549 event.code_start = code->instruction_start();
550 event.user_data = jit_handler_data;
551
552 code_event_handler_(&event);
553 }
554
555 #define DECLARE_EVENT(ignore1, name) name,
556 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
557 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
558 };
559 #undef DECLARE_EVENT
560
561
562 void Logger::ProfilerBeginEvent() { 856 void Logger::ProfilerBeginEvent() {
563 if (!log_->IsEnabled()) return; 857 if (!log_->IsEnabled()) return;
564 LogMessageBuilder msg(this); 858 Log::MessageBuilder msg(log_);
565 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); 859 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs);
566 msg.WriteToLogFile(); 860 msg.WriteToLogFile();
567 } 861 }
568 862
569 863
570 void Logger::StringEvent(const char* name, const char* value) { 864 void Logger::StringEvent(const char* name, const char* value) {
571 if (FLAG_log) UncheckedStringEvent(name, value); 865 if (FLAG_log) UncheckedStringEvent(name, value);
572 } 866 }
573 867
574 868
575 void Logger::UncheckedStringEvent(const char* name, const char* value) { 869 void Logger::UncheckedStringEvent(const char* name, const char* value) {
576 if (!log_->IsEnabled()) return; 870 if (!log_->IsEnabled()) return;
577 LogMessageBuilder msg(this); 871 Log::MessageBuilder msg(log_);
578 msg.Append("%s,\"%s\"\n", name, value); 872 msg.Append("%s,\"%s\"\n", name, value);
579 msg.WriteToLogFile(); 873 msg.WriteToLogFile();
580 } 874 }
581 875
582 876
583 void Logger::IntEvent(const char* name, int value) { 877 void Logger::IntEvent(const char* name, int value) {
584 if (FLAG_log) UncheckedIntEvent(name, value); 878 if (FLAG_log) UncheckedIntEvent(name, value);
585 } 879 }
586 880
587 881
588 void Logger::IntPtrTEvent(const char* name, intptr_t value) { 882 void Logger::IntPtrTEvent(const char* name, intptr_t value) {
589 if (FLAG_log) UncheckedIntPtrTEvent(name, value); 883 if (FLAG_log) UncheckedIntPtrTEvent(name, value);
590 } 884 }
591 885
592 886
593 void Logger::UncheckedIntEvent(const char* name, int value) { 887 void Logger::UncheckedIntEvent(const char* name, int value) {
594 if (!log_->IsEnabled()) return; 888 if (!log_->IsEnabled()) return;
595 LogMessageBuilder msg(this); 889 Log::MessageBuilder msg(log_);
596 msg.Append("%s,%d\n", name, value); 890 msg.Append("%s,%d\n", name, value);
597 msg.WriteToLogFile(); 891 msg.WriteToLogFile();
598 } 892 }
599 893
600 894
601 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { 895 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
602 if (!log_->IsEnabled()) return; 896 if (!log_->IsEnabled()) return;
603 LogMessageBuilder msg(this); 897 Log::MessageBuilder msg(log_);
604 msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value); 898 msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
605 msg.WriteToLogFile(); 899 msg.WriteToLogFile();
606 } 900 }
607 901
608 902
609 void Logger::HandleEvent(const char* name, Object** location) { 903 void Logger::HandleEvent(const char* name, Object** location) {
610 if (!log_->IsEnabled() || !FLAG_log_handles) return; 904 if (!log_->IsEnabled() || !FLAG_log_handles) return;
611 LogMessageBuilder msg(this); 905 Log::MessageBuilder msg(log_);
612 msg.Append("%s,0x%" V8PRIxPTR "\n", name, location); 906 msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
613 msg.WriteToLogFile(); 907 msg.WriteToLogFile();
614 } 908 }
615 909
616 910
617 // ApiEvent is private so all the calls come from the Logger class. It is the 911 // ApiEvent is private so all the calls come from the Logger class. It is the
618 // caller's responsibility to ensure that log is enabled and that 912 // caller's responsibility to ensure that log is enabled and that
619 // FLAG_log_api is true. 913 // FLAG_log_api is true.
620 void Logger::ApiEvent(const char* format, ...) { 914 void Logger::ApiEvent(const char* format, ...) {
621 ASSERT(log_->IsEnabled() && FLAG_log_api); 915 ASSERT(log_->IsEnabled() && FLAG_log_api);
622 LogMessageBuilder msg(this); 916 Log::MessageBuilder msg(log_);
623 va_list ap; 917 va_list ap;
624 va_start(ap, format); 918 va_start(ap, format);
625 msg.AppendVA(format, ap); 919 msg.AppendVA(format, ap);
626 va_end(ap); 920 va_end(ap);
627 msg.WriteToLogFile(); 921 msg.WriteToLogFile();
628 } 922 }
629 923
630 924
631 void Logger::ApiNamedSecurityCheck(Object* key) { 925 void Logger::ApiNamedSecurityCheck(Object* key) {
632 if (!log_->IsEnabled() || !FLAG_log_api) return; 926 if (!log_->IsEnabled() || !FLAG_log_api) return;
(...skipping 18 matching lines...) Expand all
651 } else { 945 } else {
652 ApiEvent("api,check-security,['no-name']\n"); 946 ApiEvent("api,check-security,['no-name']\n");
653 } 947 }
654 } 948 }
655 949
656 950
657 void Logger::SharedLibraryEvent(const char* library_path, 951 void Logger::SharedLibraryEvent(const char* library_path,
658 uintptr_t start, 952 uintptr_t start,
659 uintptr_t end) { 953 uintptr_t end) {
660 if (!log_->IsEnabled() || !FLAG_prof) return; 954 if (!log_->IsEnabled() || !FLAG_prof) return;
661 LogMessageBuilder msg(this); 955 Log::MessageBuilder msg(log_);
662 msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 956 msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
663 library_path, 957 library_path,
664 start, 958 start,
665 end); 959 end);
666 msg.WriteToLogFile(); 960 msg.WriteToLogFile();
667 } 961 }
668 962
669 963
670 void Logger::SharedLibraryEvent(const wchar_t* library_path, 964 void Logger::SharedLibraryEvent(const wchar_t* library_path,
671 uintptr_t start, 965 uintptr_t start,
672 uintptr_t end) { 966 uintptr_t end) {
673 if (!log_->IsEnabled() || !FLAG_prof) return; 967 if (!log_->IsEnabled() || !FLAG_prof) return;
674 LogMessageBuilder msg(this); 968 Log::MessageBuilder msg(log_);
675 msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n", 969 msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
676 library_path, 970 library_path,
677 start, 971 start,
678 end); 972 end);
679 msg.WriteToLogFile(); 973 msg.WriteToLogFile();
680 } 974 }
681 975
682 976
683 void Logger::CodeDeoptEvent(Code* code) { 977 void Logger::CodeDeoptEvent(Code* code) {
684 if (!log_->IsEnabled()) return; 978 if (!log_->IsEnabled()) return;
685 ASSERT(FLAG_log_internal_timer_events); 979 ASSERT(FLAG_log_internal_timer_events);
686 LogMessageBuilder msg(this); 980 Log::MessageBuilder msg(log_);
687 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); 981 int since_epoch = static_cast<int>(OS::Ticks() - epoch_);
688 msg.Append("code-deopt,%ld,%d\n", since_epoch, code->CodeSize()); 982 msg.Append("code-deopt,%ld,%d\n", since_epoch, code->CodeSize());
689 msg.WriteToLogFile(); 983 msg.WriteToLogFile();
690 } 984 }
691 985
692 986
693 void Logger::TimerEvent(StartEnd se, const char* name) { 987 void Logger::TimerEvent(StartEnd se, const char* name) {
694 if (!log_->IsEnabled()) return; 988 if (!log_->IsEnabled()) return;
695 ASSERT(FLAG_log_internal_timer_events); 989 ASSERT(FLAG_log_internal_timer_events);
696 LogMessageBuilder msg(this); 990 Log::MessageBuilder msg(log_);
697 int since_epoch = static_cast<int>(OS::Ticks() - epoch_); 991 int since_epoch = static_cast<int>(OS::Ticks() - epoch_);
698 const char* format = (se == START) ? "timer-event-start,\"%s\",%ld\n" 992 const char* format = (se == START) ? "timer-event-start,\"%s\",%ld\n"
699 : "timer-event-end,\"%s\",%ld\n"; 993 : "timer-event-end,\"%s\",%ld\n";
700 msg.Append(format, name, since_epoch); 994 msg.Append(format, name, since_epoch);
701 msg.WriteToLogFile(); 995 msg.WriteToLogFile();
702 } 996 }
703 997
704 998
705 void Logger::EnterExternal(Isolate* isolate) { 999 void Logger::EnterExternal(Isolate* isolate) {
706 LOG(isolate, TimerEvent(START, TimerEventScope::v8_external)); 1000 LOG(isolate, TimerEvent(START, TimerEventScope::v8_external));
(...skipping 20 matching lines...) Expand all
727 "V8.RecompileParallel"; 1021 "V8.RecompileParallel";
728 const char* Logger::TimerEventScope::v8_compile_full_code = 1022 const char* Logger::TimerEventScope::v8_compile_full_code =
729 "V8.CompileFullCode"; 1023 "V8.CompileFullCode";
730 const char* Logger::TimerEventScope::v8_execute = "V8.Execute"; 1024 const char* Logger::TimerEventScope::v8_execute = "V8.Execute";
731 const char* Logger::TimerEventScope::v8_external = "V8.External"; 1025 const char* Logger::TimerEventScope::v8_external = "V8.External";
732 1026
733 1027
734 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) { 1028 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
735 // Prints "/" + re.source + "/" + 1029 // Prints "/" + re.source + "/" +
736 // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"") 1030 // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
737 LogMessageBuilder msg(this); 1031 Log::MessageBuilder msg(log_);
738 1032
739 Handle<Object> source = GetProperty(regexp, "source"); 1033 Handle<Object> source = GetProperty(regexp, "source");
740 if (!source->IsString()) { 1034 if (!source->IsString()) {
741 msg.Append("no source"); 1035 msg.Append("no source");
742 return; 1036 return;
743 } 1037 }
744 1038
745 switch (regexp->TypeTag()) { 1039 switch (regexp->TypeTag()) {
746 case JSRegExp::ATOM: 1040 case JSRegExp::ATOM:
747 msg.Append('a'); 1041 msg.Append('a');
(...skipping 20 matching lines...) Expand all
768 if (multiline->IsTrue()) { 1062 if (multiline->IsTrue()) {
769 msg.Append('m'); 1063 msg.Append('m');
770 } 1064 }
771 1065
772 msg.WriteToLogFile(); 1066 msg.WriteToLogFile();
773 } 1067 }
774 1068
775 1069
776 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { 1070 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
777 if (!log_->IsEnabled() || !FLAG_log_regexp) return; 1071 if (!log_->IsEnabled() || !FLAG_log_regexp) return;
778 LogMessageBuilder msg(this); 1072 Log::MessageBuilder msg(log_);
779 msg.Append("regexp-compile,"); 1073 msg.Append("regexp-compile,");
780 LogRegExpSource(regexp); 1074 LogRegExpSource(regexp);
781 msg.Append(in_cache ? ",hit\n" : ",miss\n"); 1075 msg.Append(in_cache ? ",hit\n" : ",miss\n");
782 msg.WriteToLogFile(); 1076 msg.WriteToLogFile();
783 } 1077 }
784 1078
785 1079
786 void Logger::LogRuntime(Vector<const char> format, 1080 void Logger::LogRuntime(Vector<const char> format,
787 JSArray* args) { 1081 JSArray* args) {
788 if (!log_->IsEnabled() || !FLAG_log_runtime) return; 1082 if (!log_->IsEnabled() || !FLAG_log_runtime) return;
789 HandleScope scope(isolate_); 1083 HandleScope scope(isolate_);
790 LogMessageBuilder msg(this); 1084 Log::MessageBuilder msg(log_);
791 for (int i = 0; i < format.length(); i++) { 1085 for (int i = 0; i < format.length(); i++) {
792 char c = format[i]; 1086 char c = format[i];
793 if (c == '%' && i <= format.length() - 2) { 1087 if (c == '%' && i <= format.length() - 2) {
794 i++; 1088 i++;
795 ASSERT('0' <= format[i] && format[i] <= '9'); 1089 ASSERT('0' <= format[i] && format[i] <= '9');
796 MaybeObject* maybe = args->GetElement(format[i] - '0'); 1090 MaybeObject* maybe = args->GetElement(format[i] - '0');
797 Object* obj; 1091 Object* obj;
798 if (!maybe->ToObject(&obj)) { 1092 if (!maybe->ToObject(&obj)) {
799 msg.Append("<exception>"); 1093 msg.Append("<exception>");
800 continue; 1094 continue;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 1175
882 1176
883 void Logger::ApiEntryCall(const char* name) { 1177 void Logger::ApiEntryCall(const char* name) {
884 if (!log_->IsEnabled() || !FLAG_log_api) return; 1178 if (!log_->IsEnabled() || !FLAG_log_api) return;
885 ApiEvent("api,%s\n", name); 1179 ApiEvent("api,%s\n", name);
886 } 1180 }
887 1181
888 1182
889 void Logger::NewEvent(const char* name, void* object, size_t size) { 1183 void Logger::NewEvent(const char* name, void* object, size_t size) {
890 if (!log_->IsEnabled() || !FLAG_log) return; 1184 if (!log_->IsEnabled() || !FLAG_log) return;
891 LogMessageBuilder msg(this); 1185 Log::MessageBuilder msg(log_);
892 msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object, 1186 msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
893 static_cast<unsigned int>(size)); 1187 static_cast<unsigned int>(size));
894 msg.WriteToLogFile(); 1188 msg.WriteToLogFile();
895 } 1189 }
896 1190
897 1191
898 void Logger::DeleteEvent(const char* name, void* object) { 1192 void Logger::DeleteEvent(const char* name, void* object) {
899 if (!log_->IsEnabled() || !FLAG_log) return; 1193 if (!log_->IsEnabled() || !FLAG_log) return;
900 LogMessageBuilder msg(this); 1194 Log::MessageBuilder msg(log_);
901 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); 1195 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
902 msg.WriteToLogFile(); 1196 msg.WriteToLogFile();
903 } 1197 }
904 1198
905 1199
906 void Logger::NewEventStatic(const char* name, void* object, size_t size) { 1200 void Logger::NewEventStatic(const char* name, void* object, size_t size) {
907 Isolate::Current()->logger()->NewEvent(name, object, size); 1201 Isolate::Current()->logger()->NewEvent(name, object, size);
908 } 1202 }
909 1203
910 1204
911 void Logger::DeleteEventStatic(const char* name, void* object) { 1205 void Logger::DeleteEventStatic(const char* name, void* object) {
912 Isolate::Current()->logger()->DeleteEvent(name, object); 1206 Isolate::Current()->logger()->DeleteEvent(name, object);
913 } 1207 }
914 1208
1209
915 void Logger::CallbackEventInternal(const char* prefix, Name* name, 1210 void Logger::CallbackEventInternal(const char* prefix, Name* name,
916 Address entry_point) { 1211 Address entry_point) {
917 if (!log_->IsEnabled() || !FLAG_log_code) return; 1212 if (!log_->IsEnabled() || !FLAG_log_code) return;
918 LogMessageBuilder msg(this); 1213 Log::MessageBuilder msg(log_);
919 msg.Append("%s,%s,-2,", 1214 msg.Append("%s,%s,-2,",
920 kLogEventsNames[CODE_CREATION_EVENT], 1215 kLogEventsNames[CODE_CREATION_EVENT],
921 kLogEventsNames[CALLBACK_TAG]); 1216 kLogEventsNames[CALLBACK_TAG]);
922 msg.AppendAddress(entry_point); 1217 msg.AppendAddress(entry_point);
923 if (name->IsString()) { 1218 if (name->IsString()) {
924 SmartArrayPointer<char> str = 1219 SmartArrayPointer<char> str =
925 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1220 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
926 msg.Append(",1,\"%s%s\"", prefix, *str); 1221 msg.Append(",1,\"%s%s\"", prefix, *str);
927 } else { 1222 } else {
928 Symbol* symbol = Symbol::cast(name); 1223 Symbol* symbol = Symbol::cast(name);
(...skipping 21 matching lines...) Expand all
950 CallbackEventInternal("get ", name, entry_point); 1245 CallbackEventInternal("get ", name, entry_point);
951 } 1246 }
952 1247
953 1248
954 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { 1249 void Logger::SetterCallbackEvent(Name* name, Address entry_point) {
955 if (!log_->IsEnabled() || !FLAG_log_code) return; 1250 if (!log_->IsEnabled() || !FLAG_log_code) return;
956 CallbackEventInternal("set ", name, entry_point); 1251 CallbackEventInternal("set ", name, entry_point);
957 } 1252 }
958 1253
959 1254
960 void Logger::AppendName(Name* name) { 1255 static void AppendCodeCreateHeader(Log::MessageBuilder* msg,
961 if (name->IsString()) { 1256 Logger::LogEventsAndTags tag,
962 name_buffer_->AppendString(String::cast(name)); 1257 Code* code) {
963 } else {
964 Symbol* symbol = Symbol::cast(name);
965 name_buffer_->AppendBytes("symbol(");
966 if (!symbol->name()->IsUndefined()) {
967 name_buffer_->AppendBytes("\"");
968 name_buffer_->AppendString(String::cast(symbol->name()));
969 name_buffer_->AppendBytes("\" ");
970 }
971 name_buffer_->AppendBytes("hash ");
972 name_buffer_->AppendHex(symbol->Hash());
973 name_buffer_->AppendByte(')');
974 }
975 }
976
977
978 void Logger::InitNameBuffer(LogEventsAndTags tag) {
979 name_buffer_->Reset();
980 name_buffer_->AppendBytes(kLogEventsNames[tag]);
981 name_buffer_->AppendByte(':');
982 }
983
984
985 void Logger::LogRecordedBuffer(Code* code, SharedFunctionInfo* shared) {
986 if (code_event_handler_ != NULL) {
987 Script* script = shared && shared->script()->IsScript() ?
988 Script::cast(shared->script()) : NULL;
989 IssueCodeAddedEvent(code,
990 script,
991 name_buffer_->get(),
992 name_buffer_->size());
993 }
994 if (!log_->IsEnabled()) return;
995 LL_LOG(CodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()));
996 if (Serializer::enabled()) {
997 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
998 }
999 }
1000
1001
1002 void Logger::AppendCodeCreateHeader(LogMessageBuilder* msg,
1003 LogEventsAndTags tag,
1004 Code* code) {
1005 ASSERT(msg); 1258 ASSERT(msg);
1006 msg->Append("%s,%s,%d,", 1259 msg->Append("%s,%s,%d,",
1007 kLogEventsNames[CODE_CREATION_EVENT], 1260 kLogEventsNames[Logger::CODE_CREATION_EVENT],
1008 kLogEventsNames[tag], 1261 kLogEventsNames[tag],
1009 code->kind()); 1262 code->kind());
1010 msg->AppendAddress(code->address()); 1263 msg->AppendAddress(code->address());
1011 msg->Append(",%d,", code->ExecutableSize()); 1264 msg->Append(",%d,", code->ExecutableSize());
1012 } 1265 }
1013 1266
1014 1267
1015 void Logger::AppendSymbolName(LogMessageBuilder* msg,
1016 Symbol* symbol) {
1017 ASSERT(symbol);
1018 msg->Append("symbol(");
1019 if (!symbol->name()->IsUndefined()) {
1020 msg->Append("\"");
1021 msg->AppendDetailed(String::cast(symbol->name()), false);
1022 msg->Append("\" ");
1023 }
1024 msg->Append("hash %x)", symbol->Hash());
1025 }
1026
1027
1028 void Logger::CodeCreateEvent(LogEventsAndTags tag, 1268 void Logger::CodeCreateEvent(LogEventsAndTags tag,
1029 Code* code, 1269 Code* code,
1030 const char* comment) { 1270 const char* comment) {
1031 if (!is_logging_code_events()) return; 1271 if (!is_logging_code_events()) return;
1032 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1272
1033 InitNameBuffer(tag); 1273 JIT_LOG(CodeCreateEvent(tag, code, comment));
1034 name_buffer_->AppendBytes(comment); 1274 LL_LOG(CodeCreateEvent(tag, code, comment));
1035 LogRecordedBuffer(code, NULL); 1275 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, comment));
1036 }
1037 1276
1038 if (!FLAG_log_code || !log_->IsEnabled()) return; 1277 if (!FLAG_log_code || !log_->IsEnabled()) return;
1039 LogMessageBuilder msg(this); 1278 Log::MessageBuilder msg(log_);
1040 AppendCodeCreateHeader(&msg, tag, code); 1279 AppendCodeCreateHeader(&msg, tag, code);
1041 msg.AppendDoubleQuotedString(comment); 1280 msg.AppendDoubleQuotedString(comment);
1042 msg.Append('\n'); 1281 msg.Append('\n');
1043 msg.WriteToLogFile(); 1282 msg.WriteToLogFile();
1044 } 1283 }
1045 1284
1046 1285
1047 void Logger::CodeCreateEvent(LogEventsAndTags tag, 1286 void Logger::CodeCreateEvent(LogEventsAndTags tag,
1048 Code* code, 1287 Code* code,
1049 Name* name) { 1288 Name* name) {
1050 if (!is_logging_code_events()) return; 1289 if (!is_logging_code_events()) return;
1051 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1290
1052 InitNameBuffer(tag); 1291 JIT_LOG(CodeCreateEvent(tag, code, name));
1053 AppendName(name); 1292 LL_LOG(CodeCreateEvent(tag, code, name));
1054 LogRecordedBuffer(code, NULL); 1293 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, name));
1055 }
1056 1294
1057 if (!FLAG_log_code || !log_->IsEnabled()) return; 1295 if (!FLAG_log_code || !log_->IsEnabled()) return;
1058 LogMessageBuilder msg(this); 1296 Log::MessageBuilder msg(log_);
1059 AppendCodeCreateHeader(&msg, tag, code); 1297 AppendCodeCreateHeader(&msg, tag, code);
1060 if (name->IsString()) { 1298 if (name->IsString()) {
1061 msg.Append('"'); 1299 msg.Append('"');
1062 msg.AppendDetailed(String::cast(name), false); 1300 msg.AppendDetailed(String::cast(name), false);
1063 msg.Append('"'); 1301 msg.Append('"');
1064 } else { 1302 } else {
1065 AppendSymbolName(&msg, Symbol::cast(name)); 1303 msg.AppendSymbolName(Symbol::cast(name));
1066 } 1304 }
1067 msg.Append('\n'); 1305 msg.Append('\n');
1068 msg.WriteToLogFile(); 1306 msg.WriteToLogFile();
1069 } 1307 }
1070 1308
1071 1309
1072 // ComputeMarker must only be used when SharedFunctionInfo is known.
1073 static const char* ComputeMarker(Code* code) {
1074 switch (code->kind()) {
1075 case Code::FUNCTION: return code->optimizable() ? "~" : "";
1076 case Code::OPTIMIZED_FUNCTION: return "*";
1077 default: return "";
1078 }
1079 }
1080
1081
1082 void Logger::CodeCreateEvent(LogEventsAndTags tag, 1310 void Logger::CodeCreateEvent(LogEventsAndTags tag,
1083 Code* code, 1311 Code* code,
1084 SharedFunctionInfo* shared, 1312 SharedFunctionInfo* shared,
1085 CompilationInfo* info, 1313 CompilationInfo* info,
1086 Name* name) { 1314 Name* name) {
1087 if (!is_logging_code_events()) return; 1315 if (!is_logging_code_events()) return;
1088 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1316
1089 InitNameBuffer(tag); 1317 JIT_LOG(CodeCreateEvent(tag, code, shared, info, name));
1090 name_buffer_->AppendBytes(ComputeMarker(code)); 1318 LL_LOG(CodeCreateEvent(tag, code, shared, info, name));
1091 AppendName(name); 1319 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, name));
1092 LogRecordedBuffer(code, shared);
1093 }
1094 1320
1095 if (!FLAG_log_code || !log_->IsEnabled()) return; 1321 if (!FLAG_log_code || !log_->IsEnabled()) return;
1096 if (code == isolate_->builtins()->builtin( 1322 if (code == isolate_->builtins()->builtin(
1097 Builtins::kLazyCompile)) 1323 Builtins::kLazyCompile))
1098 return; 1324 return;
1099 1325
1100 LogMessageBuilder msg(this); 1326 Log::MessageBuilder msg(log_);
1101 AppendCodeCreateHeader(&msg, tag, code); 1327 AppendCodeCreateHeader(&msg, tag, code);
1102 if (name->IsString()) { 1328 if (name->IsString()) {
1103 SmartArrayPointer<char> str = 1329 SmartArrayPointer<char> str =
1104 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1330 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1105 msg.Append("\"%s\"", *str); 1331 msg.Append("\"%s\"", *str);
1106 } else { 1332 } else {
1107 AppendSymbolName(&msg, Symbol::cast(name)); 1333 msg.AppendSymbolName(Symbol::cast(name));
1108 } 1334 }
1109 msg.Append(','); 1335 msg.Append(',');
1110 msg.AppendAddress(shared->address()); 1336 msg.AppendAddress(shared->address());
1111 msg.Append(",%s", ComputeMarker(code)); 1337 msg.Append(",%s", ComputeMarker(code));
1112 msg.Append('\n'); 1338 msg.Append('\n');
1113 msg.WriteToLogFile(); 1339 msg.WriteToLogFile();
1114 } 1340 }
1115 1341
1116 1342
1117 // Although, it is possible to extract source and line from 1343 // Although, it is possible to extract source and line from
1118 // the SharedFunctionInfo object, we left it to caller 1344 // the SharedFunctionInfo object, we left it to caller
1119 // to leave logging functions free from heap allocations. 1345 // to leave logging functions free from heap allocations.
1120 void Logger::CodeCreateEvent(LogEventsAndTags tag, 1346 void Logger::CodeCreateEvent(LogEventsAndTags tag,
1121 Code* code, 1347 Code* code,
1122 SharedFunctionInfo* shared, 1348 SharedFunctionInfo* shared,
1123 CompilationInfo* info, 1349 CompilationInfo* info,
1124 Name* source, int line) { 1350 Name* source, int line) {
1125 if (!is_logging_code_events()) return; 1351 if (!is_logging_code_events()) return;
1126 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1352
1127 InitNameBuffer(tag); 1353 JIT_LOG(CodeCreateEvent(tag, code, shared, info, source, line));
1128 name_buffer_->AppendBytes(ComputeMarker(code)); 1354 LL_LOG(CodeCreateEvent(tag, code, shared, info, source, line));
1129 name_buffer_->AppendString(shared->DebugName()); 1355 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, source, line));
1130 name_buffer_->AppendByte(' ');
1131 if (source->IsString()) {
1132 name_buffer_->AppendString(String::cast(source));
1133 } else {
1134 name_buffer_->AppendBytes("symbol(hash ");
1135 name_buffer_->AppendHex(Name::cast(source)->Hash());
1136 name_buffer_->AppendByte(')');
1137 }
1138 name_buffer_->AppendByte(':');
1139 name_buffer_->AppendInt(line);
1140 LogRecordedBuffer(code, shared);
1141 }
1142 1356
1143 if (!FLAG_log_code || !log_->IsEnabled()) return; 1357 if (!FLAG_log_code || !log_->IsEnabled()) return;
1144 LogMessageBuilder msg(this); 1358 Log::MessageBuilder msg(log_);
1145 AppendCodeCreateHeader(&msg, tag, code); 1359 AppendCodeCreateHeader(&msg, tag, code);
1146 SmartArrayPointer<char> name = 1360 SmartArrayPointer<char> name =
1147 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1361 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1148 msg.Append("\"%s ", *name); 1362 msg.Append("\"%s ", *name);
1149 if (source->IsString()) { 1363 if (source->IsString()) {
1150 SmartArrayPointer<char> sourcestr = 1364 SmartArrayPointer<char> sourcestr =
1151 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1365 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1152 msg.Append("%s", *sourcestr); 1366 msg.Append("%s", *sourcestr);
1153 } else { 1367 } else {
1154 AppendSymbolName(&msg, Symbol::cast(source)); 1368 msg.AppendSymbolName(Symbol::cast(source));
1155 } 1369 }
1156 msg.Append(":%d\",", line); 1370 msg.Append(":%d\",", line);
1157 msg.AppendAddress(shared->address()); 1371 msg.AppendAddress(shared->address());
1158 msg.Append(",%s", ComputeMarker(code)); 1372 msg.Append(",%s", ComputeMarker(code));
1159 msg.Append('\n'); 1373 msg.Append('\n');
1160 msg.WriteToLogFile(); 1374 msg.WriteToLogFile();
1161 } 1375 }
1162 1376
1163 1377
1164 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { 1378 void Logger::CodeCreateEvent(LogEventsAndTags tag,
1379 Code* code,
1380 int args_count) {
1165 if (!is_logging_code_events()) return; 1381 if (!is_logging_code_events()) return;
1166 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1382
1167 InitNameBuffer(tag); 1383 JIT_LOG(CodeCreateEvent(tag, code, args_count));
1168 name_buffer_->AppendInt(args_count); 1384 LL_LOG(CodeCreateEvent(tag, code, args_count));
1169 LogRecordedBuffer(code, NULL); 1385 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, args_count));
1170 }
1171 1386
1172 if (!FLAG_log_code || !log_->IsEnabled()) return; 1387 if (!FLAG_log_code || !log_->IsEnabled()) return;
1173 LogMessageBuilder msg(this); 1388 Log::MessageBuilder msg(log_);
1174 AppendCodeCreateHeader(&msg, tag, code); 1389 AppendCodeCreateHeader(&msg, tag, code);
1175 msg.Append("\"args_count: %d\"", args_count); 1390 msg.Append("\"args_count: %d\"", args_count);
1176 msg.Append('\n'); 1391 msg.Append('\n');
1177 msg.WriteToLogFile(); 1392 msg.WriteToLogFile();
1178 } 1393 }
1179 1394
1180 1395
1181 void Logger::CodeMovingGCEvent() { 1396 void Logger::CodeMovingGCEvent() {
1182 if (!log_->IsEnabled() || !FLAG_ll_prof) return; 1397 if (!log_->IsEnabled() || !FLAG_ll_prof) return;
1183 LL_LOG(CodeMovingGCEvent()); 1398 LL_LOG(CodeMovingGCEvent());
1184 OS::SignalCodeMovingGC(); 1399 OS::SignalCodeMovingGC();
1185 } 1400 }
1186 1401
1187 1402
1188 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { 1403 void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
1189 if (!is_logging_code_events()) return; 1404 if (!is_logging_code_events()) return;
1190 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { 1405
1191 InitNameBuffer(REG_EXP_TAG); 1406 JIT_LOG(RegExpCodeCreateEvent(code, source));
1192 name_buffer_->AppendString(source); 1407 LL_LOG(RegExpCodeCreateEvent(code, source));
1193 LogRecordedBuffer(code, NULL); 1408 CODE_ADDRESS_MAP_LOG(RegExpCodeCreateEvent(code, source));
1194 }
1195 1409
1196 if (!FLAG_log_code || !log_->IsEnabled()) return; 1410 if (!FLAG_log_code || !log_->IsEnabled()) return;
1197 LogMessageBuilder msg(this); 1411 Log::MessageBuilder msg(log_);
1198 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); 1412 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code);
1199 msg.Append('"'); 1413 msg.Append('"');
1200 msg.AppendDetailed(source, false); 1414 msg.AppendDetailed(source, false);
1201 msg.Append('"'); 1415 msg.Append('"');
1202 msg.Append('\n'); 1416 msg.Append('\n');
1203 msg.WriteToLogFile(); 1417 msg.WriteToLogFile();
1204 } 1418 }
1205 1419
1206 1420
1207 void Logger::CodeMoveEvent(Address from, Address to) { 1421 void Logger::CodeMoveEvent(Address from, Address to) {
1208 if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to); 1422 JIT_LOG(CodeMovedEvent(from, to));
1209 if (!log_->IsEnabled()) return; 1423 if (!log_->IsEnabled()) return;
1210 LL_LOG(CodeMoveEvent(from, to)); 1424 LL_LOG(CodeMoveEvent(from, to));
1211 if (Serializer::enabled() && address_to_name_map_ != NULL) { 1425 CODE_ADDRESS_MAP_LOG(CodeMoveEvent(from, to));
1212 address_to_name_map_->Move(from, to);
1213 }
1214 MoveEventInternal(CODE_MOVE_EVENT, from, to); 1426 MoveEventInternal(CODE_MOVE_EVENT, from, to);
1215 } 1427 }
1216 1428
1217 1429
1218 void Logger::CodeDeleteEvent(Address from) { 1430 void Logger::CodeDeleteEvent(Address from) {
1219 if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from); 1431 JIT_LOG(CodeDeleteEvent(from));
1220 if (!log_->IsEnabled()) return; 1432 if (!log_->IsEnabled()) return;
1221 LL_LOG(CodeDeleteEvent(from)); 1433 LL_LOG(CodeDeleteEvent(from));
1222 if (Serializer::enabled() && address_to_name_map_ != NULL) { 1434 CODE_ADDRESS_MAP_LOG(CodeDeleteEvent(from));
1223 address_to_name_map_->Remove(from); 1435
1224 } 1436 if (!log_->IsEnabled() || !FLAG_log_code) return;
1225 DeleteEventInternal(CODE_DELETE_EVENT, from); 1437 Log::MessageBuilder msg(log_);
1438 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]);
1439 msg.AppendAddress(from);
1440 msg.Append('\n');
1441 msg.WriteToLogFile();
1226 } 1442 }
1227 1443
1444
1228 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, 1445 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
1229 int pc_offset, 1446 int pc_offset,
1230 int position) { 1447 int position) {
1231 if (code_event_handler_ != NULL) { 1448 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1232 IssueAddCodeLinePosInfoEvent(jit_handler_data, 1449 pc_offset,
1233 pc_offset, 1450 position,
1234 position, 1451 JitCodeEvent::POSITION));
1235 JitCodeEvent::POSITION);
1236 }
1237 } 1452 }
1238 1453
1454
1239 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, 1455 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data,
1240 int pc_offset, 1456 int pc_offset,
1241 int position) { 1457 int position) {
1242 if (code_event_handler_ != NULL) { 1458 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1243 IssueAddCodeLinePosInfoEvent(jit_handler_data, 1459 pc_offset,
1244 pc_offset, 1460 position,
1245 position, 1461 JitCodeEvent::STATEMENT_POSITION));
1246 JitCodeEvent::STATEMENT_POSITION); 1462 }
1463
1464
1465 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) {
1466 if (jit_logger_ != NULL) {
1467 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent());
1247 } 1468 }
1248 } 1469 }
1249 1470
1250 1471
1251 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) {
1252 if (code_event_handler_ != NULL) {
1253 pos_recorder->AttachJITHandlerData(IssueStartCodePosInfoEvent());
1254 }
1255 }
1256
1257 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, 1472 void Logger::CodeEndLinePosInfoRecordEvent(Code* code,
1258 void* jit_handler_data) { 1473 void* jit_handler_data) {
1259 if (code_event_handler_ != NULL) { 1474 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data));
1260 IssueEndCodePosInfoEvent(code, jit_handler_data);
1261 }
1262 } 1475 }
1263 1476
1264 1477
1265 void Logger::SnapshotPositionEvent(Address addr, int pos) { 1478 void Logger::SnapshotPositionEvent(Address addr, int pos) {
1266 if (!log_->IsEnabled()) return; 1479 if (!log_->IsEnabled()) return;
1267 LL_LOG(SnapshotPositionEvent(addr, pos)); 1480 LL_LOG(SnapshotPositionEvent(addr, pos));
1268 if (Serializer::enabled() && address_to_name_map_ != NULL) { 1481 if (Serializer::enabled()) {
1269 const char* code_name = address_to_name_map_->Lookup(addr); 1482 const char* code_name = code_address_map_->Lookup(addr);
1270 if (code_name == NULL) return; // Not a code object. 1483 if (code_name == NULL) return; // Not a code object.
1271 LogMessageBuilder msg(this); 1484 Log::MessageBuilder msg(log_);
1272 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); 1485 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
1273 msg.AppendDoubleQuotedString(code_name); 1486 msg.AppendDoubleQuotedString(code_name);
1274 msg.Append("\n"); 1487 msg.Append("\n");
1275 msg.WriteToLogFile(); 1488 msg.WriteToLogFile();
1276 } 1489 }
1277 if (!FLAG_log_snapshot_positions) return; 1490 if (!FLAG_log_snapshot_positions) return;
1278 LogMessageBuilder msg(this); 1491 Log::MessageBuilder msg(log_);
1279 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); 1492 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
1280 msg.AppendAddress(addr); 1493 msg.AppendAddress(addr);
1281 msg.Append(",%d", pos); 1494 msg.Append(",%d", pos);
1282 msg.Append('\n'); 1495 msg.Append('\n');
1283 msg.WriteToLogFile(); 1496 msg.WriteToLogFile();
1284 } 1497 }
1285 1498
1286 1499
1287 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { 1500 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
1288 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); 1501 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
1289 } 1502 }
1290 1503
1291 1504
1292 void Logger::MoveEventInternal(LogEventsAndTags event, 1505 void Logger::MoveEventInternal(LogEventsAndTags event,
1293 Address from, 1506 Address from,
1294 Address to) { 1507 Address to) {
1295 if (!log_->IsEnabled() || !FLAG_log_code) return; 1508 if (!log_->IsEnabled() || !FLAG_log_code) return;
1296 LogMessageBuilder msg(this); 1509 Log::MessageBuilder msg(log_);
1297 msg.Append("%s,", kLogEventsNames[event]); 1510 msg.Append("%s,", kLogEventsNames[event]);
1298 msg.AppendAddress(from); 1511 msg.AppendAddress(from);
1299 msg.Append(','); 1512 msg.Append(',');
1300 msg.AppendAddress(to); 1513 msg.AppendAddress(to);
1301 msg.Append('\n'); 1514 msg.Append('\n');
1302 msg.WriteToLogFile(); 1515 msg.WriteToLogFile();
1303 } 1516 }
1304 1517
1305 1518
1306 void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) {
1307 if (!log_->IsEnabled() || !FLAG_log_code) return;
1308 LogMessageBuilder msg(this);
1309 msg.Append("%s,", kLogEventsNames[event]);
1310 msg.AppendAddress(from);
1311 msg.Append('\n');
1312 msg.WriteToLogFile();
1313 }
1314
1315
1316 void Logger::ResourceEvent(const char* name, const char* tag) { 1519 void Logger::ResourceEvent(const char* name, const char* tag) {
1317 if (!log_->IsEnabled() || !FLAG_log) return; 1520 if (!log_->IsEnabled() || !FLAG_log) return;
1318 LogMessageBuilder msg(this); 1521 Log::MessageBuilder msg(log_);
1319 msg.Append("%s,%s,", name, tag); 1522 msg.Append("%s,%s,", name, tag);
1320 1523
1321 uint32_t sec, usec; 1524 uint32_t sec, usec;
1322 if (OS::GetUserTime(&sec, &usec) != -1) { 1525 if (OS::GetUserTime(&sec, &usec) != -1) {
1323 msg.Append("%d,%d,", sec, usec); 1526 msg.Append("%d,%d,", sec, usec);
1324 } 1527 }
1325 msg.Append("%.0f", OS::TimeCurrentMillis()); 1528 msg.Append("%.0f", OS::TimeCurrentMillis());
1326 1529
1327 msg.Append('\n'); 1530 msg.Append('\n');
1328 msg.WriteToLogFile(); 1531 msg.WriteToLogFile();
1329 } 1532 }
1330 1533
1331 1534
1332 void Logger::SuspectReadEvent(Name* name, Object* obj) { 1535 void Logger::SuspectReadEvent(Name* name, Object* obj) {
1333 if (!log_->IsEnabled() || !FLAG_log_suspect) return; 1536 if (!log_->IsEnabled() || !FLAG_log_suspect) return;
1334 LogMessageBuilder msg(this); 1537 Log::MessageBuilder msg(log_);
1335 String* class_name = obj->IsJSObject() 1538 String* class_name = obj->IsJSObject()
1336 ? JSObject::cast(obj)->class_name() 1539 ? JSObject::cast(obj)->class_name()
1337 : isolate_->heap()->empty_string(); 1540 : isolate_->heap()->empty_string();
1338 msg.Append("suspect-read,"); 1541 msg.Append("suspect-read,");
1339 msg.Append(class_name); 1542 msg.Append(class_name);
1340 msg.Append(','); 1543 msg.Append(',');
1341 if (name->IsString()) { 1544 if (name->IsString()) {
1342 msg.Append('"'); 1545 msg.Append('"');
1343 msg.Append(String::cast(name)); 1546 msg.Append(String::cast(name));
1344 msg.Append('"'); 1547 msg.Append('"');
1345 } else { 1548 } else {
1346 AppendSymbolName(&msg, Symbol::cast(name)); 1549 msg.AppendSymbolName(Symbol::cast(name));
1347 } 1550 }
1348 msg.Append('\n'); 1551 msg.Append('\n');
1349 msg.WriteToLogFile(); 1552 msg.WriteToLogFile();
1350 } 1553 }
1351 1554
1352 1555
1353 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) { 1556 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
1354 if (!log_->IsEnabled() || !FLAG_log_gc) return; 1557 if (!log_->IsEnabled() || !FLAG_log_gc) return;
1355 LogMessageBuilder msg(this); 1558 Log::MessageBuilder msg(log_);
1356 // Using non-relative system time in order to be able to synchronize with 1559 // Using non-relative system time in order to be able to synchronize with
1357 // external memory profiling events (e.g. DOM memory size). 1560 // external memory profiling events (e.g. DOM memory size).
1358 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", 1561 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
1359 space, kind, OS::TimeCurrentMillis()); 1562 space, kind, OS::TimeCurrentMillis());
1360 msg.WriteToLogFile(); 1563 msg.WriteToLogFile();
1361 } 1564 }
1362 1565
1363 1566
1364 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { 1567 void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
1365 if (!log_->IsEnabled() || !FLAG_log_gc) return; 1568 if (!log_->IsEnabled() || !FLAG_log_gc) return;
1366 LogMessageBuilder msg(this); 1569 Log::MessageBuilder msg(log_);
1367 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); 1570 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
1368 msg.WriteToLogFile(); 1571 msg.WriteToLogFile();
1369 } 1572 }
1370 1573
1371 1574
1372 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { 1575 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
1373 if (!log_->IsEnabled() || !FLAG_log_gc) return; 1576 if (!log_->IsEnabled() || !FLAG_log_gc) return;
1374 LogMessageBuilder msg(this); 1577 Log::MessageBuilder msg(log_);
1375 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); 1578 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
1376 msg.WriteToLogFile(); 1579 msg.WriteToLogFile();
1377 } 1580 }
1378 1581
1379 1582
1380 void Logger::DebugTag(const char* call_site_tag) { 1583 void Logger::DebugTag(const char* call_site_tag) {
1381 if (!log_->IsEnabled() || !FLAG_log) return; 1584 if (!log_->IsEnabled() || !FLAG_log) return;
1382 LogMessageBuilder msg(this); 1585 Log::MessageBuilder msg(log_);
1383 msg.Append("debug-tag,%s\n", call_site_tag); 1586 msg.Append("debug-tag,%s\n", call_site_tag);
1384 msg.WriteToLogFile(); 1587 msg.WriteToLogFile();
1385 } 1588 }
1386 1589
1387 1590
1388 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { 1591 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
1389 if (!log_->IsEnabled() || !FLAG_log) return; 1592 if (!log_->IsEnabled() || !FLAG_log) return;
1390 StringBuilder s(parameter.length() + 1); 1593 StringBuilder s(parameter.length() + 1);
1391 for (int i = 0; i < parameter.length(); ++i) { 1594 for (int i = 0; i < parameter.length(); ++i) {
1392 s.AddCharacter(static_cast<char>(parameter[i])); 1595 s.AddCharacter(static_cast<char>(parameter[i]));
1393 } 1596 }
1394 char* parameter_string = s.Finalize(); 1597 char* parameter_string = s.Finalize();
1395 LogMessageBuilder msg(this); 1598 Log::MessageBuilder msg(log_);
1396 msg.Append("debug-queue-event,%s,%15.3f,%s\n", 1599 msg.Append("debug-queue-event,%s,%15.3f,%s\n",
1397 event_type, 1600 event_type,
1398 OS::TimeCurrentMillis(), 1601 OS::TimeCurrentMillis(),
1399 parameter_string); 1602 parameter_string);
1400 DeleteArray(parameter_string); 1603 DeleteArray(parameter_string);
1401 msg.WriteToLogFile(); 1604 msg.WriteToLogFile();
1402 } 1605 }
1403 1606
1404 1607
1405 void Logger::TickEvent(TickSample* sample, bool overflow) { 1608 void Logger::TickEvent(TickSample* sample, bool overflow) {
1406 if (!log_->IsEnabled() || !FLAG_prof) return; 1609 if (!log_->IsEnabled() || !FLAG_prof) return;
1407 LogMessageBuilder msg(this); 1610 Log::MessageBuilder msg(log_);
1408 msg.Append("%s,", kLogEventsNames[TICK_EVENT]); 1611 msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
1409 msg.AppendAddress(sample->pc); 1612 msg.AppendAddress(sample->pc);
1410 msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_)); 1613 msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_));
1411 if (sample->has_external_callback) { 1614 if (sample->has_external_callback) {
1412 msg.Append(",1,"); 1615 msg.Append(",1,");
1413 msg.AppendAddress(sample->external_callback); 1616 msg.AppendAddress(sample->external_callback);
1414 } else { 1617 } else {
1415 msg.Append(",0,"); 1618 msg.Append(",0,");
1416 msg.AppendAddress(sample->tos); 1619 msg.AppendAddress(sample->tos);
1417 } 1620 }
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 description = "A keyed call IC from the snapshot"; 1798 description = "A keyed call IC from the snapshot";
1596 tag = Logger::KEYED_CALL_IC_TAG; 1799 tag = Logger::KEYED_CALL_IC_TAG;
1597 break; 1800 break;
1598 case Code::NUMBER_OF_KINDS: 1801 case Code::NUMBER_OF_KINDS:
1599 break; 1802 break;
1600 } 1803 }
1601 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); 1804 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
1602 } 1805 }
1603 1806
1604 1807
1605 void Logger::RegisterSnapshotCodeName(Code* code,
1606 const char* name,
1607 int name_size) {
1608 ASSERT(Serializer::enabled());
1609 if (address_to_name_map_ == NULL) {
1610 address_to_name_map_ = new NameMap;
1611 }
1612 address_to_name_map_->Insert(code->address(), name, name_size);
1613 }
1614
1615
1616 LowLevelLogger::LowLevelLogger(const char* name)
1617 : ll_output_handle_(NULL) {
1618 // Open the low-level log file.
1619 size_t len = strlen(name);
1620 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
1621 OS::MemCopy(ll_name.start(), name, len);
1622 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt));
1623 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
1624 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize);
1625
1626 LogCodeInfo();
1627 }
1628
1629
1630 LowLevelLogger::~LowLevelLogger() {
1631 fclose(ll_output_handle_);
1632 ll_output_handle_ = NULL;
1633 }
1634
1635
1636 void LowLevelLogger::LogCodeInfo() {
1637 #if V8_TARGET_ARCH_IA32
1638 const char arch[] = "ia32";
1639 #elif V8_TARGET_ARCH_X64
1640 const char arch[] = "x64";
1641 #elif V8_TARGET_ARCH_ARM
1642 const char arch[] = "arm";
1643 #elif V8_TARGET_ARCH_MIPS
1644 const char arch[] = "mips";
1645 #else
1646 const char arch[] = "unknown";
1647 #endif
1648 LogWriteBytes(arch, sizeof(arch));
1649 }
1650
1651 void LowLevelLogger::CodeCreateEvent(Code* code,
1652 const char* name,
1653 int name_size) {
1654 CodeCreateStruct event;
1655 event.name_size = name_size;
1656 event.code_address = code->instruction_start();
1657 ASSERT(event.code_address == code->address() + Code::kHeaderSize);
1658 event.code_size = code->instruction_size();
1659 LogWriteStruct(event);
1660 LogWriteBytes(name, name_size);
1661 LogWriteBytes(
1662 reinterpret_cast<const char*>(code->instruction_start()),
1663 code->instruction_size());
1664 }
1665
1666
1667 void LowLevelLogger::CodeMoveEvent(Address from, Address to) {
1668 CodeMoveStruct event;
1669 event.from_address = from + Code::kHeaderSize;
1670 event.to_address = to + Code::kHeaderSize;
1671 LogWriteStruct(event);
1672 }
1673
1674
1675 void LowLevelLogger::CodeDeleteEvent(Address from) {
1676 CodeDeleteStruct event;
1677 event.address = from + Code::kHeaderSize;
1678 LogWriteStruct(event);
1679 }
1680
1681
1682 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) {
1683 SnapshotPositionStruct event;
1684 event.address = addr + Code::kHeaderSize;
1685 event.position = pos;
1686 LogWriteStruct(event);
1687 }
1688
1689
1690 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
1691 size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
1692 ASSERT(static_cast<size_t>(size) == rv);
1693 USE(rv);
1694 }
1695
1696
1697 void LowLevelLogger::CodeMovingGCEvent() {
1698 const char tag = kCodeMovingGCTag;
1699
1700 LogWriteBytes(&tag, sizeof(tag));
1701 }
1702
1703
1704 void Logger::LogCodeObjects() { 1808 void Logger::LogCodeObjects() {
1705 Heap* heap = isolate_->heap(); 1809 Heap* heap = isolate_->heap();
1706 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, 1810 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
1707 "Logger::LogCodeObjects"); 1811 "Logger::LogCodeObjects");
1708 HeapIterator iterator(heap); 1812 HeapIterator iterator(heap);
1709 DisallowHeapAllocation no_gc; 1813 DisallowHeapAllocation no_gc;
1710 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 1814 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1711 if (obj->IsCode()) LogCodeObject(obj); 1815 if (obj->IsCode()) LogCodeObject(obj);
1712 } 1816 }
1713 } 1817 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 } 2007 }
1904 2008
1905 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); 2009 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks();
1906 2010
1907 return true; 2011 return true;
1908 } 2012 }
1909 2013
1910 2014
1911 void Logger::SetCodeEventHandler(uint32_t options, 2015 void Logger::SetCodeEventHandler(uint32_t options,
1912 JitCodeEventHandler event_handler) { 2016 JitCodeEventHandler event_handler) {
1913 code_event_handler_ = event_handler; 2017 if (jit_logger_) {
2018 delete jit_logger_;
2019 jit_logger_ = NULL;
2020 }
1914 2021
1915 if (code_event_handler_ != NULL && (options & kJitCodeEventEnumExisting)) { 2022 if (event_handler) {
2023 jit_logger_ = new JitLogger(event_handler);
2024 }
2025
2026 if (jit_logger_ != NULL && (options & kJitCodeEventEnumExisting)) {
1916 HandleScope scope(isolate_); 2027 HandleScope scope(isolate_);
1917 LogCodeObjects(); 2028 LogCodeObjects();
1918 LogCompiledFunctions(); 2029 LogCompiledFunctions();
1919 } 2030 }
1920 } 2031 }
1921 2032
1922 2033
1923 Sampler* Logger::sampler() { 2034 Sampler* Logger::sampler() {
1924 return ticker_; 2035 return ticker_;
1925 } 2036 }
(...skipping 11 matching lines...) Expand all
1937 } 2048 }
1938 2049
1939 delete ticker_; 2050 delete ticker_;
1940 ticker_ = NULL; 2051 ticker_ = NULL;
1941 2052
1942 if (ll_logger_) { 2053 if (ll_logger_) {
1943 delete ll_logger_; 2054 delete ll_logger_;
1944 ll_logger_ = NULL; 2055 ll_logger_ = NULL;
1945 } 2056 }
1946 2057
2058 if (jit_logger_) {
2059 delete jit_logger_;
2060 jit_logger_ = NULL;
2061 }
2062
1947 return log_->Close(); 2063 return log_->Close();
1948 } 2064 }
1949 2065
1950 } } // namespace v8::internal 2066 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/log.h ('k') | src/log-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698