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

Side by Side Diff: src/log.cc

Issue 18259024: Logger: extract low level logging code into a separate class. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: comments addressed Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/log.h ('k') | src/log-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 27 matching lines...) Expand all
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:
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
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
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
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
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
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
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
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(file_name, '%') != NULL ||
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 = file_name; *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) {
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
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
1825 } } // namespace v8::internal 1950 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/log.h ('k') | src/log-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698