V8 Project
log.cc
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdarg.h>
6 
7 #include "src/v8.h"
8 
9 #include "src/bailout-reason.h"
11 #include "src/bootstrapper.h"
12 #include "src/code-stubs.h"
13 #include "src/cpu-profiler.h"
14 #include "src/deoptimizer.h"
15 #include "src/global-handles.h"
16 #include "src/log.h"
17 #include "src/log-utils.h"
18 #include "src/macro-assembler.h"
19 #include "src/perf-jit.h"
20 #include "src/runtime-profiler.h"
21 #include "src/serialize.h"
22 #include "src/string-stream.h"
23 #include "src/vm-state-inl.h"
24 
25 namespace v8 {
26 namespace internal {
27 
28 
29 #define DECLARE_EVENT(ignore1, name) name,
30 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
32 };
33 #undef DECLARE_EVENT
34 
35 
36 #define CALL_LISTENERS(Call) \
37 for (int i = 0; i < listeners_.length(); ++i) { \
38  listeners_[i]->Call; \
39 }
40 
41 #define PROFILER_LOG(Call) \
42  do { \
43  CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \
44  if (cpu_profiler->is_profiling()) { \
45  cpu_profiler->Call; \
46  } \
47  } while (false);
48 
49 // ComputeMarker must only be used when SharedFunctionInfo is known.
50 static const char* ComputeMarker(Code* code) {
51  switch (code->kind()) {
52  case Code::FUNCTION: return code->optimizable() ? "~" : "";
53  case Code::OPTIMIZED_FUNCTION: return "*";
54  default: return "";
55  }
56 }
57 
58 
60  public:
61  NameBuffer() { Reset(); }
62 
63  void Reset() {
64  utf8_pos_ = 0;
65  }
66 
68  Reset();
70  AppendByte(':');
71  }
72 
73  void AppendName(Name* name) {
74  if (name->IsString()) {
75  AppendString(String::cast(name));
76  } else {
77  Symbol* symbol = Symbol::cast(name);
78  AppendBytes("symbol(");
79  if (!symbol->name()->IsUndefined()) {
80  AppendBytes("\"");
81  AppendString(String::cast(symbol->name()));
82  AppendBytes("\" ");
83  }
84  AppendBytes("hash ");
85  AppendHex(symbol->Hash());
86  AppendByte(')');
87  }
88  }
89 
90  void AppendString(String* str) {
91  if (str == NULL) return;
92  int uc16_length = Min(str->length(), kUtf16BufferSize);
93  String::WriteToFlat(str, utf16_buffer, 0, uc16_length);
95  for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
96  uc16 c = utf16_buffer[i];
98  utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
99  } else {
100  int char_length = unibrow::Utf8::Length(c, previous);
101  if (utf8_pos_ + char_length > kUtf8BufferSize) break;
103  utf8_pos_ += char_length;
104  }
105  previous = c;
106  }
107  }
108 
109  void AppendBytes(const char* bytes, int size) {
111  MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
112  utf8_pos_ += size;
113  }
114 
115  void AppendBytes(const char* bytes) {
116  AppendBytes(bytes, StrLength(bytes));
117  }
118 
119  void AppendByte(char c) {
120  if (utf8_pos_ >= kUtf8BufferSize) return;
121  utf8_buffer_[utf8_pos_++] = c;
122  }
123 
124  void AppendInt(int n) {
127  int size = SNPrintF(buffer, "%d", n);
128  if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
129  utf8_pos_ += size;
130  }
131  }
132 
133  void AppendHex(uint32_t n) {
136  int size = SNPrintF(buffer, "%x", n);
137  if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
138  utf8_pos_ += size;
139  }
140  }
141 
142  const char* get() { return utf8_buffer_; }
143  int size() const { return utf8_pos_; }
144 
145  private:
146  static const int kUtf8BufferSize = 512;
147  static const int kUtf16BufferSize = 128;
148 
152 };
153 
154 
156 
158 
159 
161  Code* code,
162  const char* comment) {
163  name_buffer_->Init(tag);
164  name_buffer_->AppendBytes(comment);
166 }
167 
168 
170  Code* code,
171  Name* name) {
172  name_buffer_->Init(tag);
175 }
176 
177 
179  Code* code,
180  SharedFunctionInfo* shared,
181  CompilationInfo* info,
182  Name* name) {
183  name_buffer_->Init(tag);
186  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
187 }
188 
189 
191  Code* code,
192  SharedFunctionInfo* shared,
193  CompilationInfo* info,
194  Name* source, int line, int column) {
195  name_buffer_->Init(tag);
197  name_buffer_->AppendString(shared->DebugName());
198  name_buffer_->AppendByte(' ');
199  if (source->IsString()) {
200  name_buffer_->AppendString(String::cast(source));
201  } else {
202  name_buffer_->AppendBytes("symbol(hash ");
203  name_buffer_->AppendHex(Name::cast(source)->Hash());
204  name_buffer_->AppendByte(')');
205  }
206  name_buffer_->AppendByte(':');
207  name_buffer_->AppendInt(line);
208  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
209 }
210 
211 
213  Code* code,
214  int args_count) {
215  name_buffer_->Init(tag);
216  name_buffer_->AppendInt(args_count);
218 }
219 
220 
222  name_buffer_->Init(Logger::REG_EXP_TAG);
223  name_buffer_->AppendString(source);
225 }
226 
227 
228 // Linux perf tool logging support
230  public:
231  PerfBasicLogger();
232  virtual ~PerfBasicLogger();
233 
234  virtual void CodeMoveEvent(Address from, Address to) { }
235  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
236  virtual void CodeDeleteEvent(Address from) { }
237 
238  private:
239  virtual void LogRecordedBuffer(Code* code,
240  SharedFunctionInfo* shared,
241  const char* name,
242  int length);
243 
244  // Extension added to V8 log file name to get the low-level log name.
245  static const char kFilenameFormatString[];
246  static const int kFilenameBufferPadding;
247 
248  // File buffer size of the low-level log. We don't use the default to
249  // minimize the associated overhead.
250  static const int kLogBufferSize = 2 * MB;
251 
253 };
254 
255 const char PerfBasicLogger::kFilenameFormatString[] = "/tmp/perf-%d.map";
256 // Extra space for the PID in the filename
258 
260  : perf_output_handle_(NULL) {
261  // Open the perf JIT dump file.
262  int bufferSize = sizeof(kFilenameFormatString) + kFilenameBufferPadding;
263  ScopedVector<char> perf_dump_name(bufferSize);
264  int size = SNPrintF(
265  perf_dump_name,
268  CHECK_NE(size, -1);
272  setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize);
273 }
274 
275 
277  fclose(perf_output_handle_);
279 }
280 
281 
284  const char* name,
285  int length) {
286  DCHECK(code->instruction_start() == code->address() + Code::kHeaderSize);
287 
288  base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n",
289  reinterpret_cast<uint64_t>(code->instruction_start()),
290  code->instruction_size(), length, name);
291 }
292 
293 
294 // Low-level logging support.
295 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call;
296 
298  public:
299  explicit LowLevelLogger(const char* file_name);
300  virtual ~LowLevelLogger();
301 
302  virtual void CodeMoveEvent(Address from, Address to);
303  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
304  virtual void CodeDeleteEvent(Address from);
305  virtual void SnapshotPositionEvent(Address addr, int pos);
306  virtual void CodeMovingGCEvent();
307 
308  private:
309  virtual void LogRecordedBuffer(Code* code,
310  SharedFunctionInfo* shared,
311  const char* name,
312  int length);
313 
314  // Low-level profiling event structures.
316  static const char kTag = 'C';
317 
321  };
322 
323 
324  struct CodeMoveStruct {
325  static const char kTag = 'M';
326 
329  };
330 
331 
333  static const char kTag = 'D';
334 
336  };
337 
338 
340  static const char kTag = 'P';
341 
344  };
345 
346 
347  static const char kCodeMovingGCTag = 'G';
348 
349 
350  // Extension added to V8 log file name to get the low-level log name.
351  static const char kLogExt[];
352 
353  // File buffer size of the low-level log. We don't use the default to
354  // minimize the associated overhead.
355  static const int kLogBufferSize = 2 * MB;
356 
357  void LogCodeInfo();
358  void LogWriteBytes(const char* bytes, int size);
359 
360  template <typename T>
361  void LogWriteStruct(const T& s) {
362  char tag = T::kTag;
363  LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
364  LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
365  }
366 
368 };
369 
370 const char LowLevelLogger::kLogExt[] = ".ll";
371 
373  : ll_output_handle_(NULL) {
374  // Open the low-level log file.
375  size_t len = strlen(name);
376  ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
377  MemCopy(ll_name.start(), name, len);
378  MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt));
381  setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize);
382 
383  LogCodeInfo();
384 }
385 
386 
388  fclose(ll_output_handle_);
390 }
391 
392 
394 #if V8_TARGET_ARCH_IA32
395  const char arch[] = "ia32";
396 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
397  const char arch[] = "x64";
398 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
399  const char arch[] = "x32";
400 #elif V8_TARGET_ARCH_ARM
401  const char arch[] = "arm";
402 #elif V8_TARGET_ARCH_MIPS
403  const char arch[] = "mips";
404 #elif V8_TARGET_ARCH_X87
405  const char arch[] = "x87";
406 #elif V8_TARGET_ARCH_ARM64
407  const char arch[] = "arm64";
408 #else
409  const char arch[] = "unknown";
410 #endif
411  LogWriteBytes(arch, sizeof(arch));
412 }
413 
414 
417  const char* name,
418  int length) {
419  CodeCreateStruct event;
420  event.name_size = length;
421  event.code_address = code->instruction_start();
422  DCHECK(event.code_address == code->address() + Code::kHeaderSize);
423  event.code_size = code->instruction_size();
424  LogWriteStruct(event);
425  LogWriteBytes(name, length);
427  reinterpret_cast<const char*>(code->instruction_start()),
428  code->instruction_size());
429 }
430 
431 
433  CodeMoveStruct event;
434  event.from_address = from + Code::kHeaderSize;
435  event.to_address = to + Code::kHeaderSize;
436  LogWriteStruct(event);
437 }
438 
439 
441  CodeDeleteStruct event;
442  event.address = from + Code::kHeaderSize;
443  LogWriteStruct(event);
444 }
445 
446 
449  event.address = addr + Code::kHeaderSize;
450  event.position = pos;
451  LogWriteStruct(event);
452 }
453 
454 
455 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
456  size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
457  DCHECK(static_cast<size_t>(size) == rv);
458  USE(rv);
459 }
460 
461 
463  const char tag = kCodeMovingGCTag;
464 
465  LogWriteBytes(&tag, sizeof(tag));
466 }
467 
468 
469 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call;
470 
471 
472 class JitLogger : public CodeEventLogger {
473  public:
474  explicit JitLogger(JitCodeEventHandler code_event_handler);
475 
476  virtual void CodeMoveEvent(Address from, Address to);
477  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
478  virtual void CodeDeleteEvent(Address from);
479  virtual void AddCodeLinePosInfoEvent(
480  void* jit_handler_data,
481  int pc_offset,
482  int position,
483  JitCodeEvent::PositionType position_type);
484 
485  void* StartCodePosInfoEvent();
486  void EndCodePosInfoEvent(Code* code, void* jit_handler_data);
487 
488  private:
489  virtual void LogRecordedBuffer(Code* code,
490  SharedFunctionInfo* shared,
491  const char* name,
492  int length);
493 
495 };
496 
497 
499  : code_event_handler_(code_event_handler) {
500 }
501 
502 
504  SharedFunctionInfo* shared,
505  const char* name,
506  int length) {
507  JitCodeEvent event;
508  memset(&event, 0, sizeof(event));
509  event.type = JitCodeEvent::CODE_ADDED;
510  event.code_start = code->instruction_start();
511  event.code_len = code->instruction_size();
512  Handle<SharedFunctionInfo> shared_function_handle;
513  if (shared && shared->script()->IsScript()) {
514  shared_function_handle = Handle<SharedFunctionInfo>(shared);
515  }
516  event.script = ToApiHandle<v8::UnboundScript>(shared_function_handle);
517  event.name.str = name;
518  event.name.len = length;
519  code_event_handler_(&event);
520 }
521 
522 
524  Code* from_code = Code::cast(HeapObject::FromAddress(from));
525 
526  JitCodeEvent event;
528  event.code_start = from_code->instruction_start();
529  event.code_len = from_code->instruction_size();
530 
531  // Calculate the header size.
532  const size_t header_size =
533  from_code->instruction_start() - reinterpret_cast<byte*>(from_code);
534 
535  // Calculate the new start address of the instructions.
536  event.new_code_start =
537  reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size;
538 
539  code_event_handler_(&event);
540 }
541 
542 
544  Code* from_code = Code::cast(HeapObject::FromAddress(from));
545 
546  JitCodeEvent event;
548  event.code_start = from_code->instruction_start();
549  event.code_len = from_code->instruction_size();
550 
551  code_event_handler_(&event);
552 }
553 
555  void* jit_handler_data,
556  int pc_offset,
557  int position,
558  JitCodeEvent::PositionType position_type) {
559  JitCodeEvent event;
560  memset(&event, 0, sizeof(event));
562  event.user_data = jit_handler_data;
563  event.line_info.offset = pc_offset;
564  event.line_info.pos = position;
565  event.line_info.position_type = position_type;
566 
567  code_event_handler_(&event);
568 }
569 
570 
572  JitCodeEvent event;
573  memset(&event, 0, sizeof(event));
575 
576  code_event_handler_(&event);
577  return event.user_data;
578 }
579 
580 
581 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) {
582  JitCodeEvent event;
583  memset(&event, 0, sizeof(event));
585  event.code_start = code->instruction_start();
586  event.user_data = jit_handler_data;
587 
588  code_event_handler_(&event);
589 }
590 
591 
592 // The Profiler samples pc and sp values for the main thread.
593 // Each sample is appended to a circular buffer.
594 // An independent thread removes data and writes it to the log.
595 // This design minimizes the time spent in the sampler.
596 //
597 class Profiler: public base::Thread {
598  public:
599  explicit Profiler(Isolate* isolate);
600  void Engage();
601  void Disengage();
602 
603  // Inserts collected profiling data into buffer.
604  void Insert(TickSample* sample) {
605  if (paused_)
606  return;
607 
608  if (Succ(head_) == tail_) {
609  overflow_ = true;
610  } else {
611  buffer_[head_] = *sample;
612  head_ = Succ(head_);
613  buffer_semaphore_.Signal(); // Tell we have an element.
614  }
615  }
616 
617  virtual void Run();
618 
619  // Pause and Resume TickSample data collection.
620  void pause() { paused_ = true; }
621  void resume() { paused_ = false; }
622 
623  private:
624  // Waits for a signal and removes profiling data.
625  bool Remove(TickSample* sample) {
626  buffer_semaphore_.Wait(); // Wait for an element.
627  *sample = buffer_[tail_];
628  bool result = overflow_;
629  tail_ = Succ(tail_);
630  overflow_ = false;
631  return result;
632  }
633 
634  // Returns the next index in the cyclic buffer.
635  int Succ(int index) { return (index + 1) % kBufferSize; }
636 
638  // Cyclic buffer for communicating profiling samples
639  // between the signal handler and the worker thread.
640  static const int kBufferSize = 128;
641  TickSample buffer_[kBufferSize]; // Buffer storage.
642  int head_; // Index to the buffer head.
643  int tail_; // Index to the buffer tail.
644  bool overflow_; // Tell whether a buffer overflow has occurred.
645  // Sempahore used for buffer synchronization.
646  base::Semaphore buffer_semaphore_;
647 
648  // Tells whether profiler is engaged, that is, processing thread is stated.
649  bool engaged_;
650 
651  // Tells whether worker thread should continue running.
652  bool running_;
653 
654  // Tells whether we are currently recording tick samples.
655  bool paused_;
656 };
657 
658 
659 //
660 // Ticker used to provide ticks to the profiler and the sliding state
661 // window.
662 //
663 class Ticker: public Sampler {
664  public:
667  profiler_(NULL) {}
668 
669  ~Ticker() { if (IsActive()) Stop(); }
670 
671  virtual void Tick(TickSample* sample) {
672  if (profiler_) profiler_->Insert(sample);
673  }
674 
676  DCHECK(profiler_ == NULL);
679  if (!IsActive()) Start();
680  }
681 
682  void ClearProfiler() {
683  profiler_ = NULL;
684  if (IsActive()) Stop();
686  }
687 
688  private:
690 };
691 
692 
693 //
694 // Profiler implementation.
695 //
697  : base::Thread(Options("v8:Profiler")),
698  isolate_(isolate),
699  head_(0),
700  tail_(0),
701  overflow_(false),
702  buffer_semaphore_(0),
703  engaged_(false),
704  running_(false),
705  paused_(false) {}
706 
707 
709  if (engaged_) return;
710  engaged_ = true;
711 
712  std::vector<base::OS::SharedLibraryAddress> addresses =
714  for (size_t i = 0; i < addresses.size(); ++i) {
715  LOG(isolate_, SharedLibraryEvent(
716  addresses[i].library_path, addresses[i].start, addresses[i].end));
717  }
718 
719  // Start thread processing the profiler buffer.
720  running_ = true;
721  Start();
722 
723  // Register to get ticks.
724  Logger* logger = isolate_->logger();
725  logger->ticker_->SetProfiler(this);
726 
727  logger->ProfilerBeginEvent();
728 }
729 
730 
732  if (!engaged_) return;
733 
734  // Stop receiving ticks.
736 
737  // Terminate the worker thread by setting running_ to false,
738  // inserting a fake element in the queue and then wait for
739  // the thread to terminate.
740  running_ = false;
741  TickSample sample;
742  // Reset 'paused_' flag, otherwise semaphore may not be signalled.
743  resume();
744  Insert(&sample);
745  Join();
746 
747  LOG(isolate_, UncheckedStringEvent("profiler", "end"));
748 }
749 
750 
752  TickSample sample;
753  bool overflow = Remove(&sample);
754  while (running_) {
755  LOG(isolate_, TickEvent(&sample, overflow));
756  overflow = Remove(&sample);
757  }
758 }
759 
760 
761 //
762 // Logger class implementation.
763 //
764 
766  : isolate_(isolate),
767  ticker_(NULL),
768  profiler_(NULL),
769  log_events_(NULL),
770  is_logging_(false),
771  log_(new Log(this)),
772  perf_basic_logger_(NULL),
773  perf_jit_logger_(NULL),
774  ll_logger_(NULL),
775  jit_logger_(NULL),
776  listeners_(5),
777  is_initialized_(false) {
778 }
779 
780 
782  delete log_;
783 }
784 
785 
787  DCHECK(!hasCodeEventListener(listener));
788  listeners_.Add(listener);
789 }
790 
791 
793  DCHECK(hasCodeEventListener(listener));
794  listeners_.RemoveElement(listener);
795 }
796 
797 
799  return listeners_.Contains(listener);
800 }
801 
802 
804  if (!log_->IsEnabled()) return;
805  Log::MessageBuilder msg(log_);
806  msg.Append("profiler,\"begin\",%d", kSamplingIntervalMs);
807  msg.WriteToLogFile();
808 }
809 
810 
811 void Logger::StringEvent(const char* name, const char* value) {
812  if (FLAG_log) UncheckedStringEvent(name, value);
813 }
814 
815 
816 void Logger::UncheckedStringEvent(const char* name, const char* value) {
817  if (!log_->IsEnabled()) return;
818  Log::MessageBuilder msg(log_);
819  msg.Append("%s,\"%s\"", name, value);
820  msg.WriteToLogFile();
821 }
822 
823 
824 void Logger::IntEvent(const char* name, int value) {
825  if (FLAG_log) UncheckedIntEvent(name, value);
826 }
827 
828 
829 void Logger::IntPtrTEvent(const char* name, intptr_t value) {
830  if (FLAG_log) UncheckedIntPtrTEvent(name, value);
831 }
832 
833 
834 void Logger::UncheckedIntEvent(const char* name, int value) {
835  if (!log_->IsEnabled()) return;
836  Log::MessageBuilder msg(log_);
837  msg.Append("%s,%d", name, value);
838  msg.WriteToLogFile();
839 }
840 
841 
842 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
843  if (!log_->IsEnabled()) return;
844  Log::MessageBuilder msg(log_);
845  msg.Append("%s,%" V8_PTR_PREFIX "d", name, value);
846  msg.WriteToLogFile();
847 }
848 
849 
850 void Logger::HandleEvent(const char* name, Object** location) {
851  if (!log_->IsEnabled() || !FLAG_log_handles) return;
852  Log::MessageBuilder msg(log_);
853  msg.Append("%s,0x%" V8PRIxPTR, name, location);
854  msg.WriteToLogFile();
855 }
856 
857 
858 // ApiEvent is private so all the calls come from the Logger class. It is the
859 // caller's responsibility to ensure that log is enabled and that
860 // FLAG_log_api is true.
861 void Logger::ApiEvent(const char* format, ...) {
862  DCHECK(log_->IsEnabled() && FLAG_log_api);
863  Log::MessageBuilder msg(log_);
864  va_list ap;
865  va_start(ap, format);
866  msg.AppendVA(format, ap);
867  va_end(ap);
868  msg.WriteToLogFile();
869 }
870 
871 
873  if (!log_->IsEnabled() || !FLAG_log_api) return;
874  if (key->IsString()) {
876  String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
877  ApiEvent("api,check-security,\"%s\"", str.get());
878  } else if (key->IsSymbol()) {
879  Symbol* symbol = Symbol::cast(key);
880  if (symbol->name()->IsUndefined()) {
881  ApiEvent("api,check-security,symbol(hash %x)", Symbol::cast(key)->Hash());
882  } else {
883  SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
885  ApiEvent("api,check-security,symbol(\"%s\" hash %x)", str.get(),
886  Symbol::cast(key)->Hash());
887  }
888  } else if (key->IsUndefined()) {
889  ApiEvent("api,check-security,undefined");
890  } else {
891  ApiEvent("api,check-security,['no-name']");
892  }
893 }
894 
895 
896 void Logger::SharedLibraryEvent(const std::string& library_path,
897  uintptr_t start,
898  uintptr_t end) {
899  if (!log_->IsEnabled() || !FLAG_prof) return;
900  Log::MessageBuilder msg(log_);
901  msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR,
902  library_path.c_str(), start, end);
903  msg.WriteToLogFile();
904 }
905 
906 
908  if (!log_->IsEnabled()) return;
909  DCHECK(FLAG_log_internal_timer_events);
910  Log::MessageBuilder msg(log_);
911  int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
912  msg.Append("code-deopt,%ld,%d", since_epoch, code->CodeSize());
913  msg.WriteToLogFile();
914 }
915 
916 
918  if (!log_->IsEnabled()) return;
919  DCHECK(FLAG_log_internal_timer_events);
920  Log::MessageBuilder msg(log_);
921  int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
922  msg.Append("current-time,%ld", since_epoch);
923  msg.WriteToLogFile();
924 }
925 
926 
927 void Logger::TimerEvent(Logger::StartEnd se, const char* name) {
928  if (!log_->IsEnabled()) return;
929  DCHECK(FLAG_log_internal_timer_events);
930  Log::MessageBuilder msg(log_);
931  int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
932  const char* format = (se == START) ? "timer-event-start,\"%s\",%ld"
933  : "timer-event-end,\"%s\",%ld";
934  msg.Append(format, name, since_epoch);
935  msg.WriteToLogFile();
936 }
937 
938 
941  DCHECK(isolate->current_vm_state() == JS);
942  isolate->set_current_vm_state(EXTERNAL);
943 }
944 
945 
948  DCHECK(isolate->current_vm_state() == EXTERNAL);
949  isolate->set_current_vm_state(JS);
950 }
951 
952 
953 void Logger::DefaultTimerEventsLogger(const char* name, int se) {
954  Isolate* isolate = Isolate::Current();
955  LOG(isolate, TimerEvent(static_cast<StartEnd>(se), name));
956 }
957 
958 
959 template <class TimerEvent>
961  if (TimerEvent::expose_to_api() ||
962  isolate_->event_logger() == Logger::DefaultTimerEventsLogger) {
963  isolate_->event_logger()(TimerEvent::name(), se);
964  }
965 }
966 
967 
968 // Instantiate template methods.
969 #define V(TimerName, expose) \
970  template void TimerEventScope<TimerEvent##TimerName>::LogTimerEvent( \
971  Logger::StartEnd se);
973 #undef V
974 
975 
977  // Prints "/" + re.source + "/" +
978  // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
979  Log::MessageBuilder msg(log_);
980 
982  isolate_, regexp, "source").ToHandleChecked();
983  if (!source->IsString()) {
984  msg.Append("no source");
985  return;
986  }
987 
988  switch (regexp->TypeTag()) {
989  case JSRegExp::ATOM:
990  msg.Append('a');
991  break;
992  default:
993  break;
994  }
995  msg.Append('/');
996  msg.AppendDetailed(*Handle<String>::cast(source), false);
997  msg.Append('/');
998 
999  // global flag
1001  isolate_, regexp, "global").ToHandleChecked();
1002  if (global->IsTrue()) {
1003  msg.Append('g');
1004  }
1005  // ignorecase flag
1006  Handle<Object> ignorecase = Object::GetProperty(
1007  isolate_, regexp, "ignoreCase").ToHandleChecked();
1008  if (ignorecase->IsTrue()) {
1009  msg.Append('i');
1010  }
1011  // multiline flag
1012  Handle<Object> multiline = Object::GetProperty(
1013  isolate_, regexp, "multiline").ToHandleChecked();
1014  if (multiline->IsTrue()) {
1015  msg.Append('m');
1016  }
1017 
1018  msg.WriteToLogFile();
1019 }
1020 
1021 
1022 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
1023  if (!log_->IsEnabled() || !FLAG_log_regexp) return;
1024  Log::MessageBuilder msg(log_);
1025  msg.Append("regexp-compile,");
1026  LogRegExpSource(regexp);
1027  msg.Append(in_cache ? ",hit" : ",miss");
1028  msg.WriteToLogFile();
1029 }
1030 
1031 
1033  if (!log_->IsEnabled() || !FLAG_log_api) return;
1034  ApiEvent("api,check-security,%u", index);
1035 }
1036 
1037 
1038 void Logger::ApiNamedPropertyAccess(const char* tag,
1039  JSObject* holder,
1040  Object* name) {
1041  DCHECK(name->IsName());
1042  if (!log_->IsEnabled() || !FLAG_log_api) return;
1043  String* class_name_obj = holder->class_name();
1044  SmartArrayPointer<char> class_name =
1046  if (name->IsString()) {
1047  SmartArrayPointer<char> property_name =
1048  String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1049  ApiEvent("api,%s,\"%s\",\"%s\"", tag, class_name.get(),
1050  property_name.get());
1051  } else {
1052  Symbol* symbol = Symbol::cast(name);
1053  uint32_t hash = symbol->Hash();
1054  if (symbol->name()->IsUndefined()) {
1055  ApiEvent("api,%s,\"%s\",symbol(hash %x)", tag, class_name.get(), hash);
1056  } else {
1057  SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
1059  ApiEvent("api,%s,\"%s\",symbol(\"%s\" hash %x)", tag, class_name.get(),
1060  str.get(), hash);
1061  }
1062  }
1063 }
1064 
1066  JSObject* holder,
1067  uint32_t index) {
1068  if (!log_->IsEnabled() || !FLAG_log_api) return;
1069  String* class_name_obj = holder->class_name();
1070  SmartArrayPointer<char> class_name =
1072  ApiEvent("api,%s,\"%s\",%u", tag, class_name.get(), index);
1073 }
1074 
1075 
1076 void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
1077  if (!log_->IsEnabled() || !FLAG_log_api) return;
1078  String* class_name_obj = object->class_name();
1079  SmartArrayPointer<char> class_name =
1081  ApiEvent("api,%s,\"%s\"", tag, class_name.get());
1082 }
1083 
1084 
1085 void Logger::ApiEntryCall(const char* name) {
1086  if (!log_->IsEnabled() || !FLAG_log_api) return;
1087  ApiEvent("api,%s", name);
1088 }
1089 
1090 
1091 void Logger::NewEvent(const char* name, void* object, size_t size) {
1092  if (!log_->IsEnabled() || !FLAG_log) return;
1093  Log::MessageBuilder msg(log_);
1094  msg.Append("new,%s,0x%" V8PRIxPTR ",%u", name, object,
1095  static_cast<unsigned int>(size));
1096  msg.WriteToLogFile();
1097 }
1098 
1099 
1100 void Logger::DeleteEvent(const char* name, void* object) {
1101  if (!log_->IsEnabled() || !FLAG_log) return;
1102  Log::MessageBuilder msg(log_);
1103  msg.Append("delete,%s,0x%" V8PRIxPTR, name, object);
1104  msg.WriteToLogFile();
1105 }
1106 
1107 
1108 void Logger::NewEventStatic(const char* name, void* object, size_t size) {
1109  Isolate::Current()->logger()->NewEvent(name, object, size);
1110 }
1111 
1112 
1113 void Logger::DeleteEventStatic(const char* name, void* object) {
1114  Isolate::Current()->logger()->DeleteEvent(name, object);
1115 }
1116 
1117 
1118 void Logger::CallbackEventInternal(const char* prefix, Name* name,
1119  Address entry_point) {
1120  if (!FLAG_log_code || !log_->IsEnabled()) return;
1121  Log::MessageBuilder msg(log_);
1122  msg.Append("%s,%s,-2,",
1123  kLogEventsNames[CODE_CREATION_EVENT],
1124  kLogEventsNames[CALLBACK_TAG]);
1125  msg.AppendAddress(entry_point);
1126  if (name->IsString()) {
1128  String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1129  msg.Append(",1,\"%s%s\"", prefix, str.get());
1130  } else {
1131  Symbol* symbol = Symbol::cast(name);
1132  if (symbol->name()->IsUndefined()) {
1133  msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash());
1134  } else {
1135  SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
1137  msg.Append(",1,symbol(\"%s\" hash %x)", prefix, str.get(),
1138  symbol->Hash());
1139  }
1140  }
1141  msg.WriteToLogFile();
1142 }
1143 
1144 
1146  PROFILER_LOG(CallbackEvent(name, entry_point));
1147  CallbackEventInternal("", name, entry_point);
1148 }
1149 
1150 
1152  PROFILER_LOG(GetterCallbackEvent(name, entry_point));
1153  CallbackEventInternal("get ", name, entry_point);
1154 }
1155 
1156 
1158  PROFILER_LOG(SetterCallbackEvent(name, entry_point));
1159  CallbackEventInternal("set ", name, entry_point);
1160 }
1161 
1162 
1163 static void AppendCodeCreateHeader(Log::MessageBuilder* msg,
1165  Code* code) {
1166  DCHECK(msg);
1167  msg->Append("%s,%s,%d,",
1168  kLogEventsNames[Logger::CODE_CREATION_EVENT],
1169  kLogEventsNames[tag],
1170  code->kind());
1171  msg->AppendAddress(code->address());
1172  msg->Append(",%d,", code->ExecutableSize());
1173 }
1174 
1175 
1177  Code* code,
1178  const char* comment) {
1179  PROFILER_LOG(CodeCreateEvent(tag, code, comment));
1180 
1181  if (!is_logging_code_events()) return;
1182  CALL_LISTENERS(CodeCreateEvent(tag, code, comment));
1183 
1184  if (!FLAG_log_code || !log_->IsEnabled()) return;
1185  Log::MessageBuilder msg(log_);
1186  AppendCodeCreateHeader(&msg, tag, code);
1187  msg.AppendDoubleQuotedString(comment);
1188  msg.WriteToLogFile();
1189 }
1190 
1191 
1193  Code* code,
1194  Name* name) {
1195  PROFILER_LOG(CodeCreateEvent(tag, code, name));
1196 
1197  if (!is_logging_code_events()) return;
1198  CALL_LISTENERS(CodeCreateEvent(tag, code, name));
1199 
1200  if (!FLAG_log_code || !log_->IsEnabled()) return;
1201  Log::MessageBuilder msg(log_);
1202  AppendCodeCreateHeader(&msg, tag, code);
1203  if (name->IsString()) {
1204  msg.Append('"');
1205  msg.AppendDetailed(String::cast(name), false);
1206  msg.Append('"');
1207  } else {
1208  msg.AppendSymbolName(Symbol::cast(name));
1209  }
1210  msg.WriteToLogFile();
1211 }
1212 
1213 
1215  Code* code,
1216  SharedFunctionInfo* shared,
1217  CompilationInfo* info,
1218  Name* name) {
1219  PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name));
1220 
1221  if (!is_logging_code_events()) return;
1222  CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name));
1223 
1224  if (!FLAG_log_code || !log_->IsEnabled()) return;
1225  if (code == isolate_->builtins()->builtin(Builtins::kCompileLazy)) return;
1226 
1227  Log::MessageBuilder msg(log_);
1228  AppendCodeCreateHeader(&msg, tag, code);
1229  if (name->IsString()) {
1231  String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1232  msg.Append("\"%s\"", str.get());
1233  } else {
1234  msg.AppendSymbolName(Symbol::cast(name));
1235  }
1236  msg.Append(',');
1237  msg.AppendAddress(shared->address());
1238  msg.Append(",%s", ComputeMarker(code));
1239  msg.WriteToLogFile();
1240 }
1241 
1242 
1243 // Although, it is possible to extract source and line from
1244 // the SharedFunctionInfo object, we left it to caller
1245 // to leave logging functions free from heap allocations.
1247  Code* code,
1248  SharedFunctionInfo* shared,
1249  CompilationInfo* info,
1250  Name* source, int line, int column) {
1251  PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column));
1252 
1253  if (!is_logging_code_events()) return;
1254  CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line,
1255  column));
1256 
1257  if (!FLAG_log_code || !log_->IsEnabled()) return;
1258  Log::MessageBuilder msg(log_);
1259  AppendCodeCreateHeader(&msg, tag, code);
1262  msg.Append("\"%s ", name.get());
1263  if (source->IsString()) {
1264  SmartArrayPointer<char> sourcestr =
1265  String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1266  msg.Append("%s", sourcestr.get());
1267  } else {
1268  msg.AppendSymbolName(Symbol::cast(source));
1269  }
1270  msg.Append(":%d:%d\",", line, column);
1271  msg.AppendAddress(shared->address());
1272  msg.Append(",%s", ComputeMarker(code));
1273  msg.WriteToLogFile();
1274 }
1275 
1276 
1278  Code* code,
1279  int args_count) {
1280  PROFILER_LOG(CodeCreateEvent(tag, code, args_count));
1281 
1282  if (!is_logging_code_events()) return;
1283  CALL_LISTENERS(CodeCreateEvent(tag, code, args_count));
1284 
1285  if (!FLAG_log_code || !log_->IsEnabled()) return;
1286  Log::MessageBuilder msg(log_);
1287  AppendCodeCreateHeader(&msg, tag, code);
1288  msg.Append("\"args_count: %d\"", args_count);
1289  msg.WriteToLogFile();
1290 }
1291 
1292 
1294  SharedFunctionInfo* shared) {
1295  PROFILER_LOG(CodeDisableOptEvent(code, shared));
1296 
1297  if (!is_logging_code_events()) return;
1298  CALL_LISTENERS(CodeDisableOptEvent(code, shared));
1299 
1300  if (!FLAG_log_code || !log_->IsEnabled()) return;
1301  Log::MessageBuilder msg(log_);
1302  msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]);
1305  msg.Append("\"%s\",", name.get());
1306  msg.Append("\"%s\"", GetBailoutReason(shared->DisableOptimizationReason()));
1307  msg.WriteToLogFile();
1308 }
1309 
1310 
1313 
1314  if (!is_logging_code_events()) return;
1315  if (!log_->IsEnabled() || !FLAG_ll_prof) return;
1318 }
1319 
1320 
1322  PROFILER_LOG(RegExpCodeCreateEvent(code, source));
1323 
1324  if (!is_logging_code_events()) return;
1325  CALL_LISTENERS(RegExpCodeCreateEvent(code, source));
1326 
1327  if (!FLAG_log_code || !log_->IsEnabled()) return;
1328  Log::MessageBuilder msg(log_);
1329  AppendCodeCreateHeader(&msg, REG_EXP_TAG, code);
1330  msg.Append('"');
1331  msg.AppendDetailed(source, false);
1332  msg.Append('"');
1333  msg.WriteToLogFile();
1334 }
1335 
1336 
1338  PROFILER_LOG(CodeMoveEvent(from, to));
1339 
1340  if (!is_logging_code_events()) return;
1342  MoveEventInternal(CODE_MOVE_EVENT, from, to);
1343 }
1344 
1345 
1348 
1349  if (!is_logging_code_events()) return;
1351 
1352  if (!FLAG_log_code || !log_->IsEnabled()) return;
1353  Log::MessageBuilder msg(log_);
1354  msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]);
1355  msg.AppendAddress(from);
1356  msg.WriteToLogFile();
1357 }
1358 
1359 
1360 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
1361  int pc_offset,
1362  int position) {
1363  JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1364  pc_offset,
1365  position,
1367 }
1368 
1369 
1371  int pc_offset,
1372  int position) {
1373  JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
1374  pc_offset,
1375  position,
1377 }
1378 
1379 
1380 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) {
1381  if (jit_logger_ != NULL) {
1382  pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent());
1383  }
1384 }
1385 
1386 
1388  void* jit_handler_data) {
1389  JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data));
1390 }
1391 
1392 
1393 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
1394  if (code_name == NULL) return; // Not a code object.
1395  Log::MessageBuilder msg(log_);
1396  msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
1397  msg.AppendDoubleQuotedString(code_name);
1398  msg.WriteToLogFile();
1399 }
1400 
1401 
1403  if (!log_->IsEnabled()) return;
1404  LL_LOG(SnapshotPositionEvent(addr, pos));
1405  if (!FLAG_log_snapshot_positions) return;
1406  Log::MessageBuilder msg(log_);
1407  msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
1408  msg.AppendAddress(addr);
1409  msg.Append(",%d", pos);
1410  msg.WriteToLogFile();
1411 }
1412 
1413 
1416 
1417  if (!is_logging_code_events()) return;
1418  MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
1419 }
1420 
1421 
1423  Address from,
1424  Address to) {
1425  if (!FLAG_log_code || !log_->IsEnabled()) return;
1426  Log::MessageBuilder msg(log_);
1427  msg.Append("%s,", kLogEventsNames[event]);
1428  msg.AppendAddress(from);
1429  msg.Append(',');
1430  msg.AppendAddress(to);
1431  msg.WriteToLogFile();
1432 }
1433 
1434 
1435 void Logger::ResourceEvent(const char* name, const char* tag) {
1436  if (!log_->IsEnabled() || !FLAG_log) return;
1437  Log::MessageBuilder msg(log_);
1438  msg.Append("%s,%s,", name, tag);
1439 
1440  uint32_t sec, usec;
1441  if (base::OS::GetUserTime(&sec, &usec) != -1) {
1442  msg.Append("%d,%d,", sec, usec);
1443  }
1444  msg.Append("%.0f", base::OS::TimeCurrentMillis());
1445  msg.WriteToLogFile();
1446 }
1447 
1448 
1450  if (!log_->IsEnabled() || !FLAG_log_suspect) return;
1451  Log::MessageBuilder msg(log_);
1452  String* class_name = obj->IsJSObject()
1453  ? JSObject::cast(obj)->class_name()
1454  : isolate_->heap()->empty_string();
1455  msg.Append("suspect-read,");
1456  msg.Append(class_name);
1457  msg.Append(',');
1458  if (name->IsString()) {
1459  msg.Append('"');
1460  msg.Append(String::cast(name));
1461  msg.Append('"');
1462  } else {
1463  msg.AppendSymbolName(Symbol::cast(name));
1464  }
1465  msg.WriteToLogFile();
1466 }
1467 
1468 
1469 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
1470  if (!log_->IsEnabled() || !FLAG_log_gc) return;
1471  Log::MessageBuilder msg(log_);
1472  // Using non-relative system time in order to be able to synchronize with
1473  // external memory profiling events (e.g. DOM memory size).
1474  msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f", space, kind,
1476  msg.WriteToLogFile();
1477 }
1478 
1479 
1480 void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
1481  if (!log_->IsEnabled() || !FLAG_log_gc) return;
1482  Log::MessageBuilder msg(log_);
1483  msg.Append("heap-sample-end,\"%s\",\"%s\"", space, kind);
1484  msg.WriteToLogFile();
1485 }
1486 
1487 
1488 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
1489  if (!log_->IsEnabled() || !FLAG_log_gc) return;
1490  Log::MessageBuilder msg(log_);
1491  msg.Append("heap-sample-item,%s,%d,%d", type, number, bytes);
1492  msg.WriteToLogFile();
1493 }
1494 
1495 
1496 void Logger::DebugTag(const char* call_site_tag) {
1497  if (!log_->IsEnabled() || !FLAG_log) return;
1498  Log::MessageBuilder msg(log_);
1499  msg.Append("debug-tag,%s", call_site_tag);
1500  msg.WriteToLogFile();
1501 }
1502 
1503 
1504 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
1505  if (!log_->IsEnabled() || !FLAG_log) return;
1506  StringBuilder s(parameter.length() + 1);
1507  for (int i = 0; i < parameter.length(); ++i) {
1508  s.AddCharacter(static_cast<char>(parameter[i]));
1509  }
1510  char* parameter_string = s.Finalize();
1511  Log::MessageBuilder msg(log_);
1512  msg.Append("debug-queue-event,%s,%15.3f,%s", event_type,
1513  base::OS::TimeCurrentMillis(), parameter_string);
1514  DeleteArray(parameter_string);
1515  msg.WriteToLogFile();
1516 }
1517 
1518 
1520  if (!log_->IsEnabled() || !FLAG_prof) return;
1521  Log::MessageBuilder msg(log_);
1522  msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
1523  msg.AppendAddress(sample->pc);
1524  msg.Append(",%ld", static_cast<int>(timer_.Elapsed().InMicroseconds()));
1525  if (sample->has_external_callback) {
1526  msg.Append(",1,");
1527  msg.AppendAddress(sample->external_callback);
1528  } else {
1529  msg.Append(",0,");
1530  msg.AppendAddress(sample->tos);
1531  }
1532  msg.Append(",%d", static_cast<int>(sample->state));
1533  if (overflow) {
1534  msg.Append(",overflow");
1535  }
1536  for (unsigned i = 0; i < sample->frames_count; ++i) {
1537  msg.Append(',');
1538  msg.AppendAddress(sample->stack[i]);
1539  }
1540  msg.WriteToLogFile();
1541 }
1542 
1543 
1545  if (!log_->IsEnabled()) return;
1546  if (profiler_ != NULL) {
1547  profiler_->pause();
1548  is_logging_ = false;
1549  }
1550 }
1551 
1552 
1553 // This function can be called when Log's mutex is acquired,
1554 // either from main or Profiler's thread.
1556  StopProfiler();
1557 }
1558 
1559 
1561  public:
1563  Handle<Code>* code_objects,
1564  int* count)
1565  : sfis_(sfis), code_objects_(code_objects), count_(count) { }
1566 
1567  virtual void EnterContext(Context* context) {}
1568  virtual void LeaveContext(Context* context) {}
1569 
1570  virtual void VisitFunction(JSFunction* function) {
1571  SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared());
1572  Object* maybe_script = sfi->script();
1573  if (maybe_script->IsScript()
1574  && !Script::cast(maybe_script)->HasValidSource()) return;
1575  if (sfis_ != NULL) {
1577  }
1578  if (code_objects_ != NULL) {
1579  DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
1580  code_objects_[*count_] = Handle<Code>(function->code());
1581  }
1582  *count_ = *count_ + 1;
1583  }
1584 
1585  private:
1588  int* count_;
1589 };
1590 
1591 
1594  Handle<Code>* code_objects) {
1595  HeapIterator iterator(heap);
1596  DisallowHeapAllocation no_gc;
1597  int compiled_funcs_count = 0;
1598 
1599  // Iterate the heap to find shared function info objects and record
1600  // the unoptimized code for them.
1601  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1602  if (!obj->IsSharedFunctionInfo()) continue;
1603  SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
1604  if (sfi->is_compiled()
1605  && (!sfi->script()->IsScript()
1606  || Script::cast(sfi->script())->HasValidSource())) {
1607  if (sfis != NULL) {
1608  sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi);
1609  }
1610  if (code_objects != NULL) {
1611  code_objects[compiled_funcs_count] = Handle<Code>(sfi->code());
1612  }
1613  ++compiled_funcs_count;
1614  }
1615  }
1616 
1617  // Iterate all optimized functions in all contexts.
1619  code_objects,
1620  &compiled_funcs_count);
1622 
1623  return compiled_funcs_count;
1624 }
1625 
1626 
1628  Code* code_object = Code::cast(object);
1629  LogEventsAndTags tag = Logger::STUB_TAG;
1630  const char* description = "Unknown code from the snapshot";
1631  switch (code_object->kind()) {
1632  case Code::FUNCTION:
1633  case Code::OPTIMIZED_FUNCTION:
1634  return; // We log this later using LogCompiledFunctions.
1635  case Code::BINARY_OP_IC:
1636  case Code::COMPARE_IC: // fall through
1637  case Code::COMPARE_NIL_IC: // fall through
1638  case Code::TO_BOOLEAN_IC: // fall through
1639  case Code::STUB:
1640  description =
1641  CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true);
1642  if (description == NULL)
1643  description = "A stub from the snapshot";
1644  tag = Logger::STUB_TAG;
1645  break;
1646  case Code::REGEXP:
1647  description = "Regular expression code";
1648  tag = Logger::REG_EXP_TAG;
1649  break;
1650  case Code::BUILTIN:
1651  description = "A builtin from the snapshot";
1652  tag = Logger::BUILTIN_TAG;
1653  break;
1654  case Code::HANDLER:
1655  description = "An IC handler from the snapshot";
1656  tag = Logger::HANDLER_TAG;
1657  break;
1658  case Code::KEYED_LOAD_IC:
1659  description = "A keyed load IC from the snapshot";
1660  tag = Logger::KEYED_LOAD_IC_TAG;
1661  break;
1662  case Code::LOAD_IC:
1663  description = "A load IC from the snapshot";
1664  tag = Logger::LOAD_IC_TAG;
1665  break;
1666  case Code::CALL_IC:
1667  description = "A call IC from the snapshot";
1668  tag = Logger::CALL_IC_TAG;
1669  break;
1670  case Code::STORE_IC:
1671  description = "A store IC from the snapshot";
1672  tag = Logger::STORE_IC_TAG;
1673  break;
1674  case Code::KEYED_STORE_IC:
1675  description = "A keyed store IC from the snapshot";
1676  tag = Logger::KEYED_STORE_IC_TAG;
1677  break;
1678  case Code::NUMBER_OF_KINDS:
1679  break;
1680  }
1681  PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
1682 }
1683 
1684 
1686  Heap* heap = isolate_->heap();
1688  "Logger::LogCodeObjects");
1689  HeapIterator iterator(heap);
1690  DisallowHeapAllocation no_gc;
1691  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1692  if (obj->IsCode()) LogCodeObject(obj);
1693  }
1694 }
1695 
1696 
1698  Handle<Code> code) {
1699  Handle<String> func_name(shared->DebugName());
1700  if (shared->script()->IsScript()) {
1701  Handle<Script> script(Script::cast(shared->script()));
1702  int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
1703  int column_num =
1704  Script::GetColumnNumber(script, shared->start_position()) + 1;
1705  if (script->name()->IsString()) {
1706  Handle<String> script_name(String::cast(script->name()));
1707  if (line_num > 0) {
1708  PROFILE(isolate_,
1710  Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1711  *code, *shared, NULL,
1712  *script_name, line_num, column_num));
1713  } else {
1714  // Can't distinguish eval and script here, so always use Script.
1715  PROFILE(isolate_,
1717  Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
1718  *code, *shared, NULL, *script_name));
1719  }
1720  } else {
1721  PROFILE(isolate_,
1723  Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1724  *code, *shared, NULL,
1725  isolate_->heap()->empty_string(), line_num, column_num));
1726  }
1727  } else if (shared->IsApiFunction()) {
1728  // API function.
1729  FunctionTemplateInfo* fun_data = shared->get_api_func_data();
1730  Object* raw_call_data = fun_data->call_code();
1731  if (!raw_call_data->IsUndefined()) {
1732  CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1733  Object* callback_obj = call_data->callback();
1734  Address entry_point = v8::ToCData<Address>(callback_obj);
1735  PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
1736  }
1737  } else {
1738  PROFILE(isolate_,
1740  Logger::LAZY_COMPILE_TAG, *code, *shared, NULL, *func_name));
1741  }
1742 }
1743 
1744 
1746  Heap* heap = isolate_->heap();
1748  "Logger::LogCompiledFunctions");
1749  HandleScope scope(isolate_);
1750  const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL);
1751  ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
1752  ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
1753  EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start());
1754 
1755  // During iteration, there can be heap allocation due to
1756  // GetScriptLineNumber call.
1757  for (int i = 0; i < compiled_funcs_count; ++i) {
1758  if (code_objects[i].is_identical_to(isolate_->builtins()->CompileLazy()))
1759  continue;
1760  LogExistingFunction(sfis[i], code_objects[i]);
1761  }
1762 }
1763 
1764 
1766  Heap* heap = isolate_->heap();
1768  "Logger::LogAccessorCallbacks");
1769  HeapIterator iterator(heap);
1770  DisallowHeapAllocation no_gc;
1771  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1772  if (!obj->IsExecutableAccessorInfo()) continue;
1773  ExecutableAccessorInfo* ai = ExecutableAccessorInfo::cast(obj);
1774  if (!ai->name()->IsName()) continue;
1775  Address getter_entry = v8::ToCData<Address>(ai->getter());
1776  Name* name = Name::cast(ai->name());
1777  if (getter_entry != 0) {
1778  PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
1779  }
1780  Address setter_entry = v8::ToCData<Address>(ai->setter());
1781  if (setter_entry != 0) {
1782  PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
1783  }
1784  }
1785 }
1786 
1787 
1788 static void AddIsolateIdIfNeeded(OStream& os, // NOLINT
1789  Isolate* isolate) {
1790  if (FLAG_logfile_per_isolate) os << "isolate-" << isolate << "-";
1791 }
1792 
1793 
1794 static void PrepareLogFileName(OStream& os, // NOLINT
1795  Isolate* isolate, const char* file_name) {
1796  AddIsolateIdIfNeeded(os, isolate);
1797  for (const char* p = file_name; *p; p++) {
1798  if (*p == '%') {
1799  p++;
1800  switch (*p) {
1801  case '\0':
1802  // If there's a % at the end of the string we back up
1803  // one character so we can escape the loop properly.
1804  p--;
1805  break;
1806  case 'p':
1808  break;
1809  case 't':
1810  // %t expands to the current time in milliseconds.
1811  os << static_cast<int64_t>(base::OS::TimeCurrentMillis());
1812  break;
1813  case '%':
1814  // %% expands (contracts really) to %.
1815  os << '%';
1816  break;
1817  default:
1818  // All other %'s expand to themselves.
1819  os << '%' << *p;
1820  break;
1821  }
1822  } else {
1823  os << *p;
1824  }
1825  }
1826 }
1827 
1828 
1829 bool Logger::SetUp(Isolate* isolate) {
1830  // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
1831  if (is_initialized_) return true;
1832  is_initialized_ = true;
1833 
1834  // --ll-prof implies --log-code and --log-snapshot-positions.
1835  if (FLAG_ll_prof) {
1836  FLAG_log_snapshot_positions = true;
1837  }
1838 
1839  OStringStream log_file_name;
1840  PrepareLogFileName(log_file_name, isolate, FLAG_logfile);
1841  log_->Initialize(log_file_name.c_str());
1842 
1843 
1844  if (FLAG_perf_basic_prof) {
1847  }
1848 
1849  if (FLAG_perf_jit_prof) {
1852  }
1853 
1854  if (FLAG_ll_prof) {
1855  ll_logger_ = new LowLevelLogger(log_file_name.c_str());
1857  }
1858 
1859  ticker_ = new Ticker(isolate, kSamplingIntervalMs);
1860 
1861  if (Log::InitLogAtStart()) {
1862  is_logging_ = true;
1863  }
1864 
1865  if (FLAG_prof) {
1866  profiler_ = new Profiler(isolate);
1867  is_logging_ = true;
1868  profiler_->Engage();
1869  }
1870 
1871  if (FLAG_log_internal_timer_events || FLAG_prof) timer_.Start();
1872 
1873  return true;
1874 }
1875 
1876 
1878  JitCodeEventHandler event_handler) {
1879  if (jit_logger_) {
1881  delete jit_logger_;
1882  jit_logger_ = NULL;
1883  }
1884 
1885  if (event_handler) {
1886  jit_logger_ = new JitLogger(event_handler);
1888  if (options & kJitCodeEventEnumExisting) {
1889  HandleScope scope(isolate_);
1890  LogCodeObjects();
1892  }
1893  }
1894 }
1895 
1896 
1898  return ticker_;
1899 }
1900 
1901 
1903  if (!is_initialized_) return NULL;
1904  is_initialized_ = false;
1905 
1906  // Stop the profiler before closing the file.
1907  if (profiler_ != NULL) {
1908  profiler_->Disengage();
1909  delete profiler_;
1910  profiler_ = NULL;
1911  }
1912 
1913  delete ticker_;
1914  ticker_ = NULL;
1915 
1916  if (perf_basic_logger_) {
1918  delete perf_basic_logger_;
1920  }
1921 
1922  if (perf_jit_logger_) {
1924  delete perf_jit_logger_;
1926  }
1927 
1928  if (ll_logger_) {
1930  delete ll_logger_;
1931  ll_logger_ = NULL;
1932  }
1933 
1934  if (jit_logger_) {
1936  delete jit_logger_;
1937  jit_logger_ = NULL;
1938  }
1939 
1940  return log_->Close();
1941 }
1942 
1943 } } // namespace v8::internal
#define BUILTIN(name)
Definition: builtins.cc:122
static const int kNoPreviousCharacter
Definition: unicode.h:97
static const unsigned kMaxOneByteChar
Definition: unicode.h:141
static uchar Length(uchar chr, int previous)
Definition: unicode-inl.h:140
static unsigned Encode(char *out, uchar c, int previous, bool replace_invalid=false)
Definition: unicode-inl.h:91
static void SignalCodeMovingGC()
static const char *const LogFileOpenMode
Definition: platform.h:187
static FILE * FOpen(const char *path, const char *mode)
static int GetCurrentProcessId()
static std::vector< SharedLibraryAddress > GetSharedLibraryAddresses()
static int GetUserTime(uint32_t *secs, uint32_t *usecs)
static double TimeCurrentMillis()
static void FPrint(FILE *out, const char *format,...)
Code * builtin(Name name)
Definition: builtins.h:254
void Init(Logger::LogEventsAndTags tag)
Definition: log.cc:67
void AppendBytes(const char *bytes)
Definition: log.cc:115
char utf8_buffer_[kUtf8BufferSize]
Definition: log.cc:150
uc16 utf16_buffer[kUtf16BufferSize]
Definition: log.cc:151
void AppendBytes(const char *bytes, int size)
Definition: log.cc:109
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code *code, const char *comment)
Definition: log.cc:160
virtual ~CodeEventLogger()
Definition: log.cc:157
virtual void LogRecordedBuffer(Code *code, SharedFunctionInfo *shared, const char *name, int length)=0
virtual void RegExpCodeCreateEvent(Code *code, String *source)
Definition: log.cc:221
NameBuffer * name_buffer_
Definition: log.h:534
int ExecutableSize()
Definition: objects.h:5263
int instruction_size() const
byte * instruction_start()
Definition: objects-inl.h:6176
static const int kHeaderSize
Definition: objects.h:5373
static void VisitAllOptimizedFunctions(Isolate *isolate, OptimizedFunctionVisitor *visitor)
Definition: deoptimizer.cc:284
virtual void LeaveContext(Context *context)
Definition: log.cc:1568
virtual void VisitFunction(JSFunction *function)
Definition: log.cc:1570
virtual void EnterContext(Context *context)
Definition: log.cc:1567
EnumerateOptimizedFunctionsVisitor(Handle< SharedFunctionInfo > *sfis, Handle< Code > *code_objects, int *count)
Definition: log.cc:1562
Handle< SharedFunctionInfo > * sfis_
Definition: log.cc:1586
static HeapObject * FromAddress(Address address)
Definition: objects-inl.h:1464
static const int kMakeHeapIterableMask
Definition: heap.h:721
Isolate * isolate()
Definition: heap-inl.h:589
void CollectAllGarbage(int flags, const char *gc_reason=NULL, const GCCallbackFlags gc_callback_flags=kNoGCCallbackFlags)
Definition: heap.cc:724
Builtins * builtins()
Definition: isolate.h:947
Logger * logger()
Definition: isolate.h:866
virtual void CodeDisableOptEvent(Code *code, SharedFunctionInfo *shared)
Definition: log.cc:477
virtual void LogRecordedBuffer(Code *code, SharedFunctionInfo *shared, const char *name, int length)
Definition: log.cc:503
virtual void CodeDeleteEvent(Address from)
Definition: log.cc:543
JitCodeEventHandler code_event_handler_
Definition: log.cc:494
void EndCodePosInfoEvent(Code *code, void *jit_handler_data)
Definition: log.cc:581
virtual void CodeMoveEvent(Address from, Address to)
Definition: log.cc:523
void * StartCodePosInfoEvent()
Definition: log.cc:571
JitLogger(JitCodeEventHandler code_event_handler)
Definition: log.cc:498
virtual void AddCodeLinePosInfoEvent(void *jit_handler_data, int pc_offset, int position, JitCodeEvent::PositionType position_type)
Definition: log.cc:554
bool IsEnabled()
Definition: log-utils.h:37
void Initialize(const char *log_file_name)
Definition: log-utils.cc:26
FILE * Close()
Definition: log-utils.cc:74
static bool InitLogAtStart()
Definition: log-utils.h:24
void SharedLibraryEvent(const std::string &library_path, uintptr_t start, uintptr_t end)
Definition: log.cc:896
void ApiNamedSecurityCheck(Object *key)
Definition: log.cc:872
bool is_initialized_
Definition: log.h:415
void removeCodeEventListener(CodeEventListener *listener)
Definition: log.cc:792
void CodeEndLinePosInfoRecordEvent(Code *code, void *jit_handler_data)
Definition: log.cc:1387
void DebugEvent(const char *event_type, Vector< uint16_t > parameter)
Definition: log.cc:1504
void UncheckedIntPtrTEvent(const char *name, intptr_t value)
Definition: log.cc:842
void ApiEntryCall(const char *name)
Definition: log.cc:1085
Ticker * ticker_
Definition: log.h:386
void DeleteEvent(const char *name, void *object)
Definition: log.cc:1100
static void DeleteEventStatic(const char *name, void *object)
Definition: log.cc:1113
void IntEvent(const char *name, int value)
Definition: log.cc:824
void GetterCallbackEvent(Name *name, Address entry_point)
Definition: log.cc:1151
void HeapSampleItemEvent(const char *type, int number, int bytes)
Definition: log.cc:1488
void CodeNameEvent(Address addr, int pos, const char *code_name)
Definition: log.cc:1393
void RegExpCodeCreateEvent(Code *code, String *source)
Definition: log.cc:1321
bool is_logging_code_events()
Definition: log.h:315
void SetterCallbackEvent(Name *name, Address entry_point)
Definition: log.cc:1157
void NewEvent(const char *name, void *object, size_t size)
Definition: log.cc:1091
Profiler * profiler_
Definition: log.h:391
PerfJitLogger * perf_jit_logger_
Definition: log.h:408
void CodeMovingGCEvent()
Definition: log.cc:1311
void LogAccessorCallbacks()
Definition: log.cc:1765
Logger(Isolate *isolate)
Definition: log.cc:765
void addCodeEventListener(CodeEventListener *listener)
Definition: log.cc:786
void ProfilerBeginEvent()
Definition: log.cc:803
void SharedFunctionInfoMoveEvent(Address from, Address to)
Definition: log.cc:1414
bool SetUp(Isolate *isolate)
Definition: log.cc:1829
JitLogger * jit_logger_
Definition: log.h:410
void CodeLinePosInfoAddPositionEvent(void *jit_handler_data, int pc_offset, int position)
Definition: log.cc:1360
void CodeDeoptEvent(Code *code)
Definition: log.cc:907
void CodeLinePosInfoAddStatementPositionEvent(void *jit_handler_data, int pc_offset, int position)
Definition: log.cc:1370
void UncheckedIntEvent(const char *name, int value)
Definition: log.cc:834
static void LeaveExternal(Isolate *isolate)
Definition: log.cc:946
bool is_logging_
Definition: log.h:405
static void DefaultTimerEventsLogger(const char *name, int se)
Definition: log.cc:953
void ResourceEvent(const char *name, const char *tag)
Definition: log.cc:1435
void ApiEvent(const char *name,...)
Definition: log.cc:861
void LogCompiledFunctions()
Definition: log.cc:1745
bool hasCodeEventListener(CodeEventListener *listener)
Definition: log.cc:798
void MoveEventInternal(LogEventsAndTags event, Address from, Address to)
Definition: log.cc:1422
void CodeDisableOptEvent(Code *code, SharedFunctionInfo *shared)
Definition: log.cc:1293
void SuspectReadEvent(Name *name, Object *obj)
Definition: log.cc:1449
void LogRegExpSource(Handle< JSRegExp > regexp)
Definition: log.cc:976
static void EnterExternal(Isolate *isolate)
Definition: log.cc:939
void SetCodeEventHandler(uint32_t options, JitCodeEventHandler event_handler)
Definition: log.cc:1877
void CodeCreateEvent(LogEventsAndTags tag, Code *code, const char *source)
Definition: log.cc:1176
void LogExistingFunction(Handle< SharedFunctionInfo > shared, Handle< Code > code)
Definition: log.cc:1697
void CodeDeleteEvent(Address from)
Definition: log.cc:1346
PerfBasicLogger * perf_basic_logger_
Definition: log.h:407
static void NewEventStatic(const char *name, void *object, size_t size)
Definition: log.cc:1108
void TimerEvent(StartEnd se, const char *name)
Definition: log.cc:927
void HandleEvent(const char *name, Object **location)
Definition: log.cc:850
void CurrentTimeEvent()
Definition: log.cc:917
LowLevelLogger * ll_logger_
Definition: log.h:409
void ApiNamedPropertyAccess(const char *tag, JSObject *holder, Object *name)
Definition: log.cc:1038
void StringEvent(const char *name, const char *value)
Definition: log.cc:811
void CallbackEventInternal(const char *prefix, Name *name, Address entry_point)
Definition: log.cc:1118
void UncheckedStringEvent(const char *name, const char *value)
Definition: log.cc:816
void SnapshotPositionEvent(Address addr, int pos)
Definition: log.cc:1402
base::ElapsedTimer timer_
Definition: log.h:417
Isolate * isolate_
Definition: log.h:383
void CodeStartLinePosInfoRecordEvent(PositionsRecorder *pos_recorder)
Definition: log.cc:1380
void LogFailure()
Definition: log.cc:1555
void RegExpCompileEvent(Handle< JSRegExp > regexp, bool in_cache)
Definition: log.cc:1022
void HeapSampleEndEvent(const char *space, const char *kind)
Definition: log.cc:1480
void CallbackEvent(Name *name, Address entry_point)
Definition: log.cc:1145
Sampler * sampler()
Definition: log.cc:1897
void LogCodeObjects()
Definition: log.cc:1685
void CodeMoveEvent(Address from, Address to)
Definition: log.cc:1337
void ApiIndexedSecurityCheck(uint32_t index)
Definition: log.cc:1032
void ApiObjectAccess(const char *tag, JSObject *obj)
Definition: log.cc:1076
friend class Profiler
Definition: log.h:401
void TickEvent(TickSample *sample, bool overflow)
Definition: log.cc:1519
List< CodeEventListener * > listeners_
Definition: log.h:411
void IntPtrTEvent(const char *name, intptr_t value)
Definition: log.cc:829
static const int kSamplingIntervalMs
Definition: log.h:341
FILE * TearDown()
Definition: log.cc:1902
void DebugTag(const char *call_site_tag)
Definition: log.cc:1496
@ NUMBER_OF_LOG_EVENTS
Definition: log.h:159
void HeapSampleBeginEvent(const char *space, const char *kind)
Definition: log.cc:1469
void StopProfiler()
Definition: log.cc:1544
void ApiIndexedPropertyAccess(const char *tag, JSObject *holder, uint32_t index)
Definition: log.cc:1065
void LogCodeObject(Object *code_object)
Definition: log.cc:1627
static const char kLogExt[]
Definition: log.cc:351
static const char kCodeMovingGCTag
Definition: log.cc:347
static const int kLogBufferSize
Definition: log.cc:355
virtual ~LowLevelLogger()
Definition: log.cc:387
virtual void CodeMovingGCEvent()
Definition: log.cc:462
virtual void SnapshotPositionEvent(Address addr, int pos)
Definition: log.cc:447
virtual void LogRecordedBuffer(Code *code, SharedFunctionInfo *shared, const char *name, int length)
Definition: log.cc:415
virtual void CodeDeleteEvent(Address from)
Definition: log.cc:440
void LogWriteStruct(const T &s)
Definition: log.cc:361
virtual void CodeDisableOptEvent(Code *code, SharedFunctionInfo *shared)
Definition: log.cc:303
LowLevelLogger(const char *file_name)
Definition: log.cc:372
void LogWriteBytes(const char *bytes, int size)
Definition: log.cc:455
virtual void CodeMoveEvent(Address from, Address to)
Definition: log.cc:432
const char * c_str() const
Definition: ostreams.h:84
static MUST_USE_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it)
Definition: objects.cc:109
virtual void CodeDeleteEvent(Address from)
Definition: log.cc:236
static const int kLogBufferSize
Definition: log.cc:250
virtual ~PerfBasicLogger()
Definition: log.cc:276
static const char kFilenameFormatString[]
Definition: log.cc:245
virtual void CodeMoveEvent(Address from, Address to)
Definition: log.cc:234
virtual void LogRecordedBuffer(Code *code, SharedFunctionInfo *shared, const char *name, int length)
Definition: log.cc:282
virtual void CodeDisableOptEvent(Code *code, SharedFunctionInfo *shared)
Definition: log.cc:235
static const int kFilenameBufferPadding
Definition: log.cc:246
static const int kBufferSize
Definition: log.cc:640
Profiler(Isolate *isolate)
Definition: log.cc:696
base::Semaphore buffer_semaphore_
Definition: log.cc:646
Isolate * isolate_
Definition: log.cc:637
virtual void Run()
Definition: log.cc:751
TickSample buffer_[kBufferSize]
Definition: log.cc:641
int Succ(int index)
Definition: log.cc:635
void Insert(TickSample *sample)
Definition: log.cc:604
bool Remove(TickSample *sample)
Definition: log.cc:625
int interval() const
Definition: sampler.h:67
bool IsActive() const
Definition: sampler.h:85
void DecreaseProfilingDepth()
Definition: sampler.cc:677
void IncreaseProfilingDepth()
Definition: sampler.cc:669
Isolate * isolate() const
Definition: sampler.h:66
static int GetColumnNumber(Handle< Script > script, int code_pos)
Definition: objects.cc:9635
static int GetLineNumber(Handle< Script > script, int code_pos)
Definition: objects.cc:9673
BailoutReason DisableOptimizationReason()
Definition: objects-inl.h:5750
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
Definition: objects.cc:8370
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
Definition: objects.cc:8004
Ticker(Isolate *isolate, int interval)
Definition: log.cc:665
virtual void Tick(TickSample *sample)
Definition: log.cc:671
Profiler * profiler_
Definition: log.cc:689
void SetProfiler(Profiler *profiler)
Definition: log.cc:675
void ClearProfiler()
Definition: log.cc:682
void LogTimerEvent(Logger::StartEnd se)
Definition: log.cc:960
T * start() const
Definition: vector.h:47
int length() const
Definition: vector.h:41
#define PROFILE(IsolateGetter, Call)
Definition: cpu-profiler.h:181
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob Print the time it takes to lazily compile hydrogen code stubs dump only objects containing this substring stress the GC compactor to flush out pretty print source code for builtins print C code to recreate TurboFan graphs report heap spill statistics along with enable possessive quantifier syntax for testing Minimal Log code events to the log file without profiling log positions Log statistical profiling Used with turns on browser compatible mode for profiling Enable perf linux profiler(experimental annotate support).") DEFINE_STRING(gc_fake_mmap
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi space(in MBytes)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define PROFILER_LOG(Call)
Definition: log.cc:41
#define JIT_LOG(Call)
Definition: log.cc:469
#define DECLARE_EVENT(ignore1, name)
Definition: log.cc:29
#define LL_LOG(Call)
Definition: log.cc:295
#define CALL_LISTENERS(Call)
Definition: log.cc:36
#define LOG(isolate, Call)
Definition: log.h:69
#define TIMER_EVENTS_LIST(V)
Definition: log.h:423
#define LOG_EVENTS_AND_TAGS_LIST(V)
Definition: log.h:86
#define CHECK_NE(unexpected, value)
Definition: logging.h:173
#define DCHECK(condition)
Definition: logging.h:205
void USE(T)
Definition: macros.h:322
#define V8_PTR_PREFIX
Definition: macros.h:360
#define V8PRIxPTR
Definition: macros.h:363
int int32_t
Definition: unicode.cc:24
static const char * ComputeMarker(Code *code)
Definition: log.cc:50
void DeleteArray(T *array)
Definition: allocation.h:68
static void PrepareLogFileName(OStream &os, Isolate *isolate, const char *file_name)
Definition: log.cc:1794
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)
static void AddIsolateIdIfNeeded(OStream &os, Isolate *isolate)
Definition: log.cc:1788
@ DISALLOW_NULLS
Definition: objects.h:8337
int SNPrintF(Vector< char > str, const char *format,...)
Definition: utils.cc:105
@ ROBUST_STRING_TRAVERSAL
Definition: objects.h:8338
static int EnumerateCompiledFunctions(Heap *heap, Handle< SharedFunctionInfo > *sfis, Handle< Code > *code_objects)
Definition: log.cc:1592
const char * GetBailoutReason(BailoutReason reason)
byte * Address
Definition: globals.h:101
static uint32_t Hash(RegisteredExtension *extension)
static void AppendCodeCreateHeader(Log::MessageBuilder *msg, Logger::LogEventsAndTags tag, Code *code)
Definition: log.cc:1163
uint16_t uc16
Definition: globals.h:184
const int MB
Definition: globals.h:107
static const char *const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS]
Definition: log.cc:30
int StrLength(const char *string)
Definition: vector.h:147
void MemCopy(void *dest, const void *src, size_t size)
Definition: utils.h:350
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
@ kJitCodeEventEnumExisting
Definition: v8.h:4336
void(* JitCodeEventHandler)(const JitCodeEvent *event)
Callback function passed to SetJitCodeEventHandler.
Definition: v8.h:4345
A JIT code event is issued each time code is added, moved or removed.
Definition: v8.h:4271
@ STATEMENT_POSITION
Definition: v8.h:4285
@ CODE_END_LINE_INFO_RECORDING
Definition: v8.h:4278
@ CODE_ADD_LINE_POS_INFO
Definition: v8.h:4276
@ CODE_REMOVED
Definition: v8.h:4275
@ CODE_START_LINE_INFO_RECORDING
Definition: v8.h:4277
EventType type
Definition: v8.h:4288
Address external_callback
Definition: sampler.h:45
Address stack[kMaxFramesCount]
Definition: sampler.h:49
#define T(name, string, precedence)
Definition: token.cc:25