Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 #include "macro-assembler.h" | 38 #include "macro-assembler.h" |
| 39 #include "platform.h" | 39 #include "platform.h" |
| 40 #include "runtime-profiler.h" | 40 #include "runtime-profiler.h" |
| 41 #include "serialize.h" | 41 #include "serialize.h" |
| 42 #include "string-stream.h" | 42 #include "string-stream.h" |
| 43 #include "vm-state-inl.h" | 43 #include "vm-state-inl.h" |
| 44 | 44 |
| 45 namespace v8 { | 45 namespace v8 { |
| 46 namespace internal { | 46 namespace internal { |
| 47 | 47 |
| 48 | |
| 49 // Low-level logging support. | |
| 50 class LowLevelLogger { | |
| 51 public: | |
|
yurys
2013/07/15 04:16:35
Consider moving this class and logic related to th
loislo
2013/07/15 07:37:00
I'd like to do that as a separate change.
| |
| 52 explicit LowLevelLogger(const char* file_name); | |
| 53 ~LowLevelLogger(); | |
| 54 | |
| 55 void CodeCreateEvent(Code* code, const char* name, int name_size); | |
| 56 void CodeMoveEvent(Address from, Address to); | |
| 57 void CodeDeleteEvent(Address from); | |
| 58 void SnapshotPositionEvent(Address addr, int pos); | |
| 59 void CodeMovingGCEvent(); | |
| 60 | |
| 61 private: | |
| 62 // Low-level profiling event structures. | |
| 63 | |
| 64 struct CodeCreateStruct { | |
| 65 static const char kTag = 'C'; | |
| 66 | |
| 67 int32_t name_size; | |
| 68 Address code_address; | |
| 69 int32_t code_size; | |
| 70 }; | |
| 71 | |
| 72 | |
| 73 struct CodeMoveStruct { | |
| 74 static const char kTag = 'M'; | |
| 75 | |
| 76 Address from_address; | |
| 77 Address to_address; | |
| 78 }; | |
| 79 | |
| 80 | |
| 81 struct CodeDeleteStruct { | |
| 82 static const char kTag = 'D'; | |
| 83 | |
| 84 Address address; | |
| 85 }; | |
| 86 | |
| 87 | |
| 88 struct SnapshotPositionStruct { | |
| 89 static const char kTag = 'P'; | |
| 90 | |
| 91 Address address; | |
| 92 int32_t position; | |
| 93 }; | |
| 94 | |
| 95 | |
| 96 static const char kCodeMovingGCTag = 'G'; | |
| 97 | |
| 98 | |
| 99 // Extension added to V8 log file name to get the low-level log name. | |
| 100 static const char kLogExt[]; | |
| 101 | |
| 102 // File buffer size of the low-level log. We don't use the default to | |
| 103 // minimize the associated overhead. | |
| 104 static const int kLogBufferSize = 2 * MB; | |
| 105 | |
| 106 void LogCodeInfo(); | |
| 107 void LogWriteBytes(const char* bytes, int size); | |
| 108 | |
| 109 template <typename T> | |
| 110 void LogWriteStruct(const T& s) { | |
| 111 char tag = T::kTag; | |
| 112 LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag)); | |
| 113 LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s)); | |
| 114 } | |
| 115 | |
| 116 FILE* ll_output_handle_; | |
| 117 }; | |
| 118 | |
| 119 const char LowLevelLogger::kLogExt[] = ".ll"; | |
| 120 | |
| 121 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | |
| 122 | |
| 123 | |
| 48 // The Profiler samples pc and sp values for the main thread. | 124 // The Profiler samples pc and sp values for the main thread. |
| 49 // Each sample is appended to a circular buffer. | 125 // Each sample is appended to a circular buffer. |
| 50 // An independent thread removes data and writes it to the log. | 126 // An independent thread removes data and writes it to the log. |
| 51 // This design minimizes the time spent in the sampler. | 127 // This design minimizes the time spent in the sampler. |
| 52 // | 128 // |
| 53 class Profiler: public Thread { | 129 class Profiler: public Thread { |
| 54 public: | 130 public: |
| 55 explicit Profiler(Isolate* isolate); | 131 explicit Profiler(Isolate* isolate); |
| 56 void Engage(); | 132 void Engage(); |
| 57 void Disengage(); | 133 void Disengage(); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 void Profiler::Run() { | 279 void Profiler::Run() { |
| 204 TickSample sample; | 280 TickSample sample; |
| 205 bool overflow = Remove(&sample); | 281 bool overflow = Remove(&sample); |
| 206 while (running_) { | 282 while (running_) { |
| 207 LOG(isolate_, TickEvent(&sample, overflow)); | 283 LOG(isolate_, TickEvent(&sample, overflow)); |
| 208 overflow = Remove(&sample); | 284 overflow = Remove(&sample); |
| 209 } | 285 } |
| 210 } | 286 } |
| 211 | 287 |
| 212 | 288 |
| 213 // Low-level profiling event structures. | |
| 214 | |
| 215 struct LowLevelCodeCreateStruct { | |
| 216 static const char kTag = 'C'; | |
| 217 | |
| 218 int32_t name_size; | |
| 219 Address code_address; | |
| 220 int32_t code_size; | |
| 221 }; | |
| 222 | |
| 223 | |
| 224 struct LowLevelCodeMoveStruct { | |
| 225 static const char kTag = 'M'; | |
| 226 | |
| 227 Address from_address; | |
| 228 Address to_address; | |
| 229 }; | |
| 230 | |
| 231 | |
| 232 struct LowLevelCodeDeleteStruct { | |
| 233 static const char kTag = 'D'; | |
| 234 | |
| 235 Address address; | |
| 236 }; | |
| 237 | |
| 238 | |
| 239 struct LowLevelSnapshotPositionStruct { | |
| 240 static const char kTag = 'P'; | |
| 241 | |
| 242 Address address; | |
| 243 int32_t position; | |
| 244 }; | |
| 245 | |
| 246 | |
| 247 static const char kCodeMovingGCTag = 'G'; | |
| 248 | |
| 249 | |
| 250 // | 289 // |
| 251 // Logger class implementation. | 290 // Logger class implementation. |
| 252 // | 291 // |
| 253 | 292 |
| 254 class Logger::NameMap { | 293 class Logger::NameMap { |
| 255 public: | 294 public: |
| 256 NameMap() : impl_(&PointerEquals) {} | 295 NameMap() : impl_(&PointerEquals) {} |
| 257 | 296 |
| 258 ~NameMap() { | 297 ~NameMap() { |
| 259 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | 298 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 | 437 |
| 399 | 438 |
| 400 Logger::Logger(Isolate* isolate) | 439 Logger::Logger(Isolate* isolate) |
| 401 : isolate_(isolate), | 440 : isolate_(isolate), |
| 402 ticker_(NULL), | 441 ticker_(NULL), |
| 403 profiler_(NULL), | 442 profiler_(NULL), |
| 404 log_events_(NULL), | 443 log_events_(NULL), |
| 405 logging_nesting_(0), | 444 logging_nesting_(0), |
| 406 cpu_profiler_nesting_(0), | 445 cpu_profiler_nesting_(0), |
| 407 log_(new Log(this)), | 446 log_(new Log(this)), |
| 447 ll_logger_(NULL), | |
| 408 name_buffer_(new NameBuffer), | 448 name_buffer_(new NameBuffer), |
| 409 address_to_name_map_(NULL), | 449 address_to_name_map_(NULL), |
| 410 is_initialized_(false), | 450 is_initialized_(false), |
| 411 code_event_handler_(NULL), | 451 code_event_handler_(NULL), |
| 412 last_address_(NULL), | 452 last_address_(NULL), |
| 413 prev_sp_(NULL), | 453 prev_sp_(NULL), |
| 414 prev_function_(NULL), | 454 prev_function_(NULL), |
| 415 prev_to_(NULL), | 455 prev_to_(NULL), |
| 416 prev_code_(NULL), | 456 prev_code_(NULL), |
| 417 epoch_(0) { | 457 epoch_(0) { |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 void Logger::LogRecordedBuffer(Code* code, SharedFunctionInfo* shared) { | 985 void Logger::LogRecordedBuffer(Code* code, SharedFunctionInfo* shared) { |
| 946 if (code_event_handler_ != NULL) { | 986 if (code_event_handler_ != NULL) { |
| 947 Script* script = shared && shared->script()->IsScript() ? | 987 Script* script = shared && shared->script()->IsScript() ? |
| 948 Script::cast(shared->script()) : NULL; | 988 Script::cast(shared->script()) : NULL; |
| 949 IssueCodeAddedEvent(code, | 989 IssueCodeAddedEvent(code, |
| 950 script, | 990 script, |
| 951 name_buffer_->get(), | 991 name_buffer_->get(), |
| 952 name_buffer_->size()); | 992 name_buffer_->size()); |
| 953 } | 993 } |
| 954 if (!log_->IsEnabled()) return; | 994 if (!log_->IsEnabled()) return; |
| 955 if (FLAG_ll_prof) { | 995 LL_LOG(CodeCreateEvent(code, name_buffer_->get(), name_buffer_->size())); |
| 956 LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); | |
| 957 } | |
| 958 if (Serializer::enabled()) { | 996 if (Serializer::enabled()) { |
| 959 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); | 997 RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| 960 } | 998 } |
| 961 } | 999 } |
| 962 | 1000 |
| 963 | 1001 |
| 964 void Logger::AppendCodeCreateHeader(LogMessageBuilder* msg, | 1002 void Logger::AppendCodeCreateHeader(LogMessageBuilder* msg, |
| 965 LogEventsAndTags tag, | 1003 LogEventsAndTags tag, |
| 966 Code* code) { | 1004 Code* code) { |
| 967 ASSERT(msg); | 1005 ASSERT(msg); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1135 LogMessageBuilder msg(this); | 1173 LogMessageBuilder msg(this); |
| 1136 AppendCodeCreateHeader(&msg, tag, code); | 1174 AppendCodeCreateHeader(&msg, tag, code); |
| 1137 msg.Append("\"args_count: %d\"", args_count); | 1175 msg.Append("\"args_count: %d\"", args_count); |
| 1138 msg.Append('\n'); | 1176 msg.Append('\n'); |
| 1139 msg.WriteToLogFile(); | 1177 msg.WriteToLogFile(); |
| 1140 } | 1178 } |
| 1141 | 1179 |
| 1142 | 1180 |
| 1143 void Logger::CodeMovingGCEvent() { | 1181 void Logger::CodeMovingGCEvent() { |
| 1144 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1182 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1145 LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag)); | 1183 LL_LOG(CodeMovingGCEvent()); |
| 1146 OS::SignalCodeMovingGC(); | 1184 OS::SignalCodeMovingGC(); |
| 1147 } | 1185 } |
| 1148 | 1186 |
| 1149 | 1187 |
| 1150 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1188 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 1151 if (!is_logging_code_events()) return; | 1189 if (!is_logging_code_events()) return; |
| 1152 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { | 1190 if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) { |
| 1153 InitNameBuffer(REG_EXP_TAG); | 1191 InitNameBuffer(REG_EXP_TAG); |
| 1154 name_buffer_->AppendString(source); | 1192 name_buffer_->AppendString(source); |
| 1155 LogRecordedBuffer(code, NULL); | 1193 LogRecordedBuffer(code, NULL); |
| 1156 } | 1194 } |
| 1157 | 1195 |
| 1158 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1196 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1159 LogMessageBuilder msg(this); | 1197 LogMessageBuilder msg(this); |
| 1160 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1198 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1161 msg.Append('"'); | 1199 msg.Append('"'); |
| 1162 msg.AppendDetailed(source, false); | 1200 msg.AppendDetailed(source, false); |
| 1163 msg.Append('"'); | 1201 msg.Append('"'); |
| 1164 msg.Append('\n'); | 1202 msg.Append('\n'); |
| 1165 msg.WriteToLogFile(); | 1203 msg.WriteToLogFile(); |
| 1166 } | 1204 } |
| 1167 | 1205 |
| 1168 | 1206 |
| 1169 void Logger::CodeMoveEvent(Address from, Address to) { | 1207 void Logger::CodeMoveEvent(Address from, Address to) { |
| 1170 if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to); | 1208 if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to); |
| 1171 if (!log_->IsEnabled()) return; | 1209 if (!log_->IsEnabled()) return; |
| 1172 if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to); | 1210 LL_LOG(CodeMoveEvent(from, to)); |
| 1173 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1211 if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| 1174 address_to_name_map_->Move(from, to); | 1212 address_to_name_map_->Move(from, to); |
| 1175 } | 1213 } |
| 1176 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1214 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| 1177 } | 1215 } |
| 1178 | 1216 |
| 1179 | 1217 |
| 1180 void Logger::CodeDeleteEvent(Address from) { | 1218 void Logger::CodeDeleteEvent(Address from) { |
| 1181 if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from); | 1219 if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from); |
| 1182 if (!log_->IsEnabled()) return; | 1220 if (!log_->IsEnabled()) return; |
| 1183 if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from); | 1221 LL_LOG(CodeDeleteEvent(from)); |
| 1184 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1222 if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| 1185 address_to_name_map_->Remove(from); | 1223 address_to_name_map_->Remove(from); |
| 1186 } | 1224 } |
| 1187 DeleteEventInternal(CODE_DELETE_EVENT, from); | 1225 DeleteEventInternal(CODE_DELETE_EVENT, from); |
| 1188 } | 1226 } |
| 1189 | 1227 |
| 1190 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1228 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1191 int pc_offset, | 1229 int pc_offset, |
| 1192 int position) { | 1230 int position) { |
| 1193 if (code_event_handler_ != NULL) { | 1231 if (code_event_handler_ != NULL) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1219 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | 1257 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, |
| 1220 void* jit_handler_data) { | 1258 void* jit_handler_data) { |
| 1221 if (code_event_handler_ != NULL) { | 1259 if (code_event_handler_ != NULL) { |
| 1222 IssueEndCodePosInfoEvent(code, jit_handler_data); | 1260 IssueEndCodePosInfoEvent(code, jit_handler_data); |
| 1223 } | 1261 } |
| 1224 } | 1262 } |
| 1225 | 1263 |
| 1226 | 1264 |
| 1227 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1265 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| 1228 if (!log_->IsEnabled()) return; | 1266 if (!log_->IsEnabled()) return; |
| 1229 if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos); | 1267 LL_LOG(SnapshotPositionEvent(addr, pos)); |
| 1230 if (Serializer::enabled() && address_to_name_map_ != NULL) { | 1268 if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| 1231 const char* code_name = address_to_name_map_->Lookup(addr); | 1269 const char* code_name = address_to_name_map_->Lookup(addr); |
| 1232 if (code_name == NULL) return; // Not a code object. | 1270 if (code_name == NULL) return; // Not a code object. |
| 1233 LogMessageBuilder msg(this); | 1271 LogMessageBuilder msg(this); |
| 1234 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | 1272 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1235 msg.AppendDoubleQuotedString(code_name); | 1273 msg.AppendDoubleQuotedString(code_name); |
| 1236 msg.Append("\n"); | 1274 msg.Append("\n"); |
| 1237 msg.WriteToLogFile(); | 1275 msg.WriteToLogFile(); |
| 1238 } | 1276 } |
| 1239 if (!FLAG_log_snapshot_positions) return; | 1277 if (!FLAG_log_snapshot_positions) return; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1557 description = "A keyed call IC from the snapshot"; | 1595 description = "A keyed call IC from the snapshot"; |
| 1558 tag = Logger::KEYED_CALL_IC_TAG; | 1596 tag = Logger::KEYED_CALL_IC_TAG; |
| 1559 break; | 1597 break; |
| 1560 case Code::NUMBER_OF_KINDS: | 1598 case Code::NUMBER_OF_KINDS: |
| 1561 break; | 1599 break; |
| 1562 } | 1600 } |
| 1563 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); | 1601 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); |
| 1564 } | 1602 } |
| 1565 | 1603 |
| 1566 | 1604 |
| 1567 void Logger::LogCodeInfo() { | 1605 void Logger::RegisterSnapshotCodeName(Code* code, |
| 1568 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1606 const char* name, |
| 1607 int name_size) { | |
| 1608 ASSERT(Serializer::enabled()); | |
| 1609 if (address_to_name_map_ == NULL) { | |
| 1610 address_to_name_map_ = new NameMap; | |
| 1611 } | |
| 1612 address_to_name_map_->Insert(code->address(), name, name_size); | |
| 1613 } | |
| 1614 | |
| 1615 | |
| 1616 LowLevelLogger::LowLevelLogger(const char* name) | |
| 1617 : ll_output_handle_(NULL) { | |
| 1618 // Open the low-level log file. | |
| 1619 size_t len = strlen(name); | |
| 1620 ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt))); | |
| 1621 OS::MemCopy(ll_name.start(), name, len); | |
| 1622 OS::MemCopy(ll_name.start() + len, kLogExt, sizeof(kLogExt)); | |
| 1623 ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); | |
| 1624 setvbuf(ll_output_handle_, NULL, _IOFBF, kLogBufferSize); | |
| 1625 | |
| 1626 LogCodeInfo(); | |
| 1627 } | |
| 1628 | |
| 1629 | |
| 1630 LowLevelLogger::~LowLevelLogger() { | |
| 1631 fclose(ll_output_handle_); | |
| 1632 ll_output_handle_ = NULL; | |
| 1633 } | |
| 1634 | |
| 1635 | |
| 1636 void LowLevelLogger::LogCodeInfo() { | |
| 1569 #if V8_TARGET_ARCH_IA32 | 1637 #if V8_TARGET_ARCH_IA32 |
| 1570 const char arch[] = "ia32"; | 1638 const char arch[] = "ia32"; |
| 1571 #elif V8_TARGET_ARCH_X64 | 1639 #elif V8_TARGET_ARCH_X64 |
| 1572 const char arch[] = "x64"; | 1640 const char arch[] = "x64"; |
| 1573 #elif V8_TARGET_ARCH_ARM | 1641 #elif V8_TARGET_ARCH_ARM |
| 1574 const char arch[] = "arm"; | 1642 const char arch[] = "arm"; |
| 1575 #elif V8_TARGET_ARCH_MIPS | 1643 #elif V8_TARGET_ARCH_MIPS |
| 1576 const char arch[] = "mips"; | 1644 const char arch[] = "mips"; |
| 1577 #else | 1645 #else |
| 1578 const char arch[] = "unknown"; | 1646 const char arch[] = "unknown"; |
| 1579 #endif | 1647 #endif |
| 1580 LowLevelLogWriteBytes(arch, sizeof(arch)); | 1648 LogWriteBytes(arch, sizeof(arch)); |
| 1581 } | 1649 } |
| 1582 | 1650 |
| 1583 | 1651 void LowLevelLogger::CodeCreateEvent(Code* code, |
| 1584 void Logger::RegisterSnapshotCodeName(Code* code, | |
| 1585 const char* name, | |
| 1586 int name_size) { | |
| 1587 ASSERT(Serializer::enabled()); | |
| 1588 if (address_to_name_map_ == NULL) { | |
| 1589 address_to_name_map_ = new NameMap; | |
| 1590 } | |
| 1591 address_to_name_map_->Insert(code->address(), name, name_size); | |
| 1592 } | |
| 1593 | |
| 1594 | |
| 1595 void Logger::LowLevelCodeCreateEvent(Code* code, | |
| 1596 const char* name, | 1652 const char* name, |
| 1597 int name_size) { | 1653 int name_size) { |
| 1598 if (log_->ll_output_handle_ == NULL) return; | 1654 CodeCreateStruct event; |
| 1599 LowLevelCodeCreateStruct event; | |
| 1600 event.name_size = name_size; | 1655 event.name_size = name_size; |
| 1601 event.code_address = code->instruction_start(); | 1656 event.code_address = code->instruction_start(); |
| 1602 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | 1657 ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
| 1603 event.code_size = code->instruction_size(); | 1658 event.code_size = code->instruction_size(); |
| 1604 LowLevelLogWriteStruct(event); | 1659 LogWriteStruct(event); |
| 1605 LowLevelLogWriteBytes(name, name_size); | 1660 LogWriteBytes(name, name_size); |
| 1606 LowLevelLogWriteBytes( | 1661 LogWriteBytes( |
| 1607 reinterpret_cast<const char*>(code->instruction_start()), | 1662 reinterpret_cast<const char*>(code->instruction_start()), |
| 1608 code->instruction_size()); | 1663 code->instruction_size()); |
| 1609 } | 1664 } |
| 1610 | 1665 |
| 1611 | 1666 |
| 1612 void Logger::LowLevelCodeMoveEvent(Address from, Address to) { | 1667 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { |
| 1613 if (log_->ll_output_handle_ == NULL) return; | 1668 CodeMoveStruct event; |
| 1614 LowLevelCodeMoveStruct event; | |
| 1615 event.from_address = from + Code::kHeaderSize; | 1669 event.from_address = from + Code::kHeaderSize; |
| 1616 event.to_address = to + Code::kHeaderSize; | 1670 event.to_address = to + Code::kHeaderSize; |
| 1617 LowLevelLogWriteStruct(event); | 1671 LogWriteStruct(event); |
| 1618 } | 1672 } |
| 1619 | 1673 |
| 1620 | 1674 |
| 1621 void Logger::LowLevelCodeDeleteEvent(Address from) { | 1675 void LowLevelLogger::CodeDeleteEvent(Address from) { |
| 1622 if (log_->ll_output_handle_ == NULL) return; | 1676 CodeDeleteStruct event; |
| 1623 LowLevelCodeDeleteStruct event; | |
| 1624 event.address = from + Code::kHeaderSize; | 1677 event.address = from + Code::kHeaderSize; |
| 1625 LowLevelLogWriteStruct(event); | 1678 LogWriteStruct(event); |
| 1626 } | 1679 } |
| 1627 | 1680 |
| 1628 | 1681 |
| 1629 void Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) { | 1682 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { |
| 1630 if (log_->ll_output_handle_ == NULL) return; | 1683 SnapshotPositionStruct event; |
| 1631 LowLevelSnapshotPositionStruct event; | |
| 1632 event.address = addr + Code::kHeaderSize; | 1684 event.address = addr + Code::kHeaderSize; |
| 1633 event.position = pos; | 1685 event.position = pos; |
| 1634 LowLevelLogWriteStruct(event); | 1686 LogWriteStruct(event); |
| 1635 } | 1687 } |
| 1636 | 1688 |
| 1637 | 1689 |
| 1638 void Logger::LowLevelLogWriteBytes(const char* bytes, int size) { | 1690 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { |
| 1639 size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_); | 1691 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); |
| 1640 ASSERT(static_cast<size_t>(size) == rv); | 1692 ASSERT(static_cast<size_t>(size) == rv); |
| 1641 USE(rv); | 1693 USE(rv); |
| 1642 } | 1694 } |
| 1643 | 1695 |
| 1644 | 1696 |
| 1697 void LowLevelLogger::CodeMovingGCEvent() { | |
| 1698 const char tag = kCodeMovingGCTag; | |
| 1699 | |
| 1700 LogWriteBytes(&tag, sizeof(tag)); | |
| 1701 } | |
| 1702 | |
| 1703 | |
| 1645 void Logger::LogCodeObjects() { | 1704 void Logger::LogCodeObjects() { |
| 1646 Heap* heap = isolate_->heap(); | 1705 Heap* heap = isolate_->heap(); |
| 1647 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1706 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1648 "Logger::LogCodeObjects"); | 1707 "Logger::LogCodeObjects"); |
| 1649 HeapIterator iterator(heap); | 1708 HeapIterator iterator(heap); |
| 1650 DisallowHeapAllocation no_gc; | 1709 DisallowHeapAllocation no_gc; |
| 1651 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1710 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1652 if (obj->IsCode()) LogCodeObject(obj); | 1711 if (obj->IsCode()) LogCodeObject(obj); |
| 1653 } | 1712 } |
| 1654 } | 1713 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1737 PROFILE(isolate_, GetterCallbackEvent(name, getter_entry)); | 1796 PROFILE(isolate_, GetterCallbackEvent(name, getter_entry)); |
| 1738 } | 1797 } |
| 1739 Address setter_entry = v8::ToCData<Address>(ai->setter()); | 1798 Address setter_entry = v8::ToCData<Address>(ai->setter()); |
| 1740 if (setter_entry != 0) { | 1799 if (setter_entry != 0) { |
| 1741 PROFILE(isolate_, SetterCallbackEvent(name, setter_entry)); | 1800 PROFILE(isolate_, SetterCallbackEvent(name, setter_entry)); |
| 1742 } | 1801 } |
| 1743 } | 1802 } |
| 1744 } | 1803 } |
| 1745 | 1804 |
| 1746 | 1805 |
| 1806 static void AddIsolateIdIfNeeded(StringStream* stream) { | |
| 1807 Isolate* isolate = Isolate::Current(); | |
| 1808 if (isolate->IsDefaultIsolate()) return; | |
| 1809 stream->Add("isolate-%p-", isolate); | |
| 1810 } | |
| 1811 | |
| 1812 | |
| 1813 static SmartArrayPointer<const char> PrepareLogFileName(const char* file_name) { | |
| 1814 if (strchr(FLAG_logfile, '%') != NULL || | |
|
yurys
2013/07/15 04:16:35
FLAG_logfile is passed as the parameter and read h
loislo
2013/07/15 07:37:00
FLAG_logfile was replaced with file_name
| |
| 1815 !Isolate::Current()->IsDefaultIsolate()) { | |
| 1816 // If there's a '%' in the log file name we have to expand | |
| 1817 // placeholders. | |
| 1818 HeapStringAllocator allocator; | |
| 1819 StringStream stream(&allocator); | |
| 1820 AddIsolateIdIfNeeded(&stream); | |
| 1821 for (const char* p = FLAG_logfile; *p; p++) { | |
| 1822 if (*p == '%') { | |
| 1823 p++; | |
| 1824 switch (*p) { | |
| 1825 case '\0': | |
| 1826 // If there's a % at the end of the string we back up | |
| 1827 // one character so we can escape the loop properly. | |
| 1828 p--; | |
| 1829 break; | |
| 1830 case 'p': | |
| 1831 stream.Add("%d", OS::GetCurrentProcessId()); | |
| 1832 break; | |
| 1833 case 't': { | |
| 1834 // %t expands to the current time in milliseconds. | |
| 1835 double time = OS::TimeCurrentMillis(); | |
| 1836 stream.Add("%.0f", FmtElm(time)); | |
| 1837 break; | |
| 1838 } | |
| 1839 case '%': | |
| 1840 // %% expands (contracts really) to %. | |
| 1841 stream.Put('%'); | |
| 1842 break; | |
| 1843 default: | |
| 1844 // All other %'s expand to themselves. | |
| 1845 stream.Put('%'); | |
| 1846 stream.Put(*p); | |
| 1847 break; | |
| 1848 } | |
| 1849 } else { | |
| 1850 stream.Put(*p); | |
| 1851 } | |
| 1852 } | |
| 1853 return SmartArrayPointer<const char>(stream.ToCString()); | |
| 1854 } | |
| 1855 int length = StrLength(file_name); | |
| 1856 char* str = NewArray<char>(length + 1); | |
| 1857 OS::MemCopy(str, file_name, length); | |
| 1858 str[length] = '\0'; | |
| 1859 return SmartArrayPointer<const char>(str); | |
| 1860 } | |
| 1861 | |
| 1862 | |
| 1747 bool Logger::SetUp(Isolate* isolate) { | 1863 bool Logger::SetUp(Isolate* isolate) { |
| 1748 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. | 1864 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. |
| 1749 if (is_initialized_) return true; | 1865 if (is_initialized_) return true; |
| 1750 is_initialized_ = true; | 1866 is_initialized_ = true; |
| 1751 | 1867 |
| 1752 // --ll-prof implies --log-code and --log-snapshot-positions. | 1868 // --ll-prof implies --log-code and --log-snapshot-positions. |
| 1753 if (FLAG_ll_prof) { | 1869 if (FLAG_ll_prof) { |
| 1754 FLAG_log_snapshot_positions = true; | 1870 FLAG_log_snapshot_positions = true; |
| 1755 } | 1871 } |
| 1756 | 1872 |
| 1757 // --prof_lazy controls --log-code, implies --noprof_auto. | 1873 // --prof_lazy controls --log-code, implies --noprof_auto. |
| 1758 if (FLAG_prof_lazy) { | 1874 if (FLAG_prof_lazy) { |
| 1759 FLAG_log_code = false; | 1875 FLAG_log_code = false; |
| 1760 FLAG_prof_auto = false; | 1876 FLAG_prof_auto = false; |
| 1761 } | 1877 } |
| 1762 | 1878 |
| 1763 log_->Initialize(); | 1879 SmartArrayPointer<const char> log_file_name = |
| 1880 PrepareLogFileName(FLAG_logfile); | |
| 1881 log_->Initialize(*log_file_name); | |
| 1764 | 1882 |
| 1765 if (FLAG_ll_prof) LogCodeInfo(); | 1883 if (FLAG_ll_prof && Log::InitLogAtStart()) { |
|
yurys
2013/07/15 04:16:35
Log::InitLogAtStart() check is redundant.
loislo
2013/07/15 07:37:00
Done.
| |
| 1884 ll_logger_ = new LowLevelLogger(*log_file_name); | |
| 1885 } | |
| 1766 | 1886 |
| 1767 ticker_ = new Ticker(isolate, kSamplingIntervalMs); | 1887 ticker_ = new Ticker(isolate, kSamplingIntervalMs); |
| 1768 | 1888 |
| 1769 if (Log::InitLogAtStart()) { | 1889 if (Log::InitLogAtStart()) { |
| 1770 logging_nesting_ = 1; | 1890 logging_nesting_ = 1; |
| 1771 } | 1891 } |
| 1772 | 1892 |
| 1773 if (FLAG_prof) { | 1893 if (FLAG_prof) { |
| 1774 profiler_ = new Profiler(isolate); | 1894 profiler_ = new Profiler(isolate); |
| 1775 if (!FLAG_prof_auto) { | 1895 if (!FLAG_prof_auto) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1812 // Stop the profiler before closing the file. | 1932 // Stop the profiler before closing the file. |
| 1813 if (profiler_ != NULL) { | 1933 if (profiler_ != NULL) { |
| 1814 profiler_->Disengage(); | 1934 profiler_->Disengage(); |
| 1815 delete profiler_; | 1935 delete profiler_; |
| 1816 profiler_ = NULL; | 1936 profiler_ = NULL; |
| 1817 } | 1937 } |
| 1818 | 1938 |
| 1819 delete ticker_; | 1939 delete ticker_; |
| 1820 ticker_ = NULL; | 1940 ticker_ = NULL; |
| 1821 | 1941 |
| 1942 if (ll_logger_) { | |
| 1943 delete ll_logger_; | |
| 1944 ll_logger_ = NULL; | |
| 1945 } | |
| 1946 | |
| 1822 return log_->Close(); | 1947 return log_->Close(); |
| 1823 } | 1948 } |
| 1824 | 1949 |
|
yurys
2013/07/15 04:16:35
#undefine LL_LOG ?
loislo
2013/07/15 07:37:00
I see no reasons to do that because it gives us no
| |
| 1825 } } // namespace v8::internal | 1950 } } // namespace v8::internal |
| OLD | NEW |