| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/log.h" | 5 #include "src/log.h" |
| 6 | 6 |
| 7 #include <cstdarg> | 7 #include <cstdarg> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 | 39 |
| 40 #define PROFILER_LOG(Call) \ | 40 #define PROFILER_LOG(Call) \ |
| 41 do { \ | 41 do { \ |
| 42 CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \ | 42 CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \ |
| 43 if (cpu_profiler->is_profiling()) { \ | 43 if (cpu_profiler->is_profiling()) { \ |
| 44 cpu_profiler->Call; \ | 44 cpu_profiler->Call; \ |
| 45 } \ | 45 } \ |
| 46 } while (false); | 46 } while (false); |
| 47 | 47 |
| 48 static const char* ComputeMarker(SharedFunctionInfo* shared, Code* code) { | 48 static const char* ComputeMarker(SharedFunctionInfo* shared, |
| 49 AbstractCode* code) { |
| 49 switch (code->kind()) { | 50 switch (code->kind()) { |
| 50 case Code::FUNCTION: | 51 case AbstractCode::FUNCTION: |
| 52 case AbstractCode::INTERPRETED_FUNCTION: |
| 51 return shared->optimization_disabled() ? "" : "~"; | 53 return shared->optimization_disabled() ? "" : "~"; |
| 52 case Code::OPTIMIZED_FUNCTION: | 54 case AbstractCode::OPTIMIZED_FUNCTION: |
| 53 return "*"; | 55 return "*"; |
| 54 default: | 56 default: |
| 55 return ""; | 57 return ""; |
| 56 } | 58 } |
| 57 } | 59 } |
| 58 | 60 |
| 59 | 61 |
| 60 class CodeEventLogger::NameBuffer { | 62 class CodeEventLogger::NameBuffer { |
| 61 public: | 63 public: |
| 62 NameBuffer() { Reset(); } | 64 NameBuffer() { Reset(); } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 int utf8_pos_; | 154 int utf8_pos_; |
| 153 char utf8_buffer_[kUtf8BufferSize]; | 155 char utf8_buffer_[kUtf8BufferSize]; |
| 154 uc16 utf16_buffer[kUtf16BufferSize]; | 156 uc16 utf16_buffer[kUtf16BufferSize]; |
| 155 }; | 157 }; |
| 156 | 158 |
| 157 | 159 |
| 158 CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { } | 160 CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { } |
| 159 | 161 |
| 160 CodeEventLogger::~CodeEventLogger() { delete name_buffer_; } | 162 CodeEventLogger::~CodeEventLogger() { delete name_buffer_; } |
| 161 | 163 |
| 162 | |
| 163 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 164 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 164 Code* code, | 165 AbstractCode* code, const char* comment) { |
| 165 const char* comment) { | |
| 166 name_buffer_->Init(tag); | 166 name_buffer_->Init(tag); |
| 167 name_buffer_->AppendBytes(comment); | 167 name_buffer_->AppendBytes(comment); |
| 168 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); | 168 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 169 } | 169 } |
| 170 | 170 |
| 171 | |
| 172 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 171 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 173 Code* code, | 172 AbstractCode* code, Name* name) { |
| 174 Name* name) { | |
| 175 name_buffer_->Init(tag); | 173 name_buffer_->Init(tag); |
| 176 name_buffer_->AppendName(name); | 174 name_buffer_->AppendName(name); |
| 177 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); | 175 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 178 } | 176 } |
| 179 | 177 |
| 180 | |
| 181 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 178 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 182 Code* code, | 179 AbstractCode* code, |
| 183 SharedFunctionInfo* shared, | 180 SharedFunctionInfo* shared, |
| 184 CompilationInfo* info, | 181 CompilationInfo* info, Name* name) { |
| 185 Name* name) { | |
| 186 name_buffer_->Init(tag); | 182 name_buffer_->Init(tag); |
| 187 name_buffer_->AppendBytes(ComputeMarker(shared, code)); | 183 name_buffer_->AppendBytes(ComputeMarker(shared, code)); |
| 188 name_buffer_->AppendName(name); | 184 name_buffer_->AppendName(name); |
| 189 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); | 185 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
| 190 } | 186 } |
| 191 | 187 |
| 192 | |
| 193 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 188 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 194 Code* code, | 189 AbstractCode* code, |
| 195 SharedFunctionInfo* shared, | 190 SharedFunctionInfo* shared, |
| 196 CompilationInfo* info, | 191 CompilationInfo* info, Name* source, |
| 197 Name* source, int line, int column) { | 192 int line, int column) { |
| 198 name_buffer_->Init(tag); | 193 name_buffer_->Init(tag); |
| 199 name_buffer_->AppendBytes(ComputeMarker(shared, code)); | 194 name_buffer_->AppendBytes(ComputeMarker(shared, code)); |
| 200 name_buffer_->AppendString(shared->DebugName()); | 195 name_buffer_->AppendString(shared->DebugName()); |
| 201 name_buffer_->AppendByte(' '); | 196 name_buffer_->AppendByte(' '); |
| 202 if (source->IsString()) { | 197 if (source->IsString()) { |
| 203 name_buffer_->AppendString(String::cast(source)); | 198 name_buffer_->AppendString(String::cast(source)); |
| 204 } else { | 199 } else { |
| 205 name_buffer_->AppendBytes("symbol(hash "); | 200 name_buffer_->AppendBytes("symbol(hash "); |
| 206 name_buffer_->AppendHex(Name::cast(source)->Hash()); | 201 name_buffer_->AppendHex(Name::cast(source)->Hash()); |
| 207 name_buffer_->AppendByte(')'); | 202 name_buffer_->AppendByte(')'); |
| 208 } | 203 } |
| 209 name_buffer_->AppendByte(':'); | 204 name_buffer_->AppendByte(':'); |
| 210 name_buffer_->AppendInt(line); | 205 name_buffer_->AppendInt(line); |
| 211 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); | 206 LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size()); |
| 212 } | 207 } |
| 213 | 208 |
| 214 | |
| 215 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, | 209 void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 216 Code* code, | 210 AbstractCode* code, int args_count) { |
| 217 int args_count) { | |
| 218 name_buffer_->Init(tag); | 211 name_buffer_->Init(tag); |
| 219 name_buffer_->AppendInt(args_count); | 212 name_buffer_->AppendInt(args_count); |
| 220 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); | 213 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 221 } | 214 } |
| 222 | 215 |
| 223 | 216 void CodeEventLogger::RegExpCodeCreateEvent(AbstractCode* code, |
| 224 void CodeEventLogger::RegExpCodeCreateEvent(Code* code, String* source) { | 217 String* source) { |
| 225 name_buffer_->Init(Logger::REG_EXP_TAG); | 218 name_buffer_->Init(Logger::REG_EXP_TAG); |
| 226 name_buffer_->AppendString(source); | 219 name_buffer_->AppendString(source); |
| 227 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); | 220 LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size()); |
| 228 } | 221 } |
| 229 | 222 |
| 230 | 223 |
| 231 // Linux perf tool logging support | 224 // Linux perf tool logging support |
| 232 class PerfBasicLogger : public CodeEventLogger { | 225 class PerfBasicLogger : public CodeEventLogger { |
| 233 public: | 226 public: |
| 234 PerfBasicLogger(); | 227 PerfBasicLogger(); |
| 235 virtual ~PerfBasicLogger(); | 228 ~PerfBasicLogger() override; |
| 236 | 229 |
| 237 virtual void CodeMoveEvent(Address from, Address to) { } | 230 void CodeMoveEvent(AbstractCode* from, Address to) override {} |
| 238 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } | 231 void CodeDisableOptEvent(AbstractCode* code, |
| 239 virtual void CodeDeleteEvent(Address from) { } | 232 SharedFunctionInfo* shared) override {} |
| 240 | 233 |
| 241 private: | 234 private: |
| 242 virtual void LogRecordedBuffer(Code* code, | 235 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 243 SharedFunctionInfo* shared, | 236 const char* name, int length) override; |
| 244 const char* name, | |
| 245 int length); | |
| 246 | 237 |
| 247 // Extension added to V8 log file name to get the low-level log name. | 238 // Extension added to V8 log file name to get the low-level log name. |
| 248 static const char kFilenameFormatString[]; | 239 static const char kFilenameFormatString[]; |
| 249 static const int kFilenameBufferPadding; | 240 static const int kFilenameBufferPadding; |
| 250 | 241 |
| 251 // File buffer size of the low-level log. We don't use the default to | 242 // File buffer size of the low-level log. We don't use the default to |
| 252 // minimize the associated overhead. | 243 // minimize the associated overhead. |
| 253 static const int kLogBufferSize = 2 * MB; | 244 static const int kLogBufferSize = 2 * MB; |
| 254 | 245 |
| 255 FILE* perf_output_handle_; | 246 FILE* perf_output_handle_; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 274 CHECK_NOT_NULL(perf_output_handle_); | 265 CHECK_NOT_NULL(perf_output_handle_); |
| 275 setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize); | 266 setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize); |
| 276 } | 267 } |
| 277 | 268 |
| 278 | 269 |
| 279 PerfBasicLogger::~PerfBasicLogger() { | 270 PerfBasicLogger::~PerfBasicLogger() { |
| 280 fclose(perf_output_handle_); | 271 fclose(perf_output_handle_); |
| 281 perf_output_handle_ = NULL; | 272 perf_output_handle_ = NULL; |
| 282 } | 273 } |
| 283 | 274 |
| 284 | 275 void PerfBasicLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*, |
| 285 void PerfBasicLogger::LogRecordedBuffer(Code* code, | 276 const char* name, int length) { |
| 286 SharedFunctionInfo*, | |
| 287 const char* name, | |
| 288 int length) { | |
| 289 DCHECK(code->instruction_start() == code->address() + Code::kHeaderSize); | |
| 290 | |
| 291 if (FLAG_perf_basic_prof_only_functions && | 277 if (FLAG_perf_basic_prof_only_functions && |
| 292 (code->kind() != Code::FUNCTION && | 278 (code->kind() != AbstractCode::FUNCTION && |
| 293 code->kind() != Code::OPTIMIZED_FUNCTION)) { | 279 code->kind() != AbstractCode::INTERPRETED_FUNCTION && |
| 280 code->kind() != AbstractCode::OPTIMIZED_FUNCTION)) { |
| 294 return; | 281 return; |
| 295 } | 282 } |
| 296 | 283 |
| 297 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n", | 284 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n", |
| 298 reinterpret_cast<uint64_t>(code->instruction_start()), | 285 reinterpret_cast<uint64_t>(code->instruction_start()), |
| 299 code->instruction_size(), length, name); | 286 code->instruction_size(), length, name); |
| 300 } | 287 } |
| 301 | 288 |
| 302 | 289 |
| 303 // Low-level logging support. | 290 // Low-level logging support. |
| 304 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 291 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 305 | 292 |
| 306 class LowLevelLogger : public CodeEventLogger { | 293 class LowLevelLogger : public CodeEventLogger { |
| 307 public: | 294 public: |
| 308 explicit LowLevelLogger(const char* file_name); | 295 explicit LowLevelLogger(const char* file_name); |
| 309 virtual ~LowLevelLogger(); | 296 ~LowLevelLogger() override; |
| 310 | 297 |
| 311 virtual void CodeMoveEvent(Address from, Address to); | 298 void CodeMoveEvent(AbstractCode* from, Address to) override; |
| 312 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } | 299 void CodeDisableOptEvent(AbstractCode* code, |
| 313 virtual void CodeDeleteEvent(Address from); | 300 SharedFunctionInfo* shared) override {} |
| 314 virtual void SnapshotPositionEvent(Address addr, int pos); | 301 void SnapshotPositionEvent(Address addr, int pos); |
| 315 virtual void CodeMovingGCEvent(); | 302 void CodeMovingGCEvent() override; |
| 316 | 303 |
| 317 private: | 304 private: |
| 318 virtual void LogRecordedBuffer(Code* code, | 305 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 319 SharedFunctionInfo* shared, | 306 const char* name, int length) override; |
| 320 const char* name, | |
| 321 int length); | |
| 322 | 307 |
| 323 // Low-level profiling event structures. | 308 // Low-level profiling event structures. |
| 324 struct CodeCreateStruct { | 309 struct CodeCreateStruct { |
| 325 static const char kTag = 'C'; | 310 static const char kTag = 'C'; |
| 326 | 311 |
| 327 int32_t name_size; | 312 int32_t name_size; |
| 328 Address code_address; | 313 Address code_address; |
| 329 int32_t code_size; | 314 int32_t code_size; |
| 330 }; | 315 }; |
| 331 | 316 |
| 332 | 317 |
| 333 struct CodeMoveStruct { | 318 struct CodeMoveStruct { |
| 334 static const char kTag = 'M'; | 319 static const char kTag = 'M'; |
| 335 | 320 |
| 336 Address from_address; | 321 Address from_address; |
| 337 Address to_address; | 322 Address to_address; |
| 338 }; | 323 }; |
| 339 | 324 |
| 340 | 325 |
| 341 struct CodeDeleteStruct { | |
| 342 static const char kTag = 'D'; | |
| 343 | |
| 344 Address address; | |
| 345 }; | |
| 346 | |
| 347 | |
| 348 struct SnapshotPositionStruct { | 326 struct SnapshotPositionStruct { |
| 349 static const char kTag = 'P'; | 327 static const char kTag = 'P'; |
| 350 | 328 |
| 351 Address address; | 329 Address address; |
| 352 int32_t position; | 330 int32_t position; |
| 353 }; | 331 }; |
| 354 | 332 |
| 355 | 333 |
| 356 static const char kCodeMovingGCTag = 'G'; | 334 static const char kCodeMovingGCTag = 'G'; |
| 357 | 335 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 #elif V8_TARGET_ARCH_X87 | 393 #elif V8_TARGET_ARCH_X87 |
| 416 const char arch[] = "x87"; | 394 const char arch[] = "x87"; |
| 417 #elif V8_TARGET_ARCH_ARM64 | 395 #elif V8_TARGET_ARCH_ARM64 |
| 418 const char arch[] = "arm64"; | 396 const char arch[] = "arm64"; |
| 419 #else | 397 #else |
| 420 const char arch[] = "unknown"; | 398 const char arch[] = "unknown"; |
| 421 #endif | 399 #endif |
| 422 LogWriteBytes(arch, sizeof(arch)); | 400 LogWriteBytes(arch, sizeof(arch)); |
| 423 } | 401 } |
| 424 | 402 |
| 425 | 403 void LowLevelLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*, |
| 426 void LowLevelLogger::LogRecordedBuffer(Code* code, | 404 const char* name, int length) { |
| 427 SharedFunctionInfo*, | |
| 428 const char* name, | |
| 429 int length) { | |
| 430 CodeCreateStruct event; | 405 CodeCreateStruct event; |
| 431 event.name_size = length; | 406 event.name_size = length; |
| 432 event.code_address = code->instruction_start(); | 407 event.code_address = code->instruction_start(); |
| 433 DCHECK(event.code_address == code->address() + Code::kHeaderSize); | |
| 434 event.code_size = code->instruction_size(); | 408 event.code_size = code->instruction_size(); |
| 435 LogWriteStruct(event); | 409 LogWriteStruct(event); |
| 436 LogWriteBytes(name, length); | 410 LogWriteBytes(name, length); |
| 437 LogWriteBytes( | 411 LogWriteBytes( |
| 438 reinterpret_cast<const char*>(code->instruction_start()), | 412 reinterpret_cast<const char*>(code->instruction_start()), |
| 439 code->instruction_size()); | 413 code->instruction_size()); |
| 440 } | 414 } |
| 441 | 415 |
| 442 | 416 void LowLevelLogger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 443 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | |
| 444 CodeMoveStruct event; | 417 CodeMoveStruct event; |
| 445 event.from_address = from + Code::kHeaderSize; | 418 event.from_address = from->instruction_start(); |
| 446 event.to_address = to + Code::kHeaderSize; | 419 size_t header_size = from->instruction_start() - from->address(); |
| 420 event.to_address = to + header_size; |
| 447 LogWriteStruct(event); | 421 LogWriteStruct(event); |
| 448 } | 422 } |
| 449 | 423 |
| 450 | 424 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { |
| 451 void LowLevelLogger::CodeDeleteEvent(Address from) { | 425 HeapObject* obj = HeapObject::FromAddress(addr); |
| 452 CodeDeleteStruct event; | 426 if (obj->IsAbstractCode()) { |
| 453 event.address = from + Code::kHeaderSize; | 427 SnapshotPositionStruct event; |
| 454 LogWriteStruct(event); | 428 event.address = |
| 429 addr + (obj->IsCode() ? Code::kHeaderSize : BytecodeArray::kHeaderSize); |
| 430 event.position = pos; |
| 431 LogWriteStruct(event); |
| 432 } |
| 455 } | 433 } |
| 456 | 434 |
| 457 | 435 |
| 458 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { | |
| 459 SnapshotPositionStruct event; | |
| 460 event.address = addr + Code::kHeaderSize; | |
| 461 event.position = pos; | |
| 462 LogWriteStruct(event); | |
| 463 } | |
| 464 | |
| 465 | |
| 466 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { | 436 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { |
| 467 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); | 437 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); |
| 468 DCHECK(static_cast<size_t>(size) == rv); | 438 DCHECK(static_cast<size_t>(size) == rv); |
| 469 USE(rv); | 439 USE(rv); |
| 470 } | 440 } |
| 471 | 441 |
| 472 | 442 |
| 473 void LowLevelLogger::CodeMovingGCEvent() { | 443 void LowLevelLogger::CodeMovingGCEvent() { |
| 474 const char tag = kCodeMovingGCTag; | 444 const char tag = kCodeMovingGCTag; |
| 475 | 445 |
| 476 LogWriteBytes(&tag, sizeof(tag)); | 446 LogWriteBytes(&tag, sizeof(tag)); |
| 477 } | 447 } |
| 478 | 448 |
| 479 | 449 |
| 480 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; | 450 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
| 481 | 451 |
| 482 | 452 |
| 483 class JitLogger : public CodeEventLogger { | 453 class JitLogger : public CodeEventLogger { |
| 484 public: | 454 public: |
| 485 explicit JitLogger(JitCodeEventHandler code_event_handler); | 455 explicit JitLogger(JitCodeEventHandler code_event_handler); |
| 486 | 456 |
| 487 virtual void CodeMoveEvent(Address from, Address to); | 457 void CodeMoveEvent(AbstractCode* from, Address to) override; |
| 488 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } | 458 void CodeDisableOptEvent(AbstractCode* code, |
| 489 virtual void CodeDeleteEvent(Address from); | 459 SharedFunctionInfo* shared) override {} |
| 490 virtual void AddCodeLinePosInfoEvent( | 460 void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset, |
| 491 void* jit_handler_data, | 461 int position, |
| 492 int pc_offset, | 462 JitCodeEvent::PositionType position_type); |
| 493 int position, | |
| 494 JitCodeEvent::PositionType position_type); | |
| 495 | 463 |
| 496 void* StartCodePosInfoEvent(); | 464 void* StartCodePosInfoEvent(); |
| 497 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); | 465 void EndCodePosInfoEvent(AbstractCode* code, void* jit_handler_data); |
| 498 | 466 |
| 499 private: | 467 private: |
| 500 virtual void LogRecordedBuffer(Code* code, | 468 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 501 SharedFunctionInfo* shared, | 469 const char* name, int length) override; |
| 502 const char* name, | |
| 503 int length); | |
| 504 | 470 |
| 505 JitCodeEventHandler code_event_handler_; | 471 JitCodeEventHandler code_event_handler_; |
| 506 base::Mutex logger_mutex_; | 472 base::Mutex logger_mutex_; |
| 507 }; | 473 }; |
| 508 | 474 |
| 509 | 475 |
| 510 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) | 476 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
| 511 : code_event_handler_(code_event_handler) { | 477 : code_event_handler_(code_event_handler) { |
| 512 } | 478 } |
| 513 | 479 |
| 514 | 480 void JitLogger::LogRecordedBuffer(AbstractCode* code, |
| 515 void JitLogger::LogRecordedBuffer(Code* code, | 481 SharedFunctionInfo* shared, const char* name, |
| 516 SharedFunctionInfo* shared, | |
| 517 const char* name, | |
| 518 int length) { | 482 int length) { |
| 519 JitCodeEvent event; | 483 JitCodeEvent event; |
| 520 memset(&event, 0, sizeof(event)); | 484 memset(&event, 0, sizeof(event)); |
| 521 event.type = JitCodeEvent::CODE_ADDED; | 485 event.type = JitCodeEvent::CODE_ADDED; |
| 522 event.code_start = code->instruction_start(); | 486 event.code_start = code->instruction_start(); |
| 523 event.code_len = code->instruction_size(); | 487 event.code_len = code->instruction_size(); |
| 524 Handle<SharedFunctionInfo> shared_function_handle; | 488 Handle<SharedFunctionInfo> shared_function_handle; |
| 525 if (shared && shared->script()->IsScript()) { | 489 if (shared && shared->script()->IsScript()) { |
| 526 shared_function_handle = Handle<SharedFunctionInfo>(shared); | 490 shared_function_handle = Handle<SharedFunctionInfo>(shared); |
| 527 } | 491 } |
| 528 event.script = ToApiHandle<v8::UnboundScript>(shared_function_handle); | 492 event.script = ToApiHandle<v8::UnboundScript>(shared_function_handle); |
| 529 event.name.str = name; | 493 event.name.str = name; |
| 530 event.name.len = length; | 494 event.name.len = length; |
| 531 code_event_handler_(&event); | 495 code_event_handler_(&event); |
| 532 } | 496 } |
| 533 | 497 |
| 534 | 498 void JitLogger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 535 void JitLogger::CodeMoveEvent(Address from, Address to) { | |
| 536 base::LockGuard<base::Mutex> guard(&logger_mutex_); | 499 base::LockGuard<base::Mutex> guard(&logger_mutex_); |
| 537 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 538 | 500 |
| 539 JitCodeEvent event; | 501 JitCodeEvent event; |
| 540 event.type = JitCodeEvent::CODE_MOVED; | 502 event.type = JitCodeEvent::CODE_MOVED; |
| 541 event.code_start = from_code->instruction_start(); | 503 event.code_start = from->instruction_start(); |
| 542 event.code_len = from_code->instruction_size(); | 504 event.code_len = from->instruction_size(); |
| 543 | 505 |
| 544 // Calculate the header size. | 506 // Calculate the header size. |
| 545 const size_t header_size = | 507 const size_t header_size = from->instruction_start() - from->address(); |
| 546 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | |
| 547 | 508 |
| 548 // Calculate the new start address of the instructions. | 509 // Calculate the new start address of the instructions. |
| 549 event.new_code_start = | 510 event.new_code_start = to + header_size; |
| 550 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; | |
| 551 | 511 |
| 552 code_event_handler_(&event); | 512 code_event_handler_(&event); |
| 553 } | 513 } |
| 554 | |
| 555 | |
| 556 void JitLogger::CodeDeleteEvent(Address from) { | |
| 557 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 558 | |
| 559 JitCodeEvent event; | |
| 560 event.type = JitCodeEvent::CODE_REMOVED; | |
| 561 event.code_start = from_code->instruction_start(); | |
| 562 event.code_len = from_code->instruction_size(); | |
| 563 | |
| 564 code_event_handler_(&event); | |
| 565 } | |
| 566 | 514 |
| 567 void JitLogger::AddCodeLinePosInfoEvent( | 515 void JitLogger::AddCodeLinePosInfoEvent( |
| 568 void* jit_handler_data, | 516 void* jit_handler_data, |
| 569 int pc_offset, | 517 int pc_offset, |
| 570 int position, | 518 int position, |
| 571 JitCodeEvent::PositionType position_type) { | 519 JitCodeEvent::PositionType position_type) { |
| 572 JitCodeEvent event; | 520 JitCodeEvent event; |
| 573 memset(&event, 0, sizeof(event)); | 521 memset(&event, 0, sizeof(event)); |
| 574 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO; | 522 event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO; |
| 575 event.user_data = jit_handler_data; | 523 event.user_data = jit_handler_data; |
| 576 event.line_info.offset = pc_offset; | 524 event.line_info.offset = pc_offset; |
| 577 event.line_info.pos = position; | 525 event.line_info.pos = position; |
| 578 event.line_info.position_type = position_type; | 526 event.line_info.position_type = position_type; |
| 579 | 527 |
| 580 code_event_handler_(&event); | 528 code_event_handler_(&event); |
| 581 } | 529 } |
| 582 | 530 |
| 583 | 531 |
| 584 void* JitLogger::StartCodePosInfoEvent() { | 532 void* JitLogger::StartCodePosInfoEvent() { |
| 585 JitCodeEvent event; | 533 JitCodeEvent event; |
| 586 memset(&event, 0, sizeof(event)); | 534 memset(&event, 0, sizeof(event)); |
| 587 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; | 535 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; |
| 588 | 536 |
| 589 code_event_handler_(&event); | 537 code_event_handler_(&event); |
| 590 return event.user_data; | 538 return event.user_data; |
| 591 } | 539 } |
| 592 | 540 |
| 593 | 541 void JitLogger::EndCodePosInfoEvent(AbstractCode* code, |
| 594 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) { | 542 void* jit_handler_data) { |
| 595 JitCodeEvent event; | 543 JitCodeEvent event; |
| 596 memset(&event, 0, sizeof(event)); | 544 memset(&event, 0, sizeof(event)); |
| 597 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; | 545 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; |
| 598 event.code_start = code->instruction_start(); | 546 event.code_start = code->instruction_start(); |
| 599 event.user_data = jit_handler_data; | 547 event.user_data = jit_handler_data; |
| 600 | 548 |
| 601 code_event_handler_(&event); | 549 code_event_handler_(&event); |
| 602 } | 550 } |
| 603 | 551 |
| 604 | 552 |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); | 1077 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); |
| 1130 CallbackEventInternal("get ", name, entry_point); | 1078 CallbackEventInternal("get ", name, entry_point); |
| 1131 } | 1079 } |
| 1132 | 1080 |
| 1133 | 1081 |
| 1134 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1082 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
| 1135 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); | 1083 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); |
| 1136 CallbackEventInternal("set ", name, entry_point); | 1084 CallbackEventInternal("set ", name, entry_point); |
| 1137 } | 1085 } |
| 1138 | 1086 |
| 1139 | |
| 1140 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, | 1087 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
| 1141 Logger::LogEventsAndTags tag, | 1088 Logger::LogEventsAndTags tag, |
| 1142 Code* code) { | 1089 AbstractCode* code) { |
| 1143 DCHECK(msg); | 1090 DCHECK(msg); |
| 1144 msg->Append("%s,%s,%d,", | 1091 msg->Append("%s,%s,%d,", |
| 1145 kLogEventsNames[Logger::CODE_CREATION_EVENT], | 1092 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
| 1146 kLogEventsNames[tag], | 1093 kLogEventsNames[tag], |
| 1147 code->kind()); | 1094 code->kind()); |
| 1148 msg->AppendAddress(code->address()); | 1095 msg->AppendAddress(code->address()); |
| 1149 msg->Append(",%d,", code->ExecutableSize()); | 1096 msg->Append(",%d,", code->ExecutableSize()); |
| 1150 } | 1097 } |
| 1151 | 1098 |
| 1152 | 1099 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1153 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1154 Code* code, | |
| 1155 const char* comment) { | 1100 const char* comment) { |
| 1156 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); | 1101 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); |
| 1157 | 1102 |
| 1158 if (!is_logging_code_events()) return; | 1103 if (!is_logging_code_events()) return; |
| 1159 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); | 1104 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); |
| 1160 | 1105 |
| 1161 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1106 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1162 Log::MessageBuilder msg(log_); | 1107 Log::MessageBuilder msg(log_); |
| 1163 AppendCodeCreateHeader(&msg, tag, code); | 1108 AppendCodeCreateHeader(&msg, tag, code); |
| 1164 msg.AppendDoubleQuotedString(comment); | 1109 msg.AppendDoubleQuotedString(comment); |
| 1165 msg.WriteToLogFile(); | 1110 msg.WriteToLogFile(); |
| 1166 } | 1111 } |
| 1167 | 1112 |
| 1168 | 1113 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1169 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1170 Code* code, | |
| 1171 Name* name) { | 1114 Name* name) { |
| 1172 PROFILER_LOG(CodeCreateEvent(tag, code, name)); | 1115 PROFILER_LOG(CodeCreateEvent(tag, code, name)); |
| 1173 | 1116 |
| 1174 if (!is_logging_code_events()) return; | 1117 if (!is_logging_code_events()) return; |
| 1175 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); | 1118 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); |
| 1176 | 1119 |
| 1177 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1120 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1178 Log::MessageBuilder msg(log_); | 1121 Log::MessageBuilder msg(log_); |
| 1179 AppendCodeCreateHeader(&msg, tag, code); | 1122 AppendCodeCreateHeader(&msg, tag, code); |
| 1180 if (name->IsString()) { | 1123 if (name->IsString()) { |
| 1181 msg.Append('"'); | 1124 msg.Append('"'); |
| 1182 msg.AppendDetailed(String::cast(name), false); | 1125 msg.AppendDetailed(String::cast(name), false); |
| 1183 msg.Append('"'); | 1126 msg.Append('"'); |
| 1184 } else { | 1127 } else { |
| 1185 msg.AppendSymbolName(Symbol::cast(name)); | 1128 msg.AppendSymbolName(Symbol::cast(name)); |
| 1186 } | 1129 } |
| 1187 msg.WriteToLogFile(); | 1130 msg.WriteToLogFile(); |
| 1188 } | 1131 } |
| 1189 | 1132 |
| 1190 | 1133 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1191 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1134 SharedFunctionInfo* shared, CompilationInfo* info, |
| 1192 Code* code, | |
| 1193 SharedFunctionInfo* shared, | |
| 1194 CompilationInfo* info, | |
| 1195 Name* name) { | 1135 Name* name) { |
| 1196 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); | 1136 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1197 | 1137 |
| 1198 if (!is_logging_code_events()) return; | 1138 if (!is_logging_code_events()) return; |
| 1199 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); | 1139 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); |
| 1200 | 1140 |
| 1201 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1141 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1202 if (code == isolate_->builtins()->builtin(Builtins::kCompileLazy)) return; | 1142 if (code == AbstractCode::cast( |
| 1143 isolate_->builtins()->builtin(Builtins::kCompileLazy))) { |
| 1144 return; |
| 1145 } |
| 1203 | 1146 |
| 1204 Log::MessageBuilder msg(log_); | 1147 Log::MessageBuilder msg(log_); |
| 1205 AppendCodeCreateHeader(&msg, tag, code); | 1148 AppendCodeCreateHeader(&msg, tag, code); |
| 1206 if (name->IsString()) { | 1149 if (name->IsString()) { |
| 1207 base::SmartArrayPointer<char> str = | 1150 base::SmartArrayPointer<char> str = |
| 1208 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1151 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1209 msg.Append("\"%s\"", str.get()); | 1152 msg.Append("\"%s\"", str.get()); |
| 1210 } else { | 1153 } else { |
| 1211 msg.AppendSymbolName(Symbol::cast(name)); | 1154 msg.AppendSymbolName(Symbol::cast(name)); |
| 1212 } | 1155 } |
| 1213 msg.Append(','); | 1156 msg.Append(','); |
| 1214 msg.AppendAddress(shared->address()); | 1157 msg.AppendAddress(shared->address()); |
| 1215 msg.Append(",%s", ComputeMarker(shared, code)); | 1158 msg.Append(",%s", ComputeMarker(shared, code)); |
| 1216 msg.WriteToLogFile(); | 1159 msg.WriteToLogFile(); |
| 1217 } | 1160 } |
| 1218 | 1161 |
| 1219 | 1162 |
| 1220 // Although, it is possible to extract source and line from | 1163 // Although, it is possible to extract source and line from |
| 1221 // the SharedFunctionInfo object, we left it to caller | 1164 // the SharedFunctionInfo object, we left it to caller |
| 1222 // to leave logging functions free from heap allocations. | 1165 // to leave logging functions free from heap allocations. |
| 1223 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1166 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1224 Code* code, | 1167 SharedFunctionInfo* shared, CompilationInfo* info, |
| 1225 SharedFunctionInfo* shared, | |
| 1226 CompilationInfo* info, | |
| 1227 Name* source, int line, int column) { | 1168 Name* source, int line, int column) { |
| 1228 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column)); | 1169 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column)); |
| 1229 | 1170 |
| 1230 if (!is_logging_code_events()) return; | 1171 if (!is_logging_code_events()) return; |
| 1231 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line, | 1172 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line, |
| 1232 column)); | 1173 column)); |
| 1233 | 1174 |
| 1234 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1175 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1235 Log::MessageBuilder msg(log_); | 1176 Log::MessageBuilder msg(log_); |
| 1236 AppendCodeCreateHeader(&msg, tag, code); | 1177 AppendCodeCreateHeader(&msg, tag, code); |
| 1237 base::SmartArrayPointer<char> name = | 1178 base::SmartArrayPointer<char> name = |
| 1238 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1179 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1239 msg.Append("\"%s ", name.get()); | 1180 msg.Append("\"%s ", name.get()); |
| 1240 if (source->IsString()) { | 1181 if (source->IsString()) { |
| 1241 base::SmartArrayPointer<char> sourcestr = String::cast(source)->ToCString( | 1182 base::SmartArrayPointer<char> sourcestr = String::cast(source)->ToCString( |
| 1242 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1183 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1243 msg.Append("%s", sourcestr.get()); | 1184 msg.Append("%s", sourcestr.get()); |
| 1244 } else { | 1185 } else { |
| 1245 msg.AppendSymbolName(Symbol::cast(source)); | 1186 msg.AppendSymbolName(Symbol::cast(source)); |
| 1246 } | 1187 } |
| 1247 msg.Append(":%d:%d\",", line, column); | 1188 msg.Append(":%d:%d\",", line, column); |
| 1248 msg.AppendAddress(shared->address()); | 1189 msg.AppendAddress(shared->address()); |
| 1249 msg.Append(",%s", ComputeMarker(shared, code)); | 1190 msg.Append(",%s", ComputeMarker(shared, code)); |
| 1250 msg.WriteToLogFile(); | 1191 msg.WriteToLogFile(); |
| 1251 } | 1192 } |
| 1252 | 1193 |
| 1253 | 1194 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1254 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1255 Code* code, | |
| 1256 int args_count) { | 1195 int args_count) { |
| 1257 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); | 1196 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1258 | 1197 |
| 1259 if (!is_logging_code_events()) return; | 1198 if (!is_logging_code_events()) return; |
| 1260 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); | 1199 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); |
| 1261 | 1200 |
| 1262 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1201 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1263 Log::MessageBuilder msg(log_); | 1202 Log::MessageBuilder msg(log_); |
| 1264 AppendCodeCreateHeader(&msg, tag, code); | 1203 AppendCodeCreateHeader(&msg, tag, code); |
| 1265 msg.Append("\"args_count: %d\"", args_count); | 1204 msg.Append("\"args_count: %d\"", args_count); |
| 1266 msg.WriteToLogFile(); | 1205 msg.WriteToLogFile(); |
| 1267 } | 1206 } |
| 1268 | 1207 |
| 1269 | 1208 void Logger::CodeDisableOptEvent(AbstractCode* code, |
| 1270 void Logger::CodeDisableOptEvent(Code* code, | |
| 1271 SharedFunctionInfo* shared) { | 1209 SharedFunctionInfo* shared) { |
| 1272 PROFILER_LOG(CodeDisableOptEvent(code, shared)); | 1210 PROFILER_LOG(CodeDisableOptEvent(code, shared)); |
| 1273 | 1211 |
| 1274 if (!is_logging_code_events()) return; | 1212 if (!is_logging_code_events()) return; |
| 1275 CALL_LISTENERS(CodeDisableOptEvent(code, shared)); | 1213 CALL_LISTENERS(CodeDisableOptEvent(code, shared)); |
| 1276 | 1214 |
| 1277 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1215 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1278 Log::MessageBuilder msg(log_); | 1216 Log::MessageBuilder msg(log_); |
| 1279 msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]); | 1217 msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]); |
| 1280 base::SmartArrayPointer<char> name = | 1218 base::SmartArrayPointer<char> name = |
| 1281 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1219 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1282 msg.Append("\"%s\",", name.get()); | 1220 msg.Append("\"%s\",", name.get()); |
| 1283 msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason())); | 1221 msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason())); |
| 1284 msg.WriteToLogFile(); | 1222 msg.WriteToLogFile(); |
| 1285 } | 1223 } |
| 1286 | 1224 |
| 1287 | 1225 |
| 1288 void Logger::CodeMovingGCEvent() { | 1226 void Logger::CodeMovingGCEvent() { |
| 1289 PROFILER_LOG(CodeMovingGCEvent()); | 1227 PROFILER_LOG(CodeMovingGCEvent()); |
| 1290 | 1228 |
| 1291 if (!is_logging_code_events()) return; | 1229 if (!is_logging_code_events()) return; |
| 1292 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1230 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1293 CALL_LISTENERS(CodeMovingGCEvent()); | 1231 CALL_LISTENERS(CodeMovingGCEvent()); |
| 1294 base::OS::SignalCodeMovingGC(); | 1232 base::OS::SignalCodeMovingGC(); |
| 1295 } | 1233 } |
| 1296 | 1234 |
| 1297 | 1235 void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) { |
| 1298 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | |
| 1299 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); | 1236 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); |
| 1300 | 1237 |
| 1301 if (!is_logging_code_events()) return; | 1238 if (!is_logging_code_events()) return; |
| 1302 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); | 1239 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); |
| 1303 | 1240 |
| 1304 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1241 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1305 Log::MessageBuilder msg(log_); | 1242 Log::MessageBuilder msg(log_); |
| 1306 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1243 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1307 msg.Append('"'); | 1244 msg.Append('"'); |
| 1308 msg.AppendDetailed(source, false); | 1245 msg.AppendDetailed(source, false); |
| 1309 msg.Append('"'); | 1246 msg.Append('"'); |
| 1310 msg.WriteToLogFile(); | 1247 msg.WriteToLogFile(); |
| 1311 } | 1248 } |
| 1312 | 1249 |
| 1313 | 1250 void Logger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 1314 void Logger::CodeMoveEvent(Address from, Address to) { | |
| 1315 PROFILER_LOG(CodeMoveEvent(from, to)); | 1251 PROFILER_LOG(CodeMoveEvent(from, to)); |
| 1316 | 1252 |
| 1317 if (!is_logging_code_events()) return; | 1253 if (!is_logging_code_events()) return; |
| 1318 CALL_LISTENERS(CodeMoveEvent(from, to)); | 1254 CALL_LISTENERS(CodeMoveEvent(from, to)); |
| 1319 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1255 MoveEventInternal(CODE_MOVE_EVENT, from->address(), to); |
| 1320 } | 1256 } |
| 1321 | 1257 |
| 1322 | |
| 1323 void Logger::CodeDeleteEvent(Address from) { | |
| 1324 PROFILER_LOG(CodeDeleteEvent(from)); | |
| 1325 | |
| 1326 if (!is_logging_code_events()) return; | |
| 1327 CALL_LISTENERS(CodeDeleteEvent(from)); | |
| 1328 | |
| 1329 if (!FLAG_log_code || !log_->IsEnabled()) return; | |
| 1330 Log::MessageBuilder msg(log_); | |
| 1331 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); | |
| 1332 msg.AppendAddress(from); | |
| 1333 msg.WriteToLogFile(); | |
| 1334 } | |
| 1335 | |
| 1336 | |
| 1337 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1258 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1338 int pc_offset, | 1259 int pc_offset, int position) { |
| 1339 int position) { | |
| 1340 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1260 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1341 pc_offset, | 1261 pc_offset, |
| 1342 position, | 1262 position, |
| 1343 JitCodeEvent::POSITION)); | 1263 JitCodeEvent::POSITION)); |
| 1344 } | 1264 } |
| 1345 | 1265 |
| 1346 | 1266 |
| 1347 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, | 1267 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, |
| 1348 int pc_offset, | 1268 int pc_offset, |
| 1349 int position) { | 1269 int position) { |
| 1350 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1270 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1351 pc_offset, | 1271 pc_offset, |
| 1352 position, | 1272 position, |
| 1353 JitCodeEvent::STATEMENT_POSITION)); | 1273 JitCodeEvent::STATEMENT_POSITION)); |
| 1354 } | 1274 } |
| 1355 | 1275 |
| 1356 | 1276 |
| 1357 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { | 1277 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { |
| 1358 if (jit_logger_ != NULL) { | 1278 if (jit_logger_ != NULL) { |
| 1359 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); | 1279 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); |
| 1360 } | 1280 } |
| 1361 } | 1281 } |
| 1362 | 1282 |
| 1363 | 1283 void Logger::CodeEndLinePosInfoRecordEvent(AbstractCode* code, |
| 1364 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | |
| 1365 void* jit_handler_data) { | 1284 void* jit_handler_data) { |
| 1366 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); | 1285 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
| 1367 } | 1286 } |
| 1368 | 1287 |
| 1369 | 1288 |
| 1370 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { | 1289 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { |
| 1371 if (code_name == NULL) return; // Not a code object. | 1290 if (code_name == NULL) return; // Not a code object. |
| 1372 Log::MessageBuilder msg(log_); | 1291 Log::MessageBuilder msg(log_); |
| 1373 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | 1292 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1374 msg.AppendDoubleQuotedString(code_name); | 1293 msg.AppendDoubleQuotedString(code_name); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1532 // This function can be called when Log's mutex is acquired, | 1451 // This function can be called when Log's mutex is acquired, |
| 1533 // either from main or Profiler's thread. | 1452 // either from main or Profiler's thread. |
| 1534 void Logger::LogFailure() { | 1453 void Logger::LogFailure() { |
| 1535 StopProfiler(); | 1454 StopProfiler(); |
| 1536 } | 1455 } |
| 1537 | 1456 |
| 1538 | 1457 |
| 1539 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor { | 1458 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor { |
| 1540 public: | 1459 public: |
| 1541 EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis, | 1460 EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis, |
| 1542 Handle<Code>* code_objects, | 1461 Handle<AbstractCode>* code_objects, |
| 1543 int* count) | 1462 int* count) |
| 1544 : sfis_(sfis), code_objects_(code_objects), count_(count) { } | 1463 : sfis_(sfis), code_objects_(code_objects), count_(count) {} |
| 1545 | 1464 |
| 1546 virtual void EnterContext(Context* context) {} | 1465 virtual void EnterContext(Context* context) {} |
| 1547 virtual void LeaveContext(Context* context) {} | 1466 virtual void LeaveContext(Context* context) {} |
| 1548 | 1467 |
| 1549 virtual void VisitFunction(JSFunction* function) { | 1468 virtual void VisitFunction(JSFunction* function) { |
| 1550 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared()); | 1469 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared()); |
| 1551 Object* maybe_script = sfi->script(); | 1470 Object* maybe_script = sfi->script(); |
| 1552 if (maybe_script->IsScript() | 1471 if (maybe_script->IsScript() |
| 1553 && !Script::cast(maybe_script)->HasValidSource()) return; | 1472 && !Script::cast(maybe_script)->HasValidSource()) return; |
| 1554 if (sfis_ != NULL) { | 1473 if (sfis_ != NULL) { |
| 1555 sfis_[*count_] = Handle<SharedFunctionInfo>(sfi); | 1474 sfis_[*count_] = Handle<SharedFunctionInfo>(sfi); |
| 1556 } | 1475 } |
| 1557 if (code_objects_ != NULL) { | 1476 if (code_objects_ != NULL) { |
| 1558 DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 1477 DCHECK(function->abstract_code()->kind() == |
| 1559 code_objects_[*count_] = Handle<Code>(function->code()); | 1478 AbstractCode::OPTIMIZED_FUNCTION); |
| 1479 code_objects_[*count_] = Handle<AbstractCode>(function->abstract_code()); |
| 1560 } | 1480 } |
| 1561 *count_ = *count_ + 1; | 1481 *count_ = *count_ + 1; |
| 1562 } | 1482 } |
| 1563 | 1483 |
| 1564 private: | 1484 private: |
| 1565 Handle<SharedFunctionInfo>* sfis_; | 1485 Handle<SharedFunctionInfo>* sfis_; |
| 1566 Handle<Code>* code_objects_; | 1486 Handle<AbstractCode>* code_objects_; |
| 1567 int* count_; | 1487 int* count_; |
| 1568 }; | 1488 }; |
| 1569 | 1489 |
| 1570 | |
| 1571 static int EnumerateCompiledFunctions(Heap* heap, | 1490 static int EnumerateCompiledFunctions(Heap* heap, |
| 1572 Handle<SharedFunctionInfo>* sfis, | 1491 Handle<SharedFunctionInfo>* sfis, |
| 1573 Handle<Code>* code_objects) { | 1492 Handle<AbstractCode>* code_objects) { |
| 1574 HeapIterator iterator(heap); | 1493 HeapIterator iterator(heap); |
| 1575 DisallowHeapAllocation no_gc; | 1494 DisallowHeapAllocation no_gc; |
| 1576 int compiled_funcs_count = 0; | 1495 int compiled_funcs_count = 0; |
| 1577 | 1496 |
| 1578 // Iterate the heap to find shared function info objects and record | 1497 // Iterate the heap to find shared function info objects and record |
| 1579 // the unoptimized code for them. | 1498 // the unoptimized code for them. |
| 1580 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1499 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1581 if (!obj->IsSharedFunctionInfo()) continue; | 1500 if (!obj->IsSharedFunctionInfo()) continue; |
| 1582 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); | 1501 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); |
| 1583 if (sfi->is_compiled() | 1502 if (sfi->is_compiled() |
| 1584 && (!sfi->script()->IsScript() | 1503 && (!sfi->script()->IsScript() |
| 1585 || Script::cast(sfi->script())->HasValidSource())) { | 1504 || Script::cast(sfi->script())->HasValidSource())) { |
| 1586 if (sfis != NULL) { | 1505 if (sfis != NULL) { |
| 1587 sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); | 1506 sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); |
| 1588 } | 1507 } |
| 1589 if (code_objects != NULL) { | 1508 if (code_objects != NULL) { |
| 1590 code_objects[compiled_funcs_count] = Handle<Code>(sfi->code()); | 1509 code_objects[compiled_funcs_count] = |
| 1510 Handle<AbstractCode>(sfi->abstract_code()); |
| 1591 } | 1511 } |
| 1592 ++compiled_funcs_count; | 1512 ++compiled_funcs_count; |
| 1593 } | 1513 } |
| 1594 } | 1514 } |
| 1595 | 1515 |
| 1596 // Iterate all optimized functions in all contexts. | 1516 // Iterate all optimized functions in all contexts. |
| 1597 EnumerateOptimizedFunctionsVisitor visitor(sfis, | 1517 EnumerateOptimizedFunctionsVisitor visitor(sfis, |
| 1598 code_objects, | 1518 code_objects, |
| 1599 &compiled_funcs_count); | 1519 &compiled_funcs_count); |
| 1600 Deoptimizer::VisitAllOptimizedFunctions(heap->isolate(), &visitor); | 1520 Deoptimizer::VisitAllOptimizedFunctions(heap->isolate(), &visitor); |
| 1601 | 1521 |
| 1602 return compiled_funcs_count; | 1522 return compiled_funcs_count; |
| 1603 } | 1523 } |
| 1604 | 1524 |
| 1605 | 1525 |
| 1606 void Logger::LogCodeObject(Object* object) { | 1526 void Logger::LogCodeObject(Object* object) { |
| 1607 Code* code_object = Code::cast(object); | 1527 AbstractCode* code_object = AbstractCode::cast(object); |
| 1608 LogEventsAndTags tag = Logger::STUB_TAG; | 1528 LogEventsAndTags tag = Logger::STUB_TAG; |
| 1609 const char* description = "Unknown code from the snapshot"; | 1529 const char* description = "Unknown code from the snapshot"; |
| 1610 switch (code_object->kind()) { | 1530 switch (code_object->kind()) { |
| 1611 case Code::FUNCTION: | 1531 case AbstractCode::FUNCTION: |
| 1612 case Code::OPTIMIZED_FUNCTION: | 1532 case AbstractCode::INTERPRETED_FUNCTION: |
| 1533 case AbstractCode::OPTIMIZED_FUNCTION: |
| 1613 return; // We log this later using LogCompiledFunctions. | 1534 return; // We log this later using LogCompiledFunctions. |
| 1614 case Code::BINARY_OP_IC: | 1535 case AbstractCode::BINARY_OP_IC: // fall through |
| 1615 case Code::COMPARE_IC: // fall through | 1536 case AbstractCode::COMPARE_IC: // fall through |
| 1616 case Code::COMPARE_NIL_IC: // fall through | 1537 case AbstractCode::COMPARE_NIL_IC: // fall through |
| 1617 case Code::TO_BOOLEAN_IC: // fall through | 1538 case AbstractCode::TO_BOOLEAN_IC: // fall through |
| 1618 case Code::STUB: | 1539 |
| 1619 description = CodeStub::MajorName(CodeStub::GetMajorKey(code_object)); | 1540 case AbstractCode::STUB: |
| 1541 description = |
| 1542 CodeStub::MajorName(CodeStub::GetMajorKey(code_object->GetCode())); |
| 1620 if (description == NULL) | 1543 if (description == NULL) |
| 1621 description = "A stub from the snapshot"; | 1544 description = "A stub from the snapshot"; |
| 1622 tag = Logger::STUB_TAG; | 1545 tag = Logger::STUB_TAG; |
| 1623 break; | 1546 break; |
| 1624 case Code::REGEXP: | 1547 case AbstractCode::REGEXP: |
| 1625 description = "Regular expression code"; | 1548 description = "Regular expression code"; |
| 1626 tag = Logger::REG_EXP_TAG; | 1549 tag = Logger::REG_EXP_TAG; |
| 1627 break; | 1550 break; |
| 1628 case Code::BUILTIN: | 1551 case AbstractCode::BUILTIN: |
| 1629 description = isolate_->builtins()->name(code_object->builtin_index()); | 1552 description = |
| 1553 isolate_->builtins()->name(code_object->GetCode()->builtin_index()); |
| 1630 tag = Logger::BUILTIN_TAG; | 1554 tag = Logger::BUILTIN_TAG; |
| 1631 break; | 1555 break; |
| 1632 case Code::HANDLER: | 1556 case AbstractCode::HANDLER: |
| 1633 description = "An IC handler from the snapshot"; | 1557 description = "An IC handler from the snapshot"; |
| 1634 tag = Logger::HANDLER_TAG; | 1558 tag = Logger::HANDLER_TAG; |
| 1635 break; | 1559 break; |
| 1636 case Code::KEYED_LOAD_IC: | 1560 case AbstractCode::KEYED_LOAD_IC: |
| 1637 description = "A keyed load IC from the snapshot"; | 1561 description = "A keyed load IC from the snapshot"; |
| 1638 tag = Logger::KEYED_LOAD_IC_TAG; | 1562 tag = Logger::KEYED_LOAD_IC_TAG; |
| 1639 break; | 1563 break; |
| 1640 case Code::LOAD_IC: | 1564 case AbstractCode::LOAD_IC: |
| 1641 description = "A load IC from the snapshot"; | 1565 description = "A load IC from the snapshot"; |
| 1642 tag = Logger::LOAD_IC_TAG; | 1566 tag = Logger::LOAD_IC_TAG; |
| 1643 break; | 1567 break; |
| 1644 case Code::CALL_IC: | 1568 case AbstractCode::CALL_IC: |
| 1645 description = "A call IC from the snapshot"; | 1569 description = "A call IC from the snapshot"; |
| 1646 tag = Logger::CALL_IC_TAG; | 1570 tag = Logger::CALL_IC_TAG; |
| 1647 break; | 1571 break; |
| 1648 case Code::STORE_IC: | 1572 case AbstractCode::STORE_IC: |
| 1649 description = "A store IC from the snapshot"; | 1573 description = "A store IC from the snapshot"; |
| 1650 tag = Logger::STORE_IC_TAG; | 1574 tag = Logger::STORE_IC_TAG; |
| 1651 break; | 1575 break; |
| 1652 case Code::KEYED_STORE_IC: | 1576 case AbstractCode::KEYED_STORE_IC: |
| 1653 description = "A keyed store IC from the snapshot"; | 1577 description = "A keyed store IC from the snapshot"; |
| 1654 tag = Logger::KEYED_STORE_IC_TAG; | 1578 tag = Logger::KEYED_STORE_IC_TAG; |
| 1655 break; | 1579 break; |
| 1656 case Code::WASM_FUNCTION: | 1580 case AbstractCode::WASM_FUNCTION: |
| 1657 description = "A wasm function"; | 1581 description = "A wasm function"; |
| 1658 tag = Logger::STUB_TAG; | 1582 tag = Logger::STUB_TAG; |
| 1659 break; | 1583 break; |
| 1660 case Code::NUMBER_OF_KINDS: | |
| 1661 break; | |
| 1662 } | 1584 } |
| 1663 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); | 1585 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); |
| 1664 } | 1586 } |
| 1665 | 1587 |
| 1666 | 1588 |
| 1667 void Logger::LogCodeObjects() { | 1589 void Logger::LogCodeObjects() { |
| 1668 Heap* heap = isolate_->heap(); | 1590 Heap* heap = isolate_->heap(); |
| 1669 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1591 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1670 "Logger::LogCodeObjects"); | 1592 "Logger::LogCodeObjects"); |
| 1671 HeapIterator iterator(heap); | 1593 HeapIterator iterator(heap); |
| 1672 DisallowHeapAllocation no_gc; | 1594 DisallowHeapAllocation no_gc; |
| 1673 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1595 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1674 if (obj->IsCode()) LogCodeObject(obj); | 1596 if (obj->IsCode()) LogCodeObject(obj); |
| 1597 if (obj->IsBytecodeArray()) LogCodeObject(obj); |
| 1675 } | 1598 } |
| 1676 } | 1599 } |
| 1677 | 1600 |
| 1678 | |
| 1679 void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, | 1601 void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, |
| 1680 Handle<Code> code) { | 1602 Handle<AbstractCode> code) { |
| 1681 Handle<String> func_name(shared->DebugName()); | 1603 Handle<String> func_name(shared->DebugName()); |
| 1682 if (shared->script()->IsScript()) { | 1604 if (shared->script()->IsScript()) { |
| 1683 Handle<Script> script(Script::cast(shared->script())); | 1605 Handle<Script> script(Script::cast(shared->script())); |
| 1684 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 1606 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
| 1685 int column_num = | 1607 int column_num = |
| 1686 Script::GetColumnNumber(script, shared->start_position()) + 1; | 1608 Script::GetColumnNumber(script, shared->start_position()) + 1; |
| 1687 if (script->name()->IsString()) { | 1609 if (script->name()->IsString()) { |
| 1688 Handle<String> script_name(String::cast(script->name())); | 1610 Handle<String> script_name(String::cast(script->name())); |
| 1689 if (line_num > 0) { | 1611 if (line_num > 0) { |
| 1690 PROFILE(isolate_, | 1612 PROFILE(isolate_, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 } | 1646 } |
| 1725 | 1647 |
| 1726 | 1648 |
| 1727 void Logger::LogCompiledFunctions() { | 1649 void Logger::LogCompiledFunctions() { |
| 1728 Heap* heap = isolate_->heap(); | 1650 Heap* heap = isolate_->heap(); |
| 1729 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1651 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1730 "Logger::LogCompiledFunctions"); | 1652 "Logger::LogCompiledFunctions"); |
| 1731 HandleScope scope(isolate_); | 1653 HandleScope scope(isolate_); |
| 1732 const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL); | 1654 const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL); |
| 1733 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); | 1655 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); |
| 1734 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); | 1656 ScopedVector<Handle<AbstractCode> > code_objects(compiled_funcs_count); |
| 1735 EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start()); | 1657 EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start()); |
| 1736 | 1658 |
| 1737 // During iteration, there can be heap allocation due to | 1659 // During iteration, there can be heap allocation due to |
| 1738 // GetScriptLineNumber call. | 1660 // GetScriptLineNumber call. |
| 1739 for (int i = 0; i < compiled_funcs_count; ++i) { | 1661 for (int i = 0; i < compiled_funcs_count; ++i) { |
| 1740 if (code_objects[i].is_identical_to(isolate_->builtins()->CompileLazy())) | 1662 if (code_objects[i].is_identical_to(isolate_->builtins()->CompileLazy())) |
| 1741 continue; | 1663 continue; |
| 1742 LogExistingFunction(sfis[i], code_objects[i]); | 1664 LogExistingFunction(sfis[i], code_objects[i]); |
| 1743 } | 1665 } |
| 1744 } | 1666 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 removeCodeEventListener(jit_logger_); | 1837 removeCodeEventListener(jit_logger_); |
| 1916 delete jit_logger_; | 1838 delete jit_logger_; |
| 1917 jit_logger_ = NULL; | 1839 jit_logger_ = NULL; |
| 1918 } | 1840 } |
| 1919 | 1841 |
| 1920 return log_->Close(); | 1842 return log_->Close(); |
| 1921 } | 1843 } |
| 1922 | 1844 |
| 1923 } // namespace internal | 1845 } // namespace internal |
| 1924 } // namespace v8 | 1846 } // namespace v8 |
| OLD | NEW |