| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 | 49 |
| 50 #define DECLARE_EVENT(ignore1, name) name, | 50 #define DECLARE_EVENT(ignore1, name) name, |
| 51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { | 51 static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| 52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) | 52 LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) |
| 53 }; | 53 }; |
| 54 #undef DECLARE_EVENT | 54 #undef DECLARE_EVENT |
| 55 | 55 |
| 56 | 56 |
| 57 #define CALL_LISTENERS(Call) \ |
| 58 for (int i = 0; i < listeners_.length(); ++i) { \ |
| 59 listeners_[i]->Call; \ |
| 60 } |
| 61 |
| 62 #define PROFILER_LOG(Call) \ |
| 63 do { \ |
| 64 CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \ |
| 65 if (cpu_profiler->is_profiling()) { \ |
| 66 cpu_profiler->Call; \ |
| 67 } \ |
| 68 } while (false); |
| 69 |
| 57 // ComputeMarker must only be used when SharedFunctionInfo is known. | 70 // ComputeMarker must only be used when SharedFunctionInfo is known. |
| 58 static const char* ComputeMarker(Code* code) { | 71 static const char* ComputeMarker(Code* code) { |
| 59 switch (code->kind()) { | 72 switch (code->kind()) { |
| 60 case Code::FUNCTION: return code->optimizable() ? "~" : ""; | 73 case Code::FUNCTION: return code->optimizable() ? "~" : ""; |
| 61 case Code::OPTIMIZED_FUNCTION: return "*"; | 74 case Code::OPTIMIZED_FUNCTION: return "*"; |
| 62 default: return ""; | 75 default: return ""; |
| 63 } | 76 } |
| 64 } | 77 } |
| 65 | 78 |
| 66 | 79 |
| 67 class CodeEventLogger { | 80 class CodeEventLogger::NameBuffer { |
| 68 public: | 81 public: |
| 69 virtual ~CodeEventLogger() { } | 82 NameBuffer() { Reset(); } |
| 70 | 83 |
| 71 void CodeCreateEvent(Logger::LogEventsAndTags tag, | 84 void Reset() { |
| 72 Code* code, | 85 utf8_pos_ = 0; |
| 73 const char* comment); | 86 } |
| 74 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 75 Code* code, | |
| 76 Name* name); | |
| 77 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 78 Code* code, | |
| 79 int args_count); | |
| 80 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 81 Code* code, | |
| 82 SharedFunctionInfo* shared, | |
| 83 CompilationInfo* info, | |
| 84 Name* name); | |
| 85 void CodeCreateEvent(Logger::LogEventsAndTags tag, | |
| 86 Code* code, | |
| 87 SharedFunctionInfo* shared, | |
| 88 CompilationInfo* info, | |
| 89 Name* source, | |
| 90 int line); | |
| 91 void RegExpCodeCreateEvent(Code* code, String* source); | |
| 92 | 87 |
| 93 protected: | 88 void Init(Logger::LogEventsAndTags tag) { |
| 94 class NameBuffer { | 89 Reset(); |
| 95 public: | 90 AppendBytes(kLogEventsNames[tag]); |
| 96 NameBuffer() { Reset(); } | 91 AppendByte(':'); |
| 92 } |
| 97 | 93 |
| 98 void Reset() { | 94 void AppendName(Name* name) { |
| 99 utf8_pos_ = 0; | 95 if (name->IsString()) { |
| 96 AppendString(String::cast(name)); |
| 97 } else { |
| 98 Symbol* symbol = Symbol::cast(name); |
| 99 AppendBytes("symbol("); |
| 100 if (!symbol->name()->IsUndefined()) { |
| 101 AppendBytes("\""); |
| 102 AppendString(String::cast(symbol->name())); |
| 103 AppendBytes("\" "); |
| 104 } |
| 105 AppendBytes("hash "); |
| 106 AppendHex(symbol->Hash()); |
| 107 AppendByte(')'); |
| 100 } | 108 } |
| 109 } |
| 101 | 110 |
| 102 void Init(Logger::LogEventsAndTags tag) { | 111 void AppendString(String* str) { |
| 103 Reset(); | 112 if (str == NULL) return; |
| 104 AppendBytes(kLogEventsNames[tag]); | 113 int uc16_length = Min(str->length(), kUtf16BufferSize); |
| 105 AppendByte(':'); | 114 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); |
| 115 int previous = unibrow::Utf16::kNoPreviousCharacter; |
| 116 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { |
| 117 uc16 c = utf16_buffer[i]; |
| 118 if (c <= unibrow::Utf8::kMaxOneByteChar) { |
| 119 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); |
| 120 } else { |
| 121 int char_length = unibrow::Utf8::Length(c, previous); |
| 122 if (utf8_pos_ + char_length > kUtf8BufferSize) break; |
| 123 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); |
| 124 utf8_pos_ += char_length; |
| 125 } |
| 126 previous = c; |
| 106 } | 127 } |
| 128 } |
| 107 | 129 |
| 108 void AppendName(Name* name) { | 130 void AppendBytes(const char* bytes, int size) { |
| 109 if (name->IsString()) { | 131 size = Min(size, kUtf8BufferSize - utf8_pos_); |
| 110 AppendString(String::cast(name)); | 132 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); |
| 111 } else { | 133 utf8_pos_ += size; |
| 112 Symbol* symbol = Symbol::cast(name); | 134 } |
| 113 AppendBytes("symbol("); | |
| 114 if (!symbol->name()->IsUndefined()) { | |
| 115 AppendBytes("\""); | |
| 116 AppendString(String::cast(symbol->name())); | |
| 117 AppendBytes("\" "); | |
| 118 } | |
| 119 AppendBytes("hash "); | |
| 120 AppendHex(symbol->Hash()); | |
| 121 AppendByte(')'); | |
| 122 } | |
| 123 } | |
| 124 | 135 |
| 125 void AppendString(String* str) { | 136 void AppendBytes(const char* bytes) { |
| 126 if (str == NULL) return; | 137 AppendBytes(bytes, StrLength(bytes)); |
| 127 int uc16_length = Min(str->length(), kUtf16BufferSize); | 138 } |
| 128 String::WriteToFlat(str, utf16_buffer, 0, uc16_length); | |
| 129 int previous = unibrow::Utf16::kNoPreviousCharacter; | |
| 130 for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { | |
| 131 uc16 c = utf16_buffer[i]; | |
| 132 if (c <= unibrow::Utf8::kMaxOneByteChar) { | |
| 133 utf8_buffer_[utf8_pos_++] = static_cast<char>(c); | |
| 134 } else { | |
| 135 int char_length = unibrow::Utf8::Length(c, previous); | |
| 136 if (utf8_pos_ + char_length > kUtf8BufferSize) break; | |
| 137 unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c, previous); | |
| 138 utf8_pos_ += char_length; | |
| 139 } | |
| 140 previous = c; | |
| 141 } | |
| 142 } | |
| 143 | 139 |
| 144 void AppendBytes(const char* bytes, int size) { | 140 void AppendByte(char c) { |
| 145 size = Min(size, kUtf8BufferSize - utf8_pos_); | 141 if (utf8_pos_ >= kUtf8BufferSize) return; |
| 146 OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size); | 142 utf8_buffer_[utf8_pos_++] = c; |
| 143 } |
| 144 |
| 145 void AppendInt(int n) { |
| 146 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 147 kUtf8BufferSize - utf8_pos_); |
| 148 int size = OS::SNPrintF(buffer, "%d", n); |
| 149 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| 147 utf8_pos_ += size; | 150 utf8_pos_ += size; |
| 148 } | 151 } |
| 152 } |
| 149 | 153 |
| 150 void AppendBytes(const char* bytes) { | 154 void AppendHex(uint32_t n) { |
| 151 AppendBytes(bytes, StrLength(bytes)); | 155 Vector<char> buffer(utf8_buffer_ + utf8_pos_, |
| 156 kUtf8BufferSize - utf8_pos_); |
| 157 int size = OS::SNPrintF(buffer, "%x", n); |
| 158 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| 159 utf8_pos_ += size; |
| 152 } | 160 } |
| 161 } |
| 153 | 162 |
| 154 void AppendByte(char c) { | 163 const char* get() { return utf8_buffer_; } |
| 155 if (utf8_pos_ >= kUtf8BufferSize) return; | 164 int size() const { return utf8_pos_; } |
| 156 utf8_buffer_[utf8_pos_++] = c; | |
| 157 } | |
| 158 | |
| 159 void AppendInt(int n) { | |
| 160 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
| 161 kUtf8BufferSize - utf8_pos_); | |
| 162 int size = OS::SNPrintF(buffer, "%d", n); | |
| 163 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 164 utf8_pos_ += size; | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 void AppendHex(uint32_t n) { | |
| 169 Vector<char> buffer(utf8_buffer_ + utf8_pos_, | |
| 170 kUtf8BufferSize - utf8_pos_); | |
| 171 int size = OS::SNPrintF(buffer, "%x", n); | |
| 172 if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { | |
| 173 utf8_pos_ += size; | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 const char* get() { return utf8_buffer_; } | |
| 178 int size() const { return utf8_pos_; } | |
| 179 | |
| 180 private: | |
| 181 static const int kUtf8BufferSize = 512; | |
| 182 static const int kUtf16BufferSize = 128; | |
| 183 | |
| 184 int utf8_pos_; | |
| 185 char utf8_buffer_[kUtf8BufferSize]; | |
| 186 uc16 utf16_buffer[kUtf16BufferSize]; | |
| 187 }; | |
| 188 | 165 |
| 189 private: | 166 private: |
| 190 virtual void LogRecordedBuffer(Code* code, | 167 static const int kUtf8BufferSize = 512; |
| 191 SharedFunctionInfo* shared, | 168 static const int kUtf16BufferSize = 128; |
| 192 NameBuffer* name_buffer) = 0; | |
| 193 | 169 |
| 194 NameBuffer name_buffer_; | 170 int utf8_pos_; |
| 171 char utf8_buffer_[kUtf8BufferSize]; |
| 172 uc16 utf16_buffer[kUtf16BufferSize]; |
| 195 }; | 173 }; |
| 196 | 174 |
| 197 | 175 |
| 176 CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { } |
| 177 |
| 178 CodeEventLogger::~CodeEventLogger() { delete name_buffer_; } |
| 179 |
| 180 |
| 198 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 181 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 199 Code* code, | 182 Code* code, |
| 200 const char* comment) { | 183 const char* comment) { |
| 201 name_buffer_.Init(tag); | 184 name_buffer_->Init(tag); |
| 202 name_buffer_.AppendBytes(comment); | 185 name_buffer_->AppendBytes(comment); |
| 203 LogRecordedBuffer(code, NULL, &name_buffer_); | 186 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 204 } | 187 } |
| 205 | 188 |
| 206 | 189 |
| 207 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 190 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 208 Code* code, | 191 Code* code, |
| 209 Name* name) { | 192 Name* name) { |
| 210 name_buffer_.Init(tag); | 193 name_buffer_->Init(tag); |
| 211 name_buffer_.AppendName(name); | 194 name_buffer_->AppendName(name); |
| 212 LogRecordedBuffer(code, NULL, &name_buffer_); | 195 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 213 } | 196 } |
| 214 | 197 |
| 215 | 198 |
| 216 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 199 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 217 Code* code, | 200 Code* code, |
| 218 SharedFunctionInfo* shared, | 201 SharedFunctionInfo* shared, |
| 219 CompilationInfo* info, | 202 CompilationInfo* info, |
| 220 Name* name) { | 203 Name* name) { |
| 221 name_buffer_.Init(tag); | 204 name_buffer_->Init(tag); |
| 222 name_buffer_.AppendBytes(ComputeMarker(code)); | 205 name_buffer_->AppendBytes(ComputeMarker(code)); |
| 223 name_buffer_.AppendName(name); | 206 name_buffer_->AppendName(name); |
| 224 LogRecordedBuffer(code, shared, &name_buffer_); | 207 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
| 225 } | 208 } |
| 226 | 209 |
| 227 | 210 |
| 228 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 211 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 229 Code* code, | 212 Code* code, |
| 230 SharedFunctionInfo* shared, | 213 SharedFunctionInfo* shared, |
| 231 CompilationInfo* info, | 214 CompilationInfo* info, |
| 232 Name* source, int line) { | 215 Name* source, int line) { |
| 233 name_buffer_.Init(tag); | 216 name_buffer_->Init(tag); |
| 234 name_buffer_.AppendBytes(ComputeMarker(code)); | 217 name_buffer_->AppendBytes(ComputeMarker(code)); |
| 235 name_buffer_.AppendString(shared->DebugName()); | 218 name_buffer_->AppendString(shared->DebugName()); |
| 236 name_buffer_.AppendByte(' '); | 219 name_buffer_->AppendByte(' '); |
| 237 if (source->IsString()) { | 220 if (source->IsString()) { |
| 238 name_buffer_.AppendString(String::cast(source)); | 221 name_buffer_->AppendString(String::cast(source)); |
| 239 } else { | 222 } else { |
| 240 name_buffer_.AppendBytes("symbol(hash "); | 223 name_buffer_->AppendBytes("symbol(hash "); |
| 241 name_buffer_.AppendHex(Name::cast(source)->Hash()); | 224 name_buffer_->AppendHex(Name::cast(source)->Hash()); |
| 242 name_buffer_.AppendByte(')'); | 225 name_buffer_->AppendByte(')'); |
| 243 } | 226 } |
| 244 name_buffer_.AppendByte(':'); | 227 name_buffer_->AppendByte(':'); |
| 245 name_buffer_.AppendInt(line); | 228 name_buffer_->AppendInt(line); |
| 246 LogRecordedBuffer(code, shared, &name_buffer_); | 229 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
| 247 } | 230 } |
| 248 | 231 |
| 249 | 232 |
| 250 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 233 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 251 Code* code, | 234 Code* code, |
| 252 int args_count) { | 235 int args_count) { |
| 253 name_buffer_.Init(tag); | 236 name_buffer_->Init(tag); |
| 254 name_buffer_.AppendInt(args_count); | 237 name_buffer_->AppendInt(args_count); |
| 255 LogRecordedBuffer(code, NULL, &name_buffer_); | 238 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 256 } | 239 } |
| 257 | 240 |
| 258 | 241 |
| 259 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { | 242 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 260 name_buffer_.Init(Logger::REG_EXP_TAG); | 243 name_buffer_->Init(Logger::REG_EXP_TAG); |
| 261 name_buffer_.AppendString(source); | 244 name_buffer_->AppendString(source); |
| 262 LogRecordedBuffer(code, NULL, &name_buffer_); | 245 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 263 } | 246 } |
| 264 | 247 |
| 265 | 248 |
| 266 // Low-level logging support. | 249 // Low-level logging support. |
| 250 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 251 |
| 267 class LowLevelLogger : public CodeEventLogger { | 252 class LowLevelLogger : public CodeEventLogger { |
| 268 public: | 253 public: |
| 269 explicit LowLevelLogger(const char* file_name); | 254 explicit LowLevelLogger(const char* file_name); |
| 270 virtual ~LowLevelLogger(); | 255 virtual ~LowLevelLogger(); |
| 271 | 256 |
| 272 void CodeMoveEvent(Address from, Address to); | 257 virtual void CodeMoveEvent(Address from, Address to); |
| 273 void CodeDeleteEvent(Address from); | 258 virtual void CodeDeleteEvent(Address from); |
| 274 void SnapshotPositionEvent(Address addr, int pos); | 259 virtual void SnapshotPositionEvent(Address addr, int pos); |
| 275 void CodeMovingGCEvent(); | 260 virtual void CodeMovingGCEvent(); |
| 276 | 261 |
| 277 private: | 262 private: |
| 278 virtual void LogRecordedBuffer(Code* code, | 263 virtual void LogRecordedBuffer(Code* code, |
| 279 SharedFunctionInfo* shared, | 264 SharedFunctionInfo* shared, |
| 280 NameBuffer* name_buffer); | 265 const char* name, |
| 266 int length); |
| 281 | 267 |
| 282 // Low-level profiling event structures. | 268 // Low-level profiling event structures. |
| 283 struct CodeCreateStruct { | 269 struct CodeCreateStruct { |
| 284 static const char kTag = 'C'; | 270 static const char kTag = 'C'; |
| 285 | 271 |
| 286 int32_t name_size; | 272 int32_t name_size; |
| 287 Address code_address; | 273 Address code_address; |
| 288 int32_t code_size; | 274 int32_t code_size; |
| 289 }; | 275 }; |
| 290 | 276 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 const char arch[] = "mips"; | 354 const char arch[] = "mips"; |
| 369 #else | 355 #else |
| 370 const char arch[] = "unknown"; | 356 const char arch[] = "unknown"; |
| 371 #endif | 357 #endif |
| 372 LogWriteBytes(arch, sizeof(arch)); | 358 LogWriteBytes(arch, sizeof(arch)); |
| 373 } | 359 } |
| 374 | 360 |
| 375 | 361 |
| 376 void LowLevelLogger::LogRecordedBuffer(Code* code, | 362 void LowLevelLogger::LogRecordedBuffer(Code* code, |
| 377 SharedFunctionInfo*, | 363 SharedFunctionInfo*, |
| 378 NameBuffer* name_buffer) { | 364 const char* name, |
| 365 int length) { |
| 379 CodeCreateStruct event; | 366 CodeCreateStruct event; |
| 380 event.name_size = name_buffer->size(); | 367 event.name_size = length; |
| 381 event.code_address = code->instruction_start(); | 368 event.code_address = code->instruction_start(); |
| 382 ASSERT(event.code_address == code->address() + Code::kHeaderSize); | 369 ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
| 383 event.code_size = code->instruction_size(); | 370 event.code_size = code->instruction_size(); |
| 384 LogWriteStruct(event); | 371 LogWriteStruct(event); |
| 385 LogWriteBytes(name_buffer->get(), name_buffer->size()); | 372 LogWriteBytes(name, length); |
| 386 LogWriteBytes( | 373 LogWriteBytes( |
| 387 reinterpret_cast<const char*>(code->instruction_start()), | 374 reinterpret_cast<const char*>(code->instruction_start()), |
| 388 code->instruction_size()); | 375 code->instruction_size()); |
| 389 } | 376 } |
| 390 | 377 |
| 391 | 378 |
| 392 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | 379 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { |
| 393 CodeMoveStruct event; | 380 CodeMoveStruct event; |
| 394 event.from_address = from + Code::kHeaderSize; | 381 event.from_address = from + Code::kHeaderSize; |
| 395 event.to_address = to + Code::kHeaderSize; | 382 event.to_address = to + Code::kHeaderSize; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 419 } | 406 } |
| 420 | 407 |
| 421 | 408 |
| 422 void LowLevelLogger::CodeMovingGCEvent() { | 409 void LowLevelLogger::CodeMovingGCEvent() { |
| 423 const char tag = kCodeMovingGCTag; | 410 const char tag = kCodeMovingGCTag; |
| 424 | 411 |
| 425 LogWriteBytes(&tag, sizeof(tag)); | 412 LogWriteBytes(&tag, sizeof(tag)); |
| 426 } | 413 } |
| 427 | 414 |
| 428 | 415 |
| 429 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 416 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
| 430 | |
| 431 | |
| 432 class CodeAddressMap: public CodeEventLogger { | |
| 433 public: | |
| 434 CodeAddressMap() { } | |
| 435 virtual ~CodeAddressMap() { } | |
| 436 | |
| 437 void CodeMoveEvent(Address from, Address to) { | |
| 438 address_to_name_map_.Move(from, to); | |
| 439 } | |
| 440 | |
| 441 void CodeDeleteEvent(Address from) { | |
| 442 address_to_name_map_.Remove(from); | |
| 443 } | |
| 444 | |
| 445 const char* Lookup(Address address) { | |
| 446 return address_to_name_map_.Lookup(address); | |
| 447 } | |
| 448 | |
| 449 private: | |
| 450 class NameMap { | |
| 451 public: | |
| 452 NameMap() : impl_(&PointerEquals) {} | |
| 453 | |
| 454 ~NameMap() { | |
| 455 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) { | |
| 456 DeleteArray(static_cast<const char*>(p->value)); | |
| 457 } | |
| 458 } | |
| 459 | |
| 460 void Insert(Address code_address, const char* name, int name_size) { | |
| 461 HashMap::Entry* entry = FindOrCreateEntry(code_address); | |
| 462 if (entry->value == NULL) { | |
| 463 entry->value = CopyName(name, name_size); | |
| 464 } | |
| 465 } | |
| 466 | |
| 467 const char* Lookup(Address code_address) { | |
| 468 HashMap::Entry* entry = FindEntry(code_address); | |
| 469 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL; | |
| 470 } | |
| 471 | |
| 472 void Remove(Address code_address) { | |
| 473 HashMap::Entry* entry = FindEntry(code_address); | |
| 474 if (entry != NULL) { | |
| 475 DeleteArray(static_cast<char*>(entry->value)); | |
| 476 RemoveEntry(entry); | |
| 477 } | |
| 478 } | |
| 479 | |
| 480 void Move(Address from, Address to) { | |
| 481 if (from == to) return; | |
| 482 HashMap::Entry* from_entry = FindEntry(from); | |
| 483 ASSERT(from_entry != NULL); | |
| 484 void* value = from_entry->value; | |
| 485 RemoveEntry(from_entry); | |
| 486 HashMap::Entry* to_entry = FindOrCreateEntry(to); | |
| 487 ASSERT(to_entry->value == NULL); | |
| 488 to_entry->value = value; | |
| 489 } | |
| 490 | |
| 491 private: | |
| 492 static bool PointerEquals(void* lhs, void* rhs) { | |
| 493 return lhs == rhs; | |
| 494 } | |
| 495 | |
| 496 static char* CopyName(const char* name, int name_size) { | |
| 497 char* result = NewArray<char>(name_size + 1); | |
| 498 for (int i = 0; i < name_size; ++i) { | |
| 499 char c = name[i]; | |
| 500 if (c == '\0') c = ' '; | |
| 501 result[i] = c; | |
| 502 } | |
| 503 result[name_size] = '\0'; | |
| 504 return result; | |
| 505 } | |
| 506 | |
| 507 HashMap::Entry* FindOrCreateEntry(Address code_address) { | |
| 508 return impl_.Lookup(code_address, ComputePointerHash(code_address), true); | |
| 509 } | |
| 510 | |
| 511 HashMap::Entry* FindEntry(Address code_address) { | |
| 512 return impl_.Lookup(code_address, | |
| 513 ComputePointerHash(code_address), | |
| 514 false); | |
| 515 } | |
| 516 | |
| 517 void RemoveEntry(HashMap::Entry* entry) { | |
| 518 impl_.Remove(entry->key, entry->hash); | |
| 519 } | |
| 520 | |
| 521 HashMap impl_; | |
| 522 | |
| 523 DISALLOW_COPY_AND_ASSIGN(NameMap); | |
| 524 }; | |
| 525 | |
| 526 virtual void LogRecordedBuffer(Code* code, | |
| 527 SharedFunctionInfo*, | |
| 528 NameBuffer* name_buffer) { | |
| 529 address_to_name_map_.Insert(code->address(), | |
| 530 name_buffer->get(), | |
| 531 name_buffer->size()); | |
| 532 } | |
| 533 | |
| 534 NameMap address_to_name_map_; | |
| 535 }; | |
| 536 | |
| 537 | |
| 538 #define CODE_ADDRESS_MAP_LOG(Call)\ | |
| 539 if (Serializer::enabled()) code_address_map_->Call; | |
| 540 | 417 |
| 541 | 418 |
| 542 class JitLogger : public CodeEventLogger { | 419 class JitLogger : public CodeEventLogger { |
| 543 public: | 420 public: |
| 544 explicit JitLogger(JitCodeEventHandler code_event_handler); | 421 explicit JitLogger(JitCodeEventHandler code_event_handler); |
| 545 | 422 |
| 546 void CodeMovedEvent(Address from, Address to); | 423 virtual void CodeMoveEvent(Address from, Address to); |
| 547 void CodeDeleteEvent(Address from); | 424 virtual void CodeDeleteEvent(Address from); |
| 548 void AddCodeLinePosInfoEvent( | 425 virtual void AddCodeLinePosInfoEvent( |
| 549 void* jit_handler_data, | 426 void* jit_handler_data, |
| 550 int pc_offset, | 427 int pc_offset, |
| 551 int position, | 428 int position, |
| 552 JitCodeEvent::PositionType position_type); | 429 JitCodeEvent::PositionType position_type); |
| 430 |
| 553 void* StartCodePosInfoEvent(); | 431 void* StartCodePosInfoEvent(); |
| 554 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); | 432 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); |
| 555 | 433 |
| 556 private: | 434 private: |
| 557 virtual void LogRecordedBuffer(Code* code, | 435 virtual void LogRecordedBuffer(Code* code, |
| 558 SharedFunctionInfo* shared, | 436 SharedFunctionInfo* shared, |
| 559 CodeEventLogger::NameBuffer* name_buffer); | 437 const char* name, |
| 438 int length); |
| 560 | 439 |
| 561 JitCodeEventHandler code_event_handler_; | 440 JitCodeEventHandler code_event_handler_; |
| 562 }; | 441 }; |
| 563 | 442 |
| 564 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; | |
| 565 | |
| 566 | 443 |
| 567 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) | 444 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
| 568 : code_event_handler_(code_event_handler) { | 445 : code_event_handler_(code_event_handler) { |
| 569 } | 446 } |
| 570 | 447 |
| 571 | 448 |
| 572 void JitLogger::LogRecordedBuffer(Code* code, | 449 void JitLogger::LogRecordedBuffer(Code* code, |
| 573 SharedFunctionInfo* shared, | 450 SharedFunctionInfo* shared, |
| 574 CodeEventLogger::NameBuffer* name_buffer) { | 451 const char* name, |
| 452 int length) { |
| 575 JitCodeEvent event; | 453 JitCodeEvent event; |
| 576 memset(&event, 0, sizeof(event)); | 454 memset(&event, 0, sizeof(event)); |
| 577 event.type = JitCodeEvent::CODE_ADDED; | 455 event.type = JitCodeEvent::CODE_ADDED; |
| 578 event.code_start = code->instruction_start(); | 456 event.code_start = code->instruction_start(); |
| 579 event.code_len = code->instruction_size(); | 457 event.code_len = code->instruction_size(); |
| 580 Handle<Script> script_handle; | 458 Handle<Script> script_handle; |
| 581 if (shared && shared->script()->IsScript()) { | 459 if (shared && shared->script()->IsScript()) { |
| 582 script_handle = Handle<Script>(Script::cast(shared->script())); | 460 script_handle = Handle<Script>(Script::cast(shared->script())); |
| 583 } | 461 } |
| 584 event.script = ToApiHandle<v8::Script>(script_handle); | 462 event.script = ToApiHandle<v8::Script>(script_handle); |
| 585 event.name.str = name_buffer->get(); | 463 event.name.str = name; |
| 586 event.name.len = name_buffer->size(); | 464 event.name.len = length; |
| 587 code_event_handler_(&event); | 465 code_event_handler_(&event); |
| 588 } | 466 } |
| 589 | 467 |
| 590 | 468 |
| 591 void JitLogger::CodeMovedEvent(Address from, Address to) { | 469 void JitLogger::CodeMoveEvent(Address from, Address to) { |
| 592 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | 470 Code* from_code = Code::cast(HeapObject::FromAddress(from)); |
| 593 | 471 |
| 594 JitCodeEvent event; | 472 JitCodeEvent event; |
| 595 event.type = JitCodeEvent::CODE_MOVED; | 473 event.type = JitCodeEvent::CODE_MOVED; |
| 596 event.code_start = from_code->instruction_start(); | 474 event.code_start = from_code->instruction_start(); |
| 597 event.code_len = from_code->instruction_size(); | 475 event.code_len = from_code->instruction_size(); |
| 598 | 476 |
| 599 // Calculate the header size. | 477 // Calculate the header size. |
| 600 const size_t header_size = | 478 const size_t header_size = |
| 601 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | 479 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 Logger::Logger(Isolate* isolate) | 707 Logger::Logger(Isolate* isolate) |
| 830 : isolate_(isolate), | 708 : isolate_(isolate), |
| 831 ticker_(NULL), | 709 ticker_(NULL), |
| 832 profiler_(NULL), | 710 profiler_(NULL), |
| 833 log_events_(NULL), | 711 log_events_(NULL), |
| 834 logging_nesting_(0), | 712 logging_nesting_(0), |
| 835 cpu_profiler_nesting_(0), | 713 cpu_profiler_nesting_(0), |
| 836 log_(new Log(this)), | 714 log_(new Log(this)), |
| 837 ll_logger_(NULL), | 715 ll_logger_(NULL), |
| 838 jit_logger_(NULL), | 716 jit_logger_(NULL), |
| 839 code_address_map_(new CodeAddressMap), | 717 listeners_(5), |
| 840 is_initialized_(false), | 718 is_initialized_(false), |
| 841 last_address_(NULL), | 719 last_address_(NULL), |
| 842 prev_sp_(NULL), | 720 prev_sp_(NULL), |
| 843 prev_function_(NULL), | 721 prev_function_(NULL), |
| 844 prev_to_(NULL), | 722 prev_to_(NULL), |
| 845 prev_code_(NULL), | 723 prev_code_(NULL), |
| 846 epoch_(0) { | 724 epoch_(0) { |
| 847 } | 725 } |
| 848 | 726 |
| 849 | 727 |
| 850 Logger::~Logger() { | 728 Logger::~Logger() { |
| 851 delete code_address_map_; | |
| 852 delete log_; | 729 delete log_; |
| 853 } | 730 } |
| 854 | 731 |
| 855 | 732 |
| 733 void Logger::addCodeEventListener(CodeEventListener* listener) { |
| 734 ASSERT(!hasCodeEventListener(listener)); |
| 735 listeners_.Add(listener); |
| 736 } |
| 737 |
| 738 |
| 739 void Logger::removeCodeEventListener(CodeEventListener* listener) { |
| 740 ASSERT(hasCodeEventListener(listener)); |
| 741 listeners_.RemoveElement(listener); |
| 742 } |
| 743 |
| 744 |
| 745 bool Logger::hasCodeEventListener(CodeEventListener* listener) { |
| 746 return listeners_.Contains(listener); |
| 747 } |
| 748 |
| 749 |
| 856 void Logger::ProfilerBeginEvent() { | 750 void Logger::ProfilerBeginEvent() { |
| 857 if (!log_->IsEnabled()) return; | 751 if (!log_->IsEnabled()) return; |
| 858 Log::MessageBuilder msg(log_); | 752 Log::MessageBuilder msg(log_); |
| 859 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); | 753 msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs); |
| 860 msg.WriteToLogFile(); | 754 msg.WriteToLogFile(); |
| 861 } | 755 } |
| 862 | 756 |
| 863 | 757 |
| 864 void Logger::StringEvent(const char* name, const char* value) { | 758 void Logger::StringEvent(const char* name, const char* value) { |
| 865 if (FLAG_log) UncheckedStringEvent(name, value); | 759 if (FLAG_log) UncheckedStringEvent(name, value); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 } | 1096 } |
| 1203 | 1097 |
| 1204 | 1098 |
| 1205 void Logger::DeleteEventStatic(const char* name, void* object) { | 1099 void Logger::DeleteEventStatic(const char* name, void* object) { |
| 1206 Isolate::Current()->logger()->DeleteEvent(name, object); | 1100 Isolate::Current()->logger()->DeleteEvent(name, object); |
| 1207 } | 1101 } |
| 1208 | 1102 |
| 1209 | 1103 |
| 1210 void Logger::CallbackEventInternal(const char* prefix, Name* name, | 1104 void Logger::CallbackEventInternal(const char* prefix, Name* name, |
| 1211 Address entry_point) { | 1105 Address entry_point) { |
| 1212 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1106 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1213 Log::MessageBuilder msg(log_); | 1107 Log::MessageBuilder msg(log_); |
| 1214 msg.Append("%s,%s,-2,", | 1108 msg.Append("%s,%s,-2,", |
| 1215 kLogEventsNames[CODE_CREATION_EVENT], | 1109 kLogEventsNames[CODE_CREATION_EVENT], |
| 1216 kLogEventsNames[CALLBACK_TAG]); | 1110 kLogEventsNames[CALLBACK_TAG]); |
| 1217 msg.AppendAddress(entry_point); | 1111 msg.AppendAddress(entry_point); |
| 1218 if (name->IsString()) { | 1112 if (name->IsString()) { |
| 1219 SmartArrayPointer<char> str = | 1113 SmartArrayPointer<char> str = |
| 1220 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1114 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1221 msg.Append(",1,\"%s%s\"", prefix, *str); | 1115 msg.Append(",1,\"%s%s\"", prefix, *str); |
| 1222 } else { | 1116 } else { |
| 1223 Symbol* symbol = Symbol::cast(name); | 1117 Symbol* symbol = Symbol::cast(name); |
| 1224 if (symbol->name()->IsUndefined()) { | 1118 if (symbol->name()->IsUndefined()) { |
| 1225 msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash()); | 1119 msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash()); |
| 1226 } else { | 1120 } else { |
| 1227 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString( | 1121 SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString( |
| 1228 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1122 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1229 msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash()); | 1123 msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash()); |
| 1230 } | 1124 } |
| 1231 } | 1125 } |
| 1232 msg.Append('\n'); | 1126 msg.Append('\n'); |
| 1233 msg.WriteToLogFile(); | 1127 msg.WriteToLogFile(); |
| 1234 } | 1128 } |
| 1235 | 1129 |
| 1236 | 1130 |
| 1237 void Logger::CallbackEvent(Name* name, Address entry_point) { | 1131 void Logger::CallbackEvent(Name* name, Address entry_point) { |
| 1238 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1132 PROFILER_LOG(CallbackEvent(name, entry_point)); |
| 1239 CallbackEventInternal("", name, entry_point); | 1133 CallbackEventInternal("", name, entry_point); |
| 1240 } | 1134 } |
| 1241 | 1135 |
| 1242 | 1136 |
| 1243 void Logger::GetterCallbackEvent(Name* name, Address entry_point) { | 1137 void Logger::GetterCallbackEvent(Name* name, Address entry_point) { |
| 1244 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1138 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); |
| 1245 CallbackEventInternal("get ", name, entry_point); | 1139 CallbackEventInternal("get ", name, entry_point); |
| 1246 } | 1140 } |
| 1247 | 1141 |
| 1248 | 1142 |
| 1249 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1143 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
| 1250 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1144 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); |
| 1251 CallbackEventInternal("set ", name, entry_point); | 1145 CallbackEventInternal("set ", name, entry_point); |
| 1252 } | 1146 } |
| 1253 | 1147 |
| 1254 | 1148 |
| 1255 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, | 1149 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
| 1256 Logger::LogEventsAndTags tag, | 1150 Logger::LogEventsAndTags tag, |
| 1257 Code* code) { | 1151 Code* code) { |
| 1258 ASSERT(msg); | 1152 ASSERT(msg); |
| 1259 msg->Append("%s,%s,%d,", | 1153 msg->Append("%s,%s,%d,", |
| 1260 kLogEventsNames[Logger::CODE_CREATION_EVENT], | 1154 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
| 1261 kLogEventsNames[tag], | 1155 kLogEventsNames[tag], |
| 1262 code->kind()); | 1156 code->kind()); |
| 1263 msg->AppendAddress(code->address()); | 1157 msg->AppendAddress(code->address()); |
| 1264 msg->Append(",%d,", code->ExecutableSize()); | 1158 msg->Append(",%d,", code->ExecutableSize()); |
| 1265 } | 1159 } |
| 1266 | 1160 |
| 1267 | 1161 |
| 1268 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1162 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1269 Code* code, | 1163 Code* code, |
| 1270 const char* comment) { | 1164 const char* comment) { |
| 1165 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); |
| 1166 |
| 1271 if (!is_logging_code_events()) return; | 1167 if (!is_logging_code_events()) return; |
| 1272 | 1168 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); |
| 1273 JIT_LOG(CodeCreateEvent(tag, code, comment)); | |
| 1274 LL_LOG(CodeCreateEvent(tag, code, comment)); | |
| 1275 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, comment)); | |
| 1276 | 1169 |
| 1277 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1170 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1278 Log::MessageBuilder msg(log_); | 1171 Log::MessageBuilder msg(log_); |
| 1279 AppendCodeCreateHeader(&msg, tag, code); | 1172 AppendCodeCreateHeader(&msg, tag, code); |
| 1280 msg.AppendDoubleQuotedString(comment); | 1173 msg.AppendDoubleQuotedString(comment); |
| 1281 msg.Append('\n'); | 1174 msg.Append('\n'); |
| 1282 msg.WriteToLogFile(); | 1175 msg.WriteToLogFile(); |
| 1283 } | 1176 } |
| 1284 | 1177 |
| 1285 | 1178 |
| 1286 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1179 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1287 Code* code, | 1180 Code* code, |
| 1288 Name* name) { | 1181 Name* name) { |
| 1182 PROFILER_LOG(CodeCreateEvent(tag, code, name)); |
| 1183 |
| 1289 if (!is_logging_code_events()) return; | 1184 if (!is_logging_code_events()) return; |
| 1290 | 1185 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); |
| 1291 JIT_LOG(CodeCreateEvent(tag, code, name)); | |
| 1292 LL_LOG(CodeCreateEvent(tag, code, name)); | |
| 1293 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, name)); | |
| 1294 | 1186 |
| 1295 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1187 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1296 Log::MessageBuilder msg(log_); | 1188 Log::MessageBuilder msg(log_); |
| 1297 AppendCodeCreateHeader(&msg, tag, code); | 1189 AppendCodeCreateHeader(&msg, tag, code); |
| 1298 if (name->IsString()) { | 1190 if (name->IsString()) { |
| 1299 msg.Append('"'); | 1191 msg.Append('"'); |
| 1300 msg.AppendDetailed(String::cast(name), false); | 1192 msg.AppendDetailed(String::cast(name), false); |
| 1301 msg.Append('"'); | 1193 msg.Append('"'); |
| 1302 } else { | 1194 } else { |
| 1303 msg.AppendSymbolName(Symbol::cast(name)); | 1195 msg.AppendSymbolName(Symbol::cast(name)); |
| 1304 } | 1196 } |
| 1305 msg.Append('\n'); | 1197 msg.Append('\n'); |
| 1306 msg.WriteToLogFile(); | 1198 msg.WriteToLogFile(); |
| 1307 } | 1199 } |
| 1308 | 1200 |
| 1309 | 1201 |
| 1310 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1202 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1311 Code* code, | 1203 Code* code, |
| 1312 SharedFunctionInfo* shared, | 1204 SharedFunctionInfo* shared, |
| 1313 CompilationInfo* info, | 1205 CompilationInfo* info, |
| 1314 Name* name) { | 1206 Name* name) { |
| 1207 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1208 |
| 1315 if (!is_logging_code_events()) return; | 1209 if (!is_logging_code_events()) return; |
| 1316 | 1210 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); |
| 1317 JIT_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
| 1318 LL_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
| 1319 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, name)); | |
| 1320 | 1211 |
| 1321 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1212 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1322 if (code == isolate_->builtins()->builtin( | 1213 if (code == isolate_->builtins()->builtin( |
| 1323 Builtins::kLazyCompile)) | 1214 Builtins::kLazyCompile)) |
| 1324 return; | 1215 return; |
| 1325 | 1216 |
| 1326 Log::MessageBuilder msg(log_); | 1217 Log::MessageBuilder msg(log_); |
| 1327 AppendCodeCreateHeader(&msg, tag, code); | 1218 AppendCodeCreateHeader(&msg, tag, code); |
| 1328 if (name->IsString()) { | 1219 if (name->IsString()) { |
| 1329 SmartArrayPointer<char> str = | 1220 SmartArrayPointer<char> str = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1341 | 1232 |
| 1342 | 1233 |
| 1343 // Although, it is possible to extract source and line from | 1234 // Although, it is possible to extract source and line from |
| 1344 // the SharedFunctionInfo object, we left it to caller | 1235 // the SharedFunctionInfo object, we left it to caller |
| 1345 // to leave logging functions free from heap allocations. | 1236 // to leave logging functions free from heap allocations. |
| 1346 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1237 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1347 Code* code, | 1238 Code* code, |
| 1348 SharedFunctionInfo* shared, | 1239 SharedFunctionInfo* shared, |
| 1349 CompilationInfo* info, | 1240 CompilationInfo* info, |
| 1350 Name* source, int line) { | 1241 Name* source, int line) { |
| 1242 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1243 |
| 1351 if (!is_logging_code_events()) return; | 1244 if (!is_logging_code_events()) return; |
| 1352 | 1245 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line)); |
| 1353 JIT_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
| 1354 LL_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
| 1355 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); | |
| 1356 | 1246 |
| 1357 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1247 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1358 Log::MessageBuilder msg(log_); | 1248 Log::MessageBuilder msg(log_); |
| 1359 AppendCodeCreateHeader(&msg, tag, code); | 1249 AppendCodeCreateHeader(&msg, tag, code); |
| 1360 SmartArrayPointer<char> name = | 1250 SmartArrayPointer<char> name = |
| 1361 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1251 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1362 msg.Append("\"%s ", *name); | 1252 msg.Append("\"%s ", *name); |
| 1363 if (source->IsString()) { | 1253 if (source->IsString()) { |
| 1364 SmartArrayPointer<char> sourcestr = | 1254 SmartArrayPointer<char> sourcestr = |
| 1365 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1255 String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1366 msg.Append("%s", *sourcestr); | 1256 msg.Append("%s", *sourcestr); |
| 1367 } else { | 1257 } else { |
| 1368 msg.AppendSymbolName(Symbol::cast(source)); | 1258 msg.AppendSymbolName(Symbol::cast(source)); |
| 1369 } | 1259 } |
| 1370 msg.Append(":%d\",", line); | 1260 msg.Append(":%d\",", line); |
| 1371 msg.AppendAddress(shared->address()); | 1261 msg.AppendAddress(shared->address()); |
| 1372 msg.Append(",%s", ComputeMarker(code)); | 1262 msg.Append(",%s", ComputeMarker(code)); |
| 1373 msg.Append('\n'); | 1263 msg.Append('\n'); |
| 1374 msg.WriteToLogFile(); | 1264 msg.WriteToLogFile(); |
| 1375 } | 1265 } |
| 1376 | 1266 |
| 1377 | 1267 |
| 1378 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1268 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| 1379 Code* code, | 1269 Code* code, |
| 1380 int args_count) { | 1270 int args_count) { |
| 1271 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1272 |
| 1381 if (!is_logging_code_events()) return; | 1273 if (!is_logging_code_events()) return; |
| 1382 | 1274 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); |
| 1383 JIT_LOG(CodeCreateEvent(tag, code, args_count)); | |
| 1384 LL_LOG(CodeCreateEvent(tag, code, args_count)); | |
| 1385 CODE_ADDRESS_MAP_LOG(CodeCreateEvent(tag, code, args_count)); | |
| 1386 | 1275 |
| 1387 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1276 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1388 Log::MessageBuilder msg(log_); | 1277 Log::MessageBuilder msg(log_); |
| 1389 AppendCodeCreateHeader(&msg, tag, code); | 1278 AppendCodeCreateHeader(&msg, tag, code); |
| 1390 msg.Append("\"args_count: %d\"", args_count); | 1279 msg.Append("\"args_count: %d\"", args_count); |
| 1391 msg.Append('\n'); | 1280 msg.Append('\n'); |
| 1392 msg.WriteToLogFile(); | 1281 msg.WriteToLogFile(); |
| 1393 } | 1282 } |
| 1394 | 1283 |
| 1395 | 1284 |
| 1396 void Logger::CodeMovingGCEvent() { | 1285 void Logger::CodeMovingGCEvent() { |
| 1286 PROFILER_LOG(CodeMovingGCEvent()); |
| 1287 |
| 1288 if (!is_logging_code_events()) return; |
| 1397 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1289 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1398 LL_LOG(CodeMovingGCEvent()); | 1290 CALL_LISTENERS(CodeMovingGCEvent()); |
| 1399 OS::SignalCodeMovingGC(); | 1291 OS::SignalCodeMovingGC(); |
| 1400 } | 1292 } |
| 1401 | 1293 |
| 1402 | 1294 |
| 1403 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | 1295 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| 1296 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); |
| 1297 |
| 1404 if (!is_logging_code_events()) return; | 1298 if (!is_logging_code_events()) return; |
| 1405 | 1299 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); |
| 1406 JIT_LOG(RegExpCodeCreateEvent(code, source)); | |
| 1407 LL_LOG(RegExpCodeCreateEvent(code, source)); | |
| 1408 CODE_ADDRESS_MAP_LOG(RegExpCodeCreateEvent(code, source)); | |
| 1409 | 1300 |
| 1410 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1301 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1411 Log::MessageBuilder msg(log_); | 1302 Log::MessageBuilder msg(log_); |
| 1412 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1303 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1413 msg.Append('"'); | 1304 msg.Append('"'); |
| 1414 msg.AppendDetailed(source, false); | 1305 msg.AppendDetailed(source, false); |
| 1415 msg.Append('"'); | 1306 msg.Append('"'); |
| 1416 msg.Append('\n'); | 1307 msg.Append('\n'); |
| 1417 msg.WriteToLogFile(); | 1308 msg.WriteToLogFile(); |
| 1418 } | 1309 } |
| 1419 | 1310 |
| 1420 | 1311 |
| 1421 void Logger::CodeMoveEvent(Address from, Address to) { | 1312 void Logger::CodeMoveEvent(Address from, Address to) { |
| 1422 JIT_LOG(CodeMovedEvent(from, to)); | 1313 PROFILER_LOG(CodeMoveEvent(from, to)); |
| 1423 if (!log_->IsEnabled()) return; | 1314 |
| 1424 LL_LOG(CodeMoveEvent(from, to)); | 1315 if (!is_logging_code_events()) return; |
| 1425 CODE_ADDRESS_MAP_LOG(CodeMoveEvent(from, to)); | 1316 CALL_LISTENERS(CodeMoveEvent(from, to)); |
| 1426 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1317 MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| 1427 } | 1318 } |
| 1428 | 1319 |
| 1429 | 1320 |
| 1430 void Logger::CodeDeleteEvent(Address from) { | 1321 void Logger::CodeDeleteEvent(Address from) { |
| 1431 JIT_LOG(CodeDeleteEvent(from)); | 1322 PROFILER_LOG(CodeDeleteEvent(from)); |
| 1432 if (!log_->IsEnabled()) return; | |
| 1433 LL_LOG(CodeDeleteEvent(from)); | |
| 1434 CODE_ADDRESS_MAP_LOG(CodeDeleteEvent(from)); | |
| 1435 | 1323 |
| 1436 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1324 if (!is_logging_code_events()) return; |
| 1325 CALL_LISTENERS(CodeDeleteEvent(from)); |
| 1326 |
| 1327 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1437 Log::MessageBuilder msg(log_); | 1328 Log::MessageBuilder msg(log_); |
| 1438 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); | 1329 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); |
| 1439 msg.AppendAddress(from); | 1330 msg.AppendAddress(from); |
| 1440 msg.Append('\n'); | 1331 msg.Append('\n'); |
| 1441 msg.WriteToLogFile(); | 1332 msg.WriteToLogFile(); |
| 1442 } | 1333 } |
| 1443 | 1334 |
| 1444 | 1335 |
| 1445 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1336 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1446 int pc_offset, | 1337 int pc_offset, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1468 } | 1359 } |
| 1469 } | 1360 } |
| 1470 | 1361 |
| 1471 | 1362 |
| 1472 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | 1363 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, |
| 1473 void* jit_handler_data) { | 1364 void* jit_handler_data) { |
| 1474 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); | 1365 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
| 1475 } | 1366 } |
| 1476 | 1367 |
| 1477 | 1368 |
| 1369 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { |
| 1370 if (code_name == NULL) return; // Not a code object. |
| 1371 Log::MessageBuilder msg(log_); |
| 1372 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1373 msg.AppendDoubleQuotedString(code_name); |
| 1374 msg.Append("\n"); |
| 1375 msg.WriteToLogFile(); |
| 1376 } |
| 1377 |
| 1378 |
| 1478 void Logger::SnapshotPositionEvent(Address addr, int pos) { | 1379 void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| 1479 if (!log_->IsEnabled()) return; | 1380 if (!log_->IsEnabled()) return; |
| 1480 LL_LOG(SnapshotPositionEvent(addr, pos)); | 1381 LL_LOG(SnapshotPositionEvent(addr, pos)); |
| 1481 if (Serializer::enabled()) { | |
| 1482 const char* code_name = code_address_map_->Lookup(addr); | |
| 1483 if (code_name == NULL) return; // Not a code object. | |
| 1484 Log::MessageBuilder msg(log_); | |
| 1485 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | |
| 1486 msg.AppendDoubleQuotedString(code_name); | |
| 1487 msg.Append("\n"); | |
| 1488 msg.WriteToLogFile(); | |
| 1489 } | |
| 1490 if (!FLAG_log_snapshot_positions) return; | 1382 if (!FLAG_log_snapshot_positions) return; |
| 1491 Log::MessageBuilder msg(log_); | 1383 Log::MessageBuilder msg(log_); |
| 1492 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); | 1384 msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| 1493 msg.AppendAddress(addr); | 1385 msg.AppendAddress(addr); |
| 1494 msg.Append(",%d", pos); | 1386 msg.Append(",%d", pos); |
| 1495 msg.Append('\n'); | 1387 msg.Append('\n'); |
| 1496 msg.WriteToLogFile(); | 1388 msg.WriteToLogFile(); |
| 1497 } | 1389 } |
| 1498 | 1390 |
| 1499 | 1391 |
| 1500 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { | 1392 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { |
| 1393 PROFILER_LOG(SharedFunctionInfoMoveEvent(from, to)); |
| 1394 |
| 1395 if (!is_logging_code_events()) return; |
| 1501 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); | 1396 MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to); |
| 1502 } | 1397 } |
| 1503 | 1398 |
| 1504 | 1399 |
| 1505 void Logger::MoveEventInternal(LogEventsAndTags event, | 1400 void Logger::MoveEventInternal(LogEventsAndTags event, |
| 1506 Address from, | 1401 Address from, |
| 1507 Address to) { | 1402 Address to) { |
| 1508 if (!log_->IsEnabled() || !FLAG_log_code) return; | 1403 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1509 Log::MessageBuilder msg(log_); | 1404 Log::MessageBuilder msg(log_); |
| 1510 msg.Append("%s,", kLogEventsNames[event]); | 1405 msg.Append("%s,", kLogEventsNames[event]); |
| 1511 msg.AppendAddress(from); | 1406 msg.AppendAddress(from); |
| 1512 msg.Append(','); | 1407 msg.Append(','); |
| 1513 msg.AppendAddress(to); | 1408 msg.AppendAddress(to); |
| 1514 msg.Append('\n'); | 1409 msg.Append('\n'); |
| 1515 msg.WriteToLogFile(); | 1410 msg.WriteToLogFile(); |
| 1516 } | 1411 } |
| 1517 | 1412 |
| 1518 | 1413 |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 bool Logger::SetUp(Isolate* isolate) { | 1862 bool Logger::SetUp(Isolate* isolate) { |
| 1968 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. | 1863 // Tests and EnsureInitialize() can call this twice in a row. It's harmless. |
| 1969 if (is_initialized_) return true; | 1864 if (is_initialized_) return true; |
| 1970 is_initialized_ = true; | 1865 is_initialized_ = true; |
| 1971 | 1866 |
| 1972 // --ll-prof implies --log-code and --log-snapshot-positions. | 1867 // --ll-prof implies --log-code and --log-snapshot-positions. |
| 1973 if (FLAG_ll_prof) { | 1868 if (FLAG_ll_prof) { |
| 1974 FLAG_log_snapshot_positions = true; | 1869 FLAG_log_snapshot_positions = true; |
| 1975 } | 1870 } |
| 1976 | 1871 |
| 1977 // --prof_lazy controls --log-code, implies --noprof_auto. | 1872 // --prof_lazy controls --log-code. |
| 1978 if (FLAG_prof_lazy) { | 1873 if (FLAG_prof_lazy) { |
| 1979 FLAG_log_code = false; | 1874 FLAG_log_code = false; |
| 1980 FLAG_prof_auto = false; | |
| 1981 } | 1875 } |
| 1982 | 1876 |
| 1983 SmartArrayPointer<const char> log_file_name = | 1877 SmartArrayPointer<const char> log_file_name = |
| 1984 PrepareLogFileName(FLAG_logfile); | 1878 PrepareLogFileName(FLAG_logfile); |
| 1985 log_->Initialize(*log_file_name); | 1879 log_->Initialize(*log_file_name); |
| 1986 | 1880 |
| 1987 if (FLAG_ll_prof) { | 1881 if (FLAG_ll_prof) { |
| 1988 ll_logger_ = new LowLevelLogger(*log_file_name); | 1882 ll_logger_ = new LowLevelLogger(*log_file_name); |
| 1883 addCodeEventListener(ll_logger_); |
| 1989 } | 1884 } |
| 1990 | 1885 |
| 1991 ticker_ = new Ticker(isolate, kSamplingIntervalMs); | 1886 ticker_ = new Ticker(isolate, kSamplingIntervalMs); |
| 1992 | 1887 |
| 1993 if (Log::InitLogAtStart()) { | 1888 if (Log::InitLogAtStart()) { |
| 1994 logging_nesting_ = 1; | 1889 logging_nesting_ = 1; |
| 1995 } | 1890 } |
| 1996 | 1891 |
| 1997 if (FLAG_prof) { | 1892 if (FLAG_prof) { |
| 1998 profiler_ = new Profiler(isolate); | 1893 profiler_ = new Profiler(isolate); |
| 1999 if (!FLAG_prof_auto) { | 1894 if (FLAG_prof_lazy) { |
| 2000 profiler_->pause(); | 1895 profiler_->pause(); |
| 2001 } else { | 1896 } else { |
| 2002 logging_nesting_ = 1; | 1897 logging_nesting_ = 1; |
| 2003 } | |
| 2004 if (!FLAG_prof_lazy) { | |
| 2005 profiler_->Engage(); | 1898 profiler_->Engage(); |
| 2006 } | 1899 } |
| 2007 } | 1900 } |
| 2008 | 1901 |
| 2009 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); | 1902 if (FLAG_log_internal_timer_events || FLAG_prof) epoch_ = OS::Ticks(); |
| 2010 | 1903 |
| 2011 return true; | 1904 return true; |
| 2012 } | 1905 } |
| 2013 | 1906 |
| 2014 | 1907 |
| 2015 void Logger::SetCodeEventHandler(uint32_t options, | 1908 void Logger::SetCodeEventHandler(uint32_t options, |
| 2016 JitCodeEventHandler event_handler) { | 1909 JitCodeEventHandler event_handler) { |
| 2017 if (jit_logger_) { | 1910 if (jit_logger_) { |
| 1911 removeCodeEventListener(jit_logger_); |
| 2018 delete jit_logger_; | 1912 delete jit_logger_; |
| 2019 jit_logger_ = NULL; | 1913 jit_logger_ = NULL; |
| 2020 } | 1914 } |
| 2021 | 1915 |
| 2022 if (event_handler) { | 1916 if (event_handler) { |
| 2023 jit_logger_ = new JitLogger(event_handler); | 1917 jit_logger_ = new JitLogger(event_handler); |
| 2024 } | 1918 addCodeEventListener(jit_logger_); |
| 2025 | 1919 if (options & kJitCodeEventEnumExisting) { |
| 2026 if (jit_logger_ != NULL && (options & kJitCodeEventEnumExisting)) { | 1920 HandleScope scope(isolate_); |
| 2027 HandleScope scope(isolate_); | 1921 LogCodeObjects(); |
| 2028 LogCodeObjects(); | 1922 LogCompiledFunctions(); |
| 2029 LogCompiledFunctions(); | 1923 } |
| 2030 } | 1924 } |
| 2031 } | 1925 } |
| 2032 | 1926 |
| 2033 | 1927 |
| 2034 Sampler* Logger::sampler() { | 1928 Sampler* Logger::sampler() { |
| 2035 return ticker_; | 1929 return ticker_; |
| 2036 } | 1930 } |
| 2037 | 1931 |
| 2038 | 1932 |
| 2039 FILE* Logger::TearDown() { | 1933 FILE* Logger::TearDown() { |
| 2040 if (!is_initialized_) return NULL; | 1934 if (!is_initialized_) return NULL; |
| 2041 is_initialized_ = false; | 1935 is_initialized_ = false; |
| 2042 | 1936 |
| 2043 // Stop the profiler before closing the file. | 1937 // Stop the profiler before closing the file. |
| 2044 if (profiler_ != NULL) { | 1938 if (profiler_ != NULL) { |
| 2045 profiler_->Disengage(); | 1939 profiler_->Disengage(); |
| 2046 delete profiler_; | 1940 delete profiler_; |
| 2047 profiler_ = NULL; | 1941 profiler_ = NULL; |
| 2048 } | 1942 } |
| 2049 | 1943 |
| 2050 delete ticker_; | 1944 delete ticker_; |
| 2051 ticker_ = NULL; | 1945 ticker_ = NULL; |
| 2052 | 1946 |
| 2053 if (ll_logger_) { | 1947 if (ll_logger_) { |
| 1948 removeCodeEventListener(ll_logger_); |
| 2054 delete ll_logger_; | 1949 delete ll_logger_; |
| 2055 ll_logger_ = NULL; | 1950 ll_logger_ = NULL; |
| 2056 } | 1951 } |
| 2057 | 1952 |
| 2058 if (jit_logger_) { | 1953 if (jit_logger_) { |
| 1954 removeCodeEventListener(jit_logger_); |
| 2059 delete jit_logger_; | 1955 delete jit_logger_; |
| 2060 jit_logger_ = NULL; | 1956 jit_logger_ = NULL; |
| 2061 } | 1957 } |
| 2062 | 1958 |
| 2063 return log_->Close(); | 1959 return log_->Close(); |
| 2064 } | 1960 } |
| 2065 | 1961 |
| 2066 } } // namespace v8::internal | 1962 } } // namespace v8::internal |
| OLD | NEW |