59 static const int kBufferSize = 256;
63 byte buffer_[kBufferSize];
66 void IncrementStateCounter(
StateTag state) {
71 void DecrementStateCounter(
StateTag state) {
94 if (Succ(head_) == tail_) {
99 buffer_semaphore_->
Signal();
105 buffer_semaphore_->
Wait();
106 *sample = buffer_[tail_];
107 bool result = overflow_;
122 int Succ(
int index) {
return (index + 1) % kBufferSize; }
127 static const int kBufferSize = 128;
128 TickSample buffer_[kBufferSize];
132 Semaphore* buffer_semaphore_;
152 if (sample->
state == GC)
return;
156 if (js_entry_sp == 0) {
162 if (callback !=
NULL) {
173 sample->
fp, sample->
sp,
174 sample->
sp, js_entry_sp);
177 sample->
stack[i++] = it.frame()->pc();
198 if (profiler_) profiler_->
Insert(sample);
214 profiler_ = profiler;
240 : counters_(isolate->counters()), current_index_(0), is_full_(
false) {
241 for (
int i = 0; i < kBufferSize; i++) {
242 buffer_[i] =
static_cast<byte>(OTHER);
249 LOGGER->ticker_->ClearWindow();
255 DecrementStateCounter(static_cast<StateTag>(buffer_[current_index_]));
256 }
else if (current_index_ == kBufferSize - 1) {
259 buffer_[current_index_] =
static_cast<byte>(state);
260 IncrementStateCounter(state);
262 current_index_ = (current_index_ + 1) & (kBufferSize - 1);
275 buffer_semaphore_(
OS::CreateSemaphore(0)),
283 if (engaged_)
return;
288 if (!FLAG_prof_lazy) {
297 LOGGER->ticker_->SetProfiler(
this);
299 LOGGER->ProfilerBeginEvent();
304 if (!engaged_)
return;
307 LOGGER->ticker_->ClearProfiler();
319 LOG(
ISOLATE, UncheckedStringEvent(
"profiler",
"end"));
327 LOG(isolate_, TickEvent(&sample, overflow));
328 overflow =
Remove(&sample);
367 static const char kCodeMovingGCTag =
'G';
379 for (HashMap::Entry* p = impl_.
Start(); p !=
NULL; p = impl_.
Next(p)) {
385 HashMap::Entry* entry = FindOrCreateEntry(code_address);
386 if (entry->value ==
NULL) {
387 entry->value = CopyName(name, name_size);
392 HashMap::Entry* entry = FindEntry(code_address);
393 return (entry !=
NULL) ?
static_cast<const char*
>(entry->value) :
NULL;
397 HashMap::Entry* entry = FindEntry(code_address);
405 if (from == to)
return;
406 HashMap::Entry* from_entry = FindEntry(from);
408 void* value = from_entry->value;
409 RemoveEntry(from_entry);
410 HashMap::Entry* to_entry = FindOrCreateEntry(to);
412 to_entry->value = value;
416 static bool PointerEquals(
void* lhs,
void* rhs) {
420 static char* CopyName(
const char* name,
int name_size) {
421 char* result = NewArray<char>(name_size + 1);
422 for (
int i = 0; i < name_size; ++i) {
424 if (c ==
'\0') c =
' ';
427 result[name_size] =
'\0';
431 HashMap::Entry* FindOrCreateEntry(
Address code_address) {
435 HashMap::Entry* FindEntry(
Address code_address) {
439 void RemoveEntry(HashMap::Entry* entry) {
440 impl_.
Remove(entry->key, entry->hash);
445 DISALLOW_COPY_AND_ASSIGN(
NameMap);
458 if (str ==
NULL)
return;
460 int utf8_length =
Min(str->
length(), kUtf8BufferSize - utf8_pos_);
462 utf8_pos_ += utf8_length;
465 int uc16_length =
Min(str->
length(), kUtf16BufferSize);
468 for (
int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
469 uc16 c = utf16_buffer[i];
471 utf8_buffer_[utf8_pos_++] =
static_cast<char>(c);
474 if (utf8_pos_ + char_length > kUtf8BufferSize)
break;
476 utf8_pos_ += char_length;
483 size =
Min(size, kUtf8BufferSize - utf8_pos_);
484 memcpy(utf8_buffer_ + utf8_pos_, bytes, size);
493 if (utf8_pos_ >= kUtf8BufferSize)
return;
494 utf8_buffer_[utf8_pos_++] = c;
498 Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_);
500 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
505 const char*
get() {
return utf8_buffer_; }
506 int size()
const {
return utf8_pos_; }
509 static const int kUtf8BufferSize = 512;
510 static const int kUtf16BufferSize = 128;
513 char utf8_buffer_[kUtf8BufferSize];
514 uc16 utf16_buffer[kUtf16BufferSize];
521 sliding_state_window_(
NULL),
524 cpu_profiler_nesting_(0),
526 name_buffer_(new NameBuffer),
527 address_to_name_map_(
NULL),
528 is_initialized_(
false),
529 code_event_handler_(
NULL),
532 prev_function_(
NULL),
539 delete address_to_name_map_;
545 void Logger::IssueCodeAddedEvent(Code*
code,
550 event.code_start = code->instruction_start();
551 event.code_len = code->instruction_size();
552 event.name.str = name;
553 event.name.len = name_len;
555 code_event_handler_(&event);
564 event.code_start = from_code->instruction_start();
565 event.code_len = from_code->instruction_size();
568 const size_t header_size =
569 from_code->instruction_start() -
reinterpret_cast<byte*
>(from_code);
572 event.new_code_start =
575 code_event_handler_(&event);
579 void Logger::IssueCodeRemovedEvent(
Address from) {
584 event.code_start = from_code->instruction_start();
585 event.code_len = from_code->instruction_size();
587 code_event_handler_(&event);
591 #define DECLARE_EVENT(ignore1, name) name,
598 void Logger::ProfilerBeginEvent() {
602 msg.WriteToLogFile();
607 if (FLAG_log) UncheckedStringEvent(name, value);
611 void Logger::UncheckedStringEvent(
const char* name,
const char* value) {
614 msg.Append(
"%s,\"%s\"\n", name, value);
615 msg.WriteToLogFile();
620 if (FLAG_log) UncheckedIntEvent(name, value);
625 if (FLAG_log) UncheckedIntPtrTEvent(name, value);
629 void Logger::UncheckedIntEvent(
const char* name,
int value) {
632 msg.Append(
"%s,%d\n", name, value);
633 msg.WriteToLogFile();
637 void Logger::UncheckedIntPtrTEvent(
const char* name, intptr_t value) {
641 msg.WriteToLogFile();
646 if (!log_->
IsEnabled() || !FLAG_log_handles)
return;
648 msg.Append(
"%s,0x%" V8PRIxPTR "\n", name, location);
649 msg.WriteToLogFile();
656 void Logger::ApiEvent(
const char* format, ...) {
660 va_start(ap, format);
661 msg.AppendVA(format, ap);
663 msg.WriteToLogFile();
668 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
669 if (key->IsString()) {
672 ApiEvent(
"api,check-security,\"%s\"\n", *str);
673 }
else if (key->IsUndefined()) {
674 ApiEvent(
"api,check-security,undefined\n");
676 ApiEvent(
"api,check-security,['no-name']\n");
684 if (!log_->
IsEnabled() || !FLAG_prof)
return;
690 msg.WriteToLogFile();
697 if (!log_->
IsEnabled() || !FLAG_prof)
return;
703 msg.WriteToLogFile();
713 if (!source->IsString()) {
714 msg.Append(
"no source");
718 switch (regexp->TypeTag()) {
730 Handle<Object> global =
GetProperty(regexp,
"global");
731 if (global->IsTrue()) {
735 Handle<Object> ignorecase =
GetProperty(regexp,
"ignoreCase");
736 if (ignorecase->IsTrue()) {
740 Handle<Object> multiline =
GetProperty(regexp,
"multiline");
741 if (multiline->IsTrue()) {
745 msg.WriteToLogFile();
750 if (!log_->
IsEnabled() || !FLAG_log_regexp)
return;
752 msg.Append(
"regexp-compile,");
753 LogRegExpSource(regexp);
754 msg.Append(in_cache ?
",hit\n" :
",miss\n");
755 msg.WriteToLogFile();
760 if (!log_->
IsEnabled() || !FLAG_log_runtime)
return;
763 for (
int i = 0; i < format.
length(); i++) {
765 if (c ==
'%' && i <= format.
length() - 2) {
767 ASSERT(
'0' <= format[i] && format[i] <=
'9');
768 MaybeObject* maybe = args->
GetElement(format[i] -
'0');
770 if (!maybe->ToObject(&obj)) {
771 msg.Append(
"<exception>");
786 msg.Append(
"0x%x",
Smi::cast(obj)->value());
789 msg.Append(
"%i",
Smi::cast(obj)->value());
799 msg.WriteToLogFile();
804 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
805 ApiEvent(
"api,check-security,%u\n", index);
813 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
819 ApiEvent(
"api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
825 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
829 ApiEvent(
"api,%s,\"%s\",%u\n", tag, *class_name, index);
833 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
834 String* class_name_obj =
object->class_name();
837 ApiEvent(
"api,%s,\"%s\"\n", tag, *class_name);
842 if (!log_->
IsEnabled() || !FLAG_log_api)
return;
843 ApiEvent(
"api,%s\n", name);
848 if (!log_->
IsEnabled() || !FLAG_log)
return;
850 msg.Append(
"new,%s,0x%" V8PRIxPTR ",%u\n", name,
object,
851 static_cast<unsigned int>(size));
852 msg.WriteToLogFile();
857 if (!log_->
IsEnabled() || !FLAG_log)
return;
859 msg.Append(
"delete,%s,0x%" V8PRIxPTR "\n", name,
object);
860 msg.WriteToLogFile();
865 LOGGER->NewEvent(name,
object, size);
870 LOGGER->DeleteEvent(name,
object);
873 void Logger::CallbackEventInternal(
const char* prefix,
const char* name,
875 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
878 kLogEventsNames[CODE_CREATION_EVENT],
879 kLogEventsNames[CALLBACK_TAG]);
880 msg.AppendAddress(entry_point);
881 msg.Append(
",1,\"%s%s\"", prefix, name);
883 msg.WriteToLogFile();
888 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
891 CallbackEventInternal(
"", *str, entry_point);
896 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
899 CallbackEventInternal(
"get ", *str, entry_point);
904 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
907 CallbackEventInternal(
"set ", *str, entry_point);
913 const char* comment) {
916 name_buffer_->
Reset();
921 if (code_event_handler_ !=
NULL) {
922 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
926 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
929 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
931 if (!FLAG_log_code)
return;
934 kLogEventsNames[CODE_CREATION_EVENT],
935 kLogEventsNames[tag]);
936 msg.AppendAddress(code->
address());
938 for (
const char* p = comment; *p !=
'\0'; p++) {
946 msg.WriteToLogFile();
955 name_buffer_->
Reset();
960 if (code_event_handler_ !=
NULL) {
961 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
965 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
968 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
970 if (!FLAG_log_code)
return;
973 kLogEventsNames[CODE_CREATION_EVENT],
974 kLogEventsNames[tag]);
975 msg.AppendAddress(code->
address());
977 msg.AppendDetailed(name,
false);
980 msg.WriteToLogFile();
985 static const char* ComputeMarker(
Code* code) {
986 switch (code->
kind()) {
987 case Code::FUNCTION:
return code->
optimizable() ?
"~" :
"";
988 case Code::OPTIMIZED_FUNCTION:
return "*";
1000 name_buffer_->
Reset();
1006 if (code_event_handler_ !=
NULL) {
1007 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
1011 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
1014 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
1016 if (!FLAG_log_code)
return;
1017 if (code == Isolate::Current()->builtins()->builtin(
1018 Builtins::kLazyCompile))
1024 msg.Append(
"%s,%s,",
1025 kLogEventsNames[CODE_CREATION_EVENT],
1026 kLogEventsNames[tag]);
1027 msg.AppendAddress(code->
address());
1029 msg.AppendAddress(shared->
address());
1030 msg.Append(
",%s", ComputeMarker(code));
1032 msg.WriteToLogFile();
1042 String* source,
int line) {
1045 name_buffer_->
Reset();
1055 if (code_event_handler_ !=
NULL) {
1056 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
1060 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
1063 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
1065 if (!FLAG_log_code)
return;
1071 msg.Append(
"%s,%s,",
1072 kLogEventsNames[CODE_CREATION_EVENT],
1073 kLogEventsNames[tag]);
1074 msg.AppendAddress(code->
address());
1075 msg.Append(
",%d,\"%s %s:%d\",",
1080 msg.AppendAddress(shared->
address());
1081 msg.Append(
",%s", ComputeMarker(code));
1083 msg.WriteToLogFile();
1090 name_buffer_->
Reset();
1095 if (code_event_handler_ !=
NULL) {
1096 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
1100 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
1103 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
1105 if (!FLAG_log_code)
return;
1107 msg.Append(
"%s,%s,",
1108 kLogEventsNames[CODE_CREATION_EVENT],
1109 kLogEventsNames[tag]);
1110 msg.AppendAddress(code->
address());
1111 msg.Append(
",%d,\"args_count: %d\"", code->
ExecutableSize(), args_count);
1113 msg.WriteToLogFile();
1118 if (!log_->
IsEnabled() || !FLAG_ll_prof)
return;
1119 LowLevelLogWriteBytes(&kCodeMovingGCTag,
sizeof(kCodeMovingGCTag));
1127 name_buffer_->
Reset();
1128 name_buffer_->
AppendBytes(kLogEventsNames[REG_EXP_TAG]);
1132 if (code_event_handler_ !=
NULL) {
1133 IssueCodeAddedEvent(code, name_buffer_->
get(), name_buffer_->
size());
1137 LowLevelCodeCreateEvent(code, name_buffer_->
get(), name_buffer_->
size());
1140 RegisterSnapshotCodeName(code, name_buffer_->
get(), name_buffer_->
size());
1142 if (!FLAG_log_code)
return;
1144 msg.Append(
"%s,%s,",
1145 kLogEventsNames[CODE_CREATION_EVENT],
1146 kLogEventsNames[REG_EXP_TAG]);
1147 msg.AppendAddress(code->
address());
1149 msg.AppendDetailed(source,
false);
1152 msg.WriteToLogFile();
1157 if (code_event_handler_ !=
NULL) IssueCodeMovedEvent(from, to);
1159 if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
1161 address_to_name_map_->
Move(from, to);
1163 MoveEventInternal(CODE_MOVE_EVENT, from, to);
1168 if (code_event_handler_ !=
NULL) IssueCodeRemovedEvent(from);
1170 if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
1172 address_to_name_map_->
Remove(from);
1174 DeleteEventInternal(CODE_DELETE_EVENT, from);
1180 if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos);
1182 const char* code_name = address_to_name_map_->
Lookup(addr);
1183 if (code_name ==
NULL)
return;
1185 msg.Append(
"%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
1186 for (
const char* p = code_name; *p !=
'\0'; ++p) {
1187 if (*p ==
'"') msg.Append(
'\\');
1191 msg.WriteToLogFile();
1193 if (!FLAG_log_snapshot_positions)
return;
1195 msg.Append(
"%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
1196 msg.AppendAddress(addr);
1197 msg.Append(
",%d", pos);
1199 msg.WriteToLogFile();
1204 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
1211 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
1213 msg.Append(
"%s,", kLogEventsNames[event]);
1214 msg.AppendAddress(from);
1216 msg.AppendAddress(to);
1218 msg.WriteToLogFile();
1223 if (!log_->
IsEnabled() || !FLAG_log_code)
return;
1225 msg.Append(
"%s,", kLogEventsNames[event]);
1226 msg.AppendAddress(from);
1228 msg.WriteToLogFile();
1233 if (!log_->
IsEnabled() || !FLAG_log)
return;
1235 msg.Append(
"%s,%s,", name, tag);
1239 msg.Append(
"%d,%d,", sec, usec);
1244 msg.WriteToLogFile();
1249 if (!log_->
IsEnabled() || !FLAG_log_suspect)
return;
1251 String* class_name = obj->IsJSObject()
1253 :
HEAP->empty_string();
1254 msg.Append(
"suspect-read,");
1255 msg.Append(class_name);
1261 msg.WriteToLogFile();
1266 if (!log_->
IsEnabled() || !FLAG_log_gc)
return;
1270 msg.Append(
"heap-sample-begin,\"%s\",\"%s\",%.0f\n",
1272 msg.WriteToLogFile();
1277 if (!log_->
IsEnabled() || !FLAG_log_gc)
return;
1279 msg.Append(
"heap-sample-end,\"%s\",\"%s\"\n", space, kind);
1280 msg.WriteToLogFile();
1285 if (!log_->
IsEnabled() || !FLAG_log_gc)
return;
1287 msg.Append(
"heap-sample-item,%s,%d,%d\n", type, number, bytes);
1288 msg.WriteToLogFile();
1293 if (!log_->
IsEnabled() || !FLAG_log)
return;
1295 msg.Append(
"debug-tag,%s\n", call_site_tag);
1296 msg.WriteToLogFile();
1301 if (!log_->
IsEnabled() || !FLAG_log)
return;
1303 for (
int i = 0; i < parameter.
length(); ++i) {
1306 char* parameter_string = s.Finalize();
1308 msg.Append(
"debug-queue-event,%s,%15.3f,%s\n",
1313 msg.WriteToLogFile();
1318 if (!log_->
IsEnabled() || !FLAG_prof)
return;
1320 msg.Append(
"%s,", kLogEventsNames[TICK_EVENT]);
1321 msg.AppendAddress(sample->
pc);
1323 msg.AppendAddress(sample->
sp);
1329 msg.AppendAddress(sample->
tos);
1331 msg.Append(
",%d", static_cast<int>(sample->
state));
1333 msg.Append(
",overflow");
1337 msg.AppendAddress(sample->
stack[i]);
1340 msg.WriteToLogFile();
1345 return profiler_ ==
NULL || profiler_->
paused();
1351 if (profiler_ !=
NULL) {
1353 if (--cpu_profiler_nesting_ == 0) {
1355 if (FLAG_prof_lazy) {
1359 FLAG_log_code =
false;
1360 LOG(
ISOLATE, UncheckedStringEvent(
"profiler",
"pause"));
1370 if (profiler_ !=
NULL) {
1371 if (cpu_profiler_nesting_++ == 0) {
1373 if (FLAG_prof_lazy) {
1375 LOG(
ISOLATE, UncheckedStringEvent(
"profiler",
"resume"));
1376 FLAG_log_code =
true;
1379 if (!FLAG_sliding_state_window && !ticker_->
IsActive()) {
1396 bool Logger::IsProfilerSamplerActive() {
1406 : sfis_(sfis), code_objects_(code_objects), count_(count) { }
1413 Object* maybe_script = sfi->script();
1414 if (maybe_script->IsScript()
1416 if (sfis_ !=
NULL) {
1419 if (code_objects_ !=
NULL) {
1420 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
1421 code_objects_[*count_] =
Handle<Code>(
function->code());
1423 *count_ = *count_ + 1;
1435 HeapIterator iterator;
1436 AssertNoAllocation no_alloc;
1437 int compiled_funcs_count = 0;
1441 for (HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
1442 if (!obj->IsSharedFunctionInfo())
continue;
1444 if (sfi->is_compiled()
1445 && (!sfi->script()->IsScript()
1450 if (code_objects !=
NULL) {
1451 code_objects[compiled_funcs_count] = Handle<Code>(sfi->code());
1453 ++compiled_funcs_count;
1458 EnumerateOptimizedFunctionsVisitor visitor(sfis,
1460 &compiled_funcs_count);
1463 return compiled_funcs_count;
1467 void Logger::LogCodeObject(
Object*
object) {
1471 const char* description =
"Unknown code from the snapshot";
1472 switch (code_object->kind()) {
1473 case Code::FUNCTION:
1474 case Code::OPTIMIZED_FUNCTION:
1476 case Code::UNARY_OP_IC:
1477 case Code::BINARY_OP_IC:
1478 case Code::COMPARE_IC:
1479 case Code::TO_BOOLEAN_IC:
1482 CodeStub::MajorName(CodeStub::GetMajorKey(code_object),
true);
1483 if (description ==
NULL)
1484 description =
"A stub from the snapshot";
1485 tag = Logger::STUB_TAG;
1488 description =
"A builtin from the snapshot";
1489 tag = Logger::BUILTIN_TAG;
1491 case Code::KEYED_LOAD_IC:
1492 description =
"A keyed load IC from the snapshot";
1493 tag = Logger::KEYED_LOAD_IC_TAG;
1496 description =
"A load IC from the snapshot";
1497 tag = Logger::LOAD_IC_TAG;
1499 case Code::STORE_IC:
1500 description =
"A store IC from the snapshot";
1501 tag = Logger::STORE_IC_TAG;
1503 case Code::KEYED_STORE_IC:
1504 description =
"A keyed store IC from the snapshot";
1505 tag = Logger::KEYED_STORE_IC_TAG;
1508 description =
"A call IC from the snapshot";
1509 tag = Logger::CALL_IC_TAG;
1511 case Code::KEYED_CALL_IC:
1512 description =
"A keyed call IC from the snapshot";
1513 tag = Logger::KEYED_CALL_IC_TAG;
1521 void Logger::LogCodeInfo() {
1522 if (!log_->
IsEnabled() || !FLAG_ll_prof)
return;
1523 #if V8_TARGET_ARCH_IA32
1524 const char arch[] =
"ia32";
1525 #elif V8_TARGET_ARCH_X64
1526 const char arch[] =
"x64";
1527 #elif V8_TARGET_ARCH_ARM
1528 const char arch[] =
"arm";
1529 #elif V8_TARGET_ARCH_MIPS
1530 const char arch[] =
"mips";
1532 const char arch[] =
"unknown";
1534 LowLevelLogWriteBytes(arch,
sizeof(arch));
1538 void Logger::RegisterSnapshotCodeName(Code* code,
1542 if (address_to_name_map_ ==
NULL) {
1543 address_to_name_map_ =
new NameMap;
1545 address_to_name_map_->
Insert(code->address(), name, name_size);
1549 void Logger::LowLevelCodeCreateEvent(Code* code,
1552 if (log_->ll_output_handle_ ==
NULL)
return;
1553 LowLevelCodeCreateStruct event;
1554 event.name_size = name_size;
1555 event.code_address = code->instruction_start();
1557 event.code_size = code->instruction_size();
1558 LowLevelLogWriteStruct(event);
1559 LowLevelLogWriteBytes(name, name_size);
1560 LowLevelLogWriteBytes(
1561 reinterpret_cast<const char*>(code->instruction_start()),
1562 code->instruction_size());
1567 if (log_->ll_output_handle_ ==
NULL)
return;
1568 LowLevelCodeMoveStruct event;
1571 LowLevelLogWriteStruct(event);
1575 void Logger::LowLevelCodeDeleteEvent(
Address from) {
1576 if (log_->ll_output_handle_ ==
NULL)
return;
1577 LowLevelCodeDeleteStruct event;
1579 LowLevelLogWriteStruct(event);
1583 void Logger::LowLevelSnapshotPositionEvent(
Address addr,
int pos) {
1584 if (log_->ll_output_handle_ ==
NULL)
return;
1585 LowLevelSnapshotPositionStruct event;
1587 event.position = pos;
1588 LowLevelLogWriteStruct(event);
1592 void Logger::LowLevelLogWriteBytes(
const char* bytes,
int size) {
1593 size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_);
1594 ASSERT(static_cast<size_t>(size) == rv);
1601 "Logger::LogCodeObjects");
1602 HeapIterator iterator;
1604 for (
HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
1605 if (obj->IsCode()) LogCodeObject(obj);
1613 if (shared->script()->IsScript()) {
1615 if (script->name()->IsString()) {
1621 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1623 *script_name, line_num + 1));
1628 Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
1629 *code, *shared, *script_name));
1634 Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1635 *code, *shared, *func_name));
1637 }
else if (shared->IsApiFunction()) {
1640 Object* raw_call_data = fun_data->call_code();
1641 if (!raw_call_data->IsUndefined()) {
1643 Object* callback_obj = call_data->callback();
1644 Address entry_point = v8::ToCData<Address>(callback_obj);
1650 Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
1657 "Logger::LogCompiledFunctions");
1659 const int compiled_funcs_count = EnumerateCompiledFunctions(
NULL,
NULL);
1662 EnumerateCompiledFunctions(sfis.
start(), code_objects.
start());
1666 for (
int i = 0; i < compiled_funcs_count; ++i) {
1667 if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
1668 Builtins::kLazyCompile))
1677 "Logger::LogAccessorCallbacks");
1678 HeapIterator iterator;
1680 for (
HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
1681 if (!obj->IsAccessorInfo())
continue;
1683 if (!ai->name()->IsString())
continue;
1685 Address getter_entry = v8::ToCData<Address>(ai->getter());
1686 if (getter_entry != 0) {
1689 Address setter_entry = v8::ToCData<Address>(ai->setter());
1690 if (setter_entry != 0) {
1699 if (is_initialized_)
return true;
1700 is_initialized_ =
true;
1704 FLAG_log_snapshot_positions =
true;
1708 if (FLAG_prof_lazy) {
1709 FLAG_log_code =
false;
1710 FLAG_prof_auto =
false;
1719 if (FLAG_ll_prof) LogCodeInfo();
1721 Isolate* isolate = Isolate::Current();
1724 if (FLAG_sliding_state_window && sliding_state_window_ ==
NULL) {
1728 bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
1729 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
1730 || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
1732 if (start_logging) {
1733 logging_nesting_ = 1;
1738 if (!FLAG_prof_auto) {
1741 logging_nesting_ = 1;
1743 if (!FLAG_prof_lazy) {
1754 code_event_handler_ = event_handler;
1781 if (!is_initialized_)
return NULL;
1782 is_initialized_ =
false;
1785 if (profiler_ !=
NULL) {
1791 delete sliding_state_window_;
1792 sliding_state_window_ =
NULL;
1797 return log_->
Close();
1806 if (ticker_ ==
NULL) {
1807 FLAG_sliding_state_window =
true;
1812 if (sliding_state_window_ ==
NULL) {
1818 static Mutex* active_samplers_mutex =
NULL;
1824 if (!active_samplers_mutex) {
1833 ActiveSamplersExist() && i < active_samplers_->length();
1835 func(active_samplers_->at(i), param);
1837 return ActiveSamplersExist();
1841 static void ComputeCpuProfiling(
Sampler*
sampler,
void* flag_ptr) {
1842 bool*
flag =
reinterpret_cast<bool*
>(flag_ptr);
1849 if (!IterateActiveSamplers(&ComputeCpuProfiling, &flag)) {
1850 return HAS_NO_SAMPLERS;
1852 return flag ? HAS_CPU_PROFILING_SAMPLERS : HAS_SAMPLERS;
1859 if (active_samplers_ ==
NULL) {
1862 ASSERT(!active_samplers_->Contains(sampler));
1864 active_samplers_->Add(sampler);
1872 bool removed = active_samplers_->RemoveElement(sampler);
void LogRuntime(Vector< const char > format, JSArray *args)
Address external_callback
static void NewEventStatic(const char *name, void *object, size_t size)
void RegExpCodeCreateEvent(Code *code, String *source)
static CallHandlerInfo * cast(Object *obj)
void CodeMoveEvent(Address from, Address to)
SlidingStateWindow(Isolate *isolate)
virtual void VisitFunction(JSFunction *function)
void GetterCallbackEvent(String *name, Address entry_point)
void Move(Address from, Address to)
void SetterCallbackEvent(String *name, Address entry_point)
static String * cast(Object *obj)
#define LOG(isolate, Call)
bool Remove(TickSample *sample)
static void DeleteEventStatic(const char *name, void *object)
static void SignalCodeMovingGC()
static Address js_entry_sp(ThreadLocalTop *thread)
static Handle< String > cast(Handle< S > that)
void DecreaseProfilingDepth()
void EnsureTickerStopped()
virtual void Tick(TickSample *sample)
bool is_logging_code_events()
static int GetUserTime(uint32_t *secs, uint32_t *usecs)
void LogCompiledFunctions()
void CodeDeleteEvent(Address from)
void SetProfiler(Profiler *profiler)
void IntPtrTEvent(const char *name, intptr_t value)
#define ASSERT(condition)
void EnsureTickerStarted()
#define PROFILE(isolate, Call)
static Script * cast(Object *obj)
static JSRegExp * cast(Object *obj)
static SharedFunctionInfo * cast(Object *obj)
void ApiNamedSecurityCheck(Object *key)
Address stack[kMaxFramesCount]
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
void HandleEvent(const char *name, Object **location)
static Code * cast(Object *obj)
static void RemoveActiveSampler(Sampler *sampler)
static Smi * cast(Object *object)
void ApiIndexedSecurityCheck(uint32_t index)
void SnapshotPositionEvent(Address addr, int pos)
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
void AppendBytes(const char *bytes)
uint32_t ComputePointerHash(void *ptr)
void HeapSampleBeginEvent(const char *space, const char *kind)
static uchar Length(uchar chr, int previous)
void AppendBytes(const char *bytes, int size)
void LogExistingFunction(Handle< SharedFunctionInfo > shared, Handle< Code > code)
void Insert(TickSample *sample)
void IncreaseProfilingDepth()
virtual void EnterContext(Context *context)
Profiler(Isolate *isolate)
static Address & Address_at(Address addr)
void DebugEvent(const char *event_type, Vector< uint16_t > parameter)
void Insert(Address code_address, const char *name, int name_size)
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
void RegExpCompileEvent(Handle< JSRegExp > regexp, bool in_cache)
static Mutex * CreateMutex()
static double TimeCurrentMillis()
static const int kMakeHeapIterableMask
Address external_callback()
Ticker(Isolate *isolate, int interval)
virtual void LeaveContext(Context *context)
void EnableSlidingStateWindow()
void ApiNamedPropertyAccess(const char *tag, JSObject *holder, Object *name)
activate correct semantics for inheriting readonliness false
static unsigned Encode(char *out, uchar c, int previous)
int StrLength(const char *string)
void ApiIndexedPropertyAccess(const char *tag, JSObject *holder, uint32_t index)
void SharedLibraryEvent(const char *library_path, uintptr_t start, uintptr_t end)
void ApiEntryCall(const char *name)
void(* JitCodeEventHandler)(const JitCodeEvent *event)
static int SNPrintF(Vector< char > str, const char *format,...)
void HeapSampleEndEvent(const char *space, const char *kind)
int GetScriptLineNumber(Handle< Script > script, int code_pos)
#define DECLARE_EVENT(ignore1, name)
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
EnumerateOptimizedFunctionsVisitor(Handle< SharedFunctionInfo > *sfis, Handle< Code > *code_objects, int *count)
void CallbackEvent(String *name, Address entry_point)
void AddCharacter(char c)
void AddState(StateTag state)
static const int kMaxFramesCount
void HeapSampleItemEvent(const char *type, int number, int bytes)
void DeleteEvent(const char *name, void *object)
void ApiObjectAccess(const char *tag, JSObject *obj)
static const int kHeaderSize
static void LogSharedLibraryAddresses()
void * Remove(void *key, uint32_t hash)
TemplateHashMapImpl< FreeStoreAllocationPolicy > HashMap
static const int kSamplingIntervalMs
static HeapObject * FromAddress(Address address)
static const unsigned kMaxAsciiCharCodeU
static AccessorInfo * cast(Object *obj)
friend class SlidingStateWindow
static Handle< Object > GetElement(Handle< Object > object, uint32_t index)
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
void SharedFunctionInfoMoveEvent(Address from, Address to)
void IntEvent(const char *name, int value)
static void AddActiveSampler(Sampler *sampler)
void LogAccessorCallbacks()
void AppendString(String *str)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
friend class LogMessageBuilder
static bool IterateActiveSamplers(VisitSampler func, void *param)
void Remove(Address code_address)
void DeleteArray(T *array)
const char * Lookup(Address code_address)
ThreadLocalTop * thread_local_top()
virtual void DoSampleStack(TickSample *sample)
void CodeCreateEvent(LogEventsAndTags tag, Code *code, const char *source)
void DebugTag(const char *call_site_tag)
bool has_external_callback
void ResourceEvent(const char *name, const char *tag)
static JSObject * cast(Object *obj)
void NewEvent(const char *name, void *object, size_t size)
StatsCounter * state_counters(StateTag state)
Entry * Next(Entry *p) const
static const int kNoPreviousCharacter
void SetWindow(SlidingStateWindow *window)
static void Trace(Isolate *isolate, TickSample *sample)
void SuspectReadEvent(String *name, Object *obj)
#define LOG_EVENTS_AND_TAGS_LIST(V)
void StringEvent(const char *name, const char *value)
void SetCodeEventHandler(uint32_t options, JitCodeEventHandler event_handler)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset flag