Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // 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 {} |
| 233 void CodeDeleteEvent(AbstractCode* from) override {} | |
| 240 | 234 |
| 241 private: | 235 private: |
| 242 virtual void LogRecordedBuffer(Code* code, | 236 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 243 SharedFunctionInfo* shared, | 237 const char* name, int length) override; |
| 244 const char* name, | |
| 245 int length); | |
| 246 | 238 |
| 247 // Extension added to V8 log file name to get the low-level log name. | 239 // Extension added to V8 log file name to get the low-level log name. |
| 248 static const char kFilenameFormatString[]; | 240 static const char kFilenameFormatString[]; |
| 249 static const int kFilenameBufferPadding; | 241 static const int kFilenameBufferPadding; |
| 250 | 242 |
| 251 // File buffer size of the low-level log. We don't use the default to | 243 // File buffer size of the low-level log. We don't use the default to |
| 252 // minimize the associated overhead. | 244 // minimize the associated overhead. |
| 253 static const int kLogBufferSize = 2 * MB; | 245 static const int kLogBufferSize = 2 * MB; |
| 254 | 246 |
| 255 FILE* perf_output_handle_; | 247 FILE* perf_output_handle_; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 274 CHECK_NOT_NULL(perf_output_handle_); | 266 CHECK_NOT_NULL(perf_output_handle_); |
| 275 setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize); | 267 setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize); |
| 276 } | 268 } |
| 277 | 269 |
| 278 | 270 |
| 279 PerfBasicLogger::~PerfBasicLogger() { | 271 PerfBasicLogger::~PerfBasicLogger() { |
| 280 fclose(perf_output_handle_); | 272 fclose(perf_output_handle_); |
| 281 perf_output_handle_ = NULL; | 273 perf_output_handle_ = NULL; |
| 282 } | 274 } |
| 283 | 275 |
| 284 | 276 void PerfBasicLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*, |
| 285 void PerfBasicLogger::LogRecordedBuffer(Code* code, | 277 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 && | 278 if (FLAG_perf_basic_prof_only_functions && |
| 292 (code->kind() != Code::FUNCTION && | 279 (code->kind() != AbstractCode::FUNCTION && |
| 293 code->kind() != Code::OPTIMIZED_FUNCTION)) { | 280 code->kind() != AbstractCode::INTERPRETED_FUNCTION && |
| 281 code->kind() != AbstractCode::OPTIMIZED_FUNCTION)) { | |
| 294 return; | 282 return; |
| 295 } | 283 } |
| 296 | 284 |
| 297 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n", | 285 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n", |
| 298 reinterpret_cast<uint64_t>(code->instruction_start()), | 286 reinterpret_cast<uint64_t>(code->instruction_start()), |
| 299 code->instruction_size(), length, name); | 287 code->instruction_size(), length, name); |
| 300 } | 288 } |
| 301 | 289 |
| 302 | 290 |
| 303 // Low-level logging support. | 291 // Low-level logging support. |
| 304 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; | 292 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; |
| 305 | 293 |
| 306 class LowLevelLogger : public CodeEventLogger { | 294 class LowLevelLogger : public CodeEventLogger { |
| 307 public: | 295 public: |
| 308 explicit LowLevelLogger(const char* file_name); | 296 explicit LowLevelLogger(const char* file_name); |
| 309 virtual ~LowLevelLogger(); | 297 ~LowLevelLogger() override; |
| 310 | 298 |
| 311 virtual void CodeMoveEvent(Address from, Address to); | 299 void CodeMoveEvent(AbstractCode* from, Address to) override; |
| 312 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } | 300 void CodeDisableOptEvent(AbstractCode* code, |
| 313 virtual void CodeDeleteEvent(Address from); | 301 SharedFunctionInfo* shared) override {} |
| 314 virtual void SnapshotPositionEvent(Address addr, int pos); | 302 void CodeDeleteEvent(AbstractCode* from) override; |
| 315 virtual void CodeMovingGCEvent(); | 303 void SnapshotPositionEvent(Address addr, int pos); |
| 304 void CodeMovingGCEvent() override; | |
| 316 | 305 |
| 317 private: | 306 private: |
| 318 virtual void LogRecordedBuffer(Code* code, | 307 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 319 SharedFunctionInfo* shared, | 308 const char* name, int length) override; |
| 320 const char* name, | |
| 321 int length); | |
| 322 | 309 |
| 323 // Low-level profiling event structures. | 310 // Low-level profiling event structures. |
| 324 struct CodeCreateStruct { | 311 struct CodeCreateStruct { |
| 325 static const char kTag = 'C'; | 312 static const char kTag = 'C'; |
| 326 | 313 |
| 327 int32_t name_size; | 314 int32_t name_size; |
| 328 Address code_address; | 315 Address code_address; |
| 329 int32_t code_size; | 316 int32_t code_size; |
| 330 }; | 317 }; |
| 331 | 318 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 #elif V8_TARGET_ARCH_X87 | 402 #elif V8_TARGET_ARCH_X87 |
| 416 const char arch[] = "x87"; | 403 const char arch[] = "x87"; |
| 417 #elif V8_TARGET_ARCH_ARM64 | 404 #elif V8_TARGET_ARCH_ARM64 |
| 418 const char arch[] = "arm64"; | 405 const char arch[] = "arm64"; |
| 419 #else | 406 #else |
| 420 const char arch[] = "unknown"; | 407 const char arch[] = "unknown"; |
| 421 #endif | 408 #endif |
| 422 LogWriteBytes(arch, sizeof(arch)); | 409 LogWriteBytes(arch, sizeof(arch)); |
| 423 } | 410 } |
| 424 | 411 |
| 425 | 412 void LowLevelLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*, |
| 426 void LowLevelLogger::LogRecordedBuffer(Code* code, | 413 const char* name, int length) { |
| 427 SharedFunctionInfo*, | |
| 428 const char* name, | |
| 429 int length) { | |
| 430 CodeCreateStruct event; | 414 CodeCreateStruct event; |
| 431 event.name_size = length; | 415 event.name_size = length; |
| 432 event.code_address = code->instruction_start(); | 416 event.code_address = code->instruction_start(); |
| 433 DCHECK(event.code_address == code->address() + Code::kHeaderSize); | |
| 434 event.code_size = code->instruction_size(); | 417 event.code_size = code->instruction_size(); |
| 435 LogWriteStruct(event); | 418 LogWriteStruct(event); |
| 436 LogWriteBytes(name, length); | 419 LogWriteBytes(name, length); |
| 437 LogWriteBytes( | 420 LogWriteBytes( |
| 438 reinterpret_cast<const char*>(code->instruction_start()), | 421 reinterpret_cast<const char*>(code->instruction_start()), |
| 439 code->instruction_size()); | 422 code->instruction_size()); |
| 440 } | 423 } |
| 441 | 424 |
| 442 | 425 void LowLevelLogger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 443 void LowLevelLogger::CodeMoveEvent(Address from, Address to) { | |
| 444 CodeMoveStruct event; | 426 CodeMoveStruct event; |
| 445 event.from_address = from + Code::kHeaderSize; | 427 event.from_address = from->instruction_start(); |
| 446 event.to_address = to + Code::kHeaderSize; | 428 size_t header_size = from->instruction_start() - from->address(); |
| 429 event.to_address = to + header_size; | |
| 447 LogWriteStruct(event); | 430 LogWriteStruct(event); |
| 448 } | 431 } |
| 449 | 432 |
| 450 | 433 void LowLevelLogger::CodeDeleteEvent(AbstractCode* from) { |
| 451 void LowLevelLogger::CodeDeleteEvent(Address from) { | |
| 452 CodeDeleteStruct event; | 434 CodeDeleteStruct event; |
| 453 event.address = from + Code::kHeaderSize; | 435 event.address = from->instruction_start(); |
| 454 LogWriteStruct(event); | 436 LogWriteStruct(event); |
| 455 } | 437 } |
| 456 | 438 |
| 457 | 439 |
| 458 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { | 440 void LowLevelLogger::SnapshotPositionEvent(Address addr, int pos) { |
| 459 SnapshotPositionStruct event; | 441 HeapObject* obj = HeapObject::FromAddress(addr); |
| 460 event.address = addr + Code::kHeaderSize; | 442 if (obj->IsAbstractCode()) { |
|
rmcilroy
2016/02/23 18:52:55
Yang: had a go at removing SnapshotPositionEvent
| |
| 461 event.position = pos; | 443 SnapshotPositionStruct event; |
| 462 LogWriteStruct(event); | 444 event.address = |
| 445 addr + (obj->IsCode() ? Code::kHeaderSize : BytecodeArray::kHeaderSize); | |
| 446 event.position = pos; | |
| 447 LogWriteStruct(event); | |
| 448 } | |
| 463 } | 449 } |
| 464 | 450 |
| 465 | 451 |
| 466 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { | 452 void LowLevelLogger::LogWriteBytes(const char* bytes, int size) { |
| 467 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); | 453 size_t rv = fwrite(bytes, 1, size, ll_output_handle_); |
| 468 DCHECK(static_cast<size_t>(size) == rv); | 454 DCHECK(static_cast<size_t>(size) == rv); |
| 469 USE(rv); | 455 USE(rv); |
| 470 } | 456 } |
| 471 | 457 |
| 472 | 458 |
| 473 void LowLevelLogger::CodeMovingGCEvent() { | 459 void LowLevelLogger::CodeMovingGCEvent() { |
| 474 const char tag = kCodeMovingGCTag; | 460 const char tag = kCodeMovingGCTag; |
| 475 | 461 |
| 476 LogWriteBytes(&tag, sizeof(tag)); | 462 LogWriteBytes(&tag, sizeof(tag)); |
| 477 } | 463 } |
| 478 | 464 |
| 479 | 465 |
| 480 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; | 466 #define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call; |
| 481 | 467 |
| 482 | 468 |
| 483 class JitLogger : public CodeEventLogger { | 469 class JitLogger : public CodeEventLogger { |
| 484 public: | 470 public: |
| 485 explicit JitLogger(JitCodeEventHandler code_event_handler); | 471 explicit JitLogger(JitCodeEventHandler code_event_handler); |
| 486 | 472 |
| 487 virtual void CodeMoveEvent(Address from, Address to); | 473 void CodeMoveEvent(AbstractCode* from, Address to) override; |
| 488 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } | 474 void CodeDisableOptEvent(AbstractCode* code, |
| 489 virtual void CodeDeleteEvent(Address from); | 475 SharedFunctionInfo* shared) override {} |
| 490 virtual void AddCodeLinePosInfoEvent( | 476 void CodeDeleteEvent(AbstractCode* from) override; |
| 491 void* jit_handler_data, | 477 void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset, |
| 492 int pc_offset, | 478 int position, |
| 493 int position, | 479 JitCodeEvent::PositionType position_type); |
| 494 JitCodeEvent::PositionType position_type); | |
| 495 | 480 |
| 496 void* StartCodePosInfoEvent(); | 481 void* StartCodePosInfoEvent(); |
| 497 void EndCodePosInfoEvent(Code* code, void* jit_handler_data); | 482 void EndCodePosInfoEvent(AbstractCode* code, void* jit_handler_data); |
| 498 | 483 |
| 499 private: | 484 private: |
| 500 virtual void LogRecordedBuffer(Code* code, | 485 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 501 SharedFunctionInfo* shared, | 486 const char* name, int length) override; |
| 502 const char* name, | |
| 503 int length); | |
| 504 | 487 |
| 505 JitCodeEventHandler code_event_handler_; | 488 JitCodeEventHandler code_event_handler_; |
| 506 base::Mutex logger_mutex_; | 489 base::Mutex logger_mutex_; |
| 507 }; | 490 }; |
| 508 | 491 |
| 509 | 492 |
| 510 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) | 493 JitLogger::JitLogger(JitCodeEventHandler code_event_handler) |
| 511 : code_event_handler_(code_event_handler) { | 494 : code_event_handler_(code_event_handler) { |
| 512 } | 495 } |
| 513 | 496 |
| 514 | 497 void JitLogger::LogRecordedBuffer(AbstractCode* code, |
| 515 void JitLogger::LogRecordedBuffer(Code* code, | 498 SharedFunctionInfo* shared, const char* name, |
| 516 SharedFunctionInfo* shared, | |
| 517 const char* name, | |
| 518 int length) { | 499 int length) { |
| 519 JitCodeEvent event; | 500 JitCodeEvent event; |
| 520 memset(&event, 0, sizeof(event)); | 501 memset(&event, 0, sizeof(event)); |
| 521 event.type = JitCodeEvent::CODE_ADDED; | 502 event.type = JitCodeEvent::CODE_ADDED; |
| 522 event.code_start = code->instruction_start(); | 503 event.code_start = code->instruction_start(); |
| 523 event.code_len = code->instruction_size(); | 504 event.code_len = code->instruction_size(); |
| 524 Handle<SharedFunctionInfo> shared_function_handle; | 505 Handle<SharedFunctionInfo> shared_function_handle; |
| 525 if (shared && shared->script()->IsScript()) { | 506 if (shared && shared->script()->IsScript()) { |
| 526 shared_function_handle = Handle<SharedFunctionInfo>(shared); | 507 shared_function_handle = Handle<SharedFunctionInfo>(shared); |
| 527 } | 508 } |
| 528 event.script = ToApiHandle<v8::UnboundScript>(shared_function_handle); | 509 event.script = ToApiHandle<v8::UnboundScript>(shared_function_handle); |
| 529 event.name.str = name; | 510 event.name.str = name; |
| 530 event.name.len = length; | 511 event.name.len = length; |
| 531 code_event_handler_(&event); | 512 code_event_handler_(&event); |
| 532 } | 513 } |
| 533 | 514 |
| 534 | 515 void JitLogger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 535 void JitLogger::CodeMoveEvent(Address from, Address to) { | |
| 536 base::LockGuard<base::Mutex> guard(&logger_mutex_); | 516 base::LockGuard<base::Mutex> guard(&logger_mutex_); |
| 537 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 538 | 517 |
| 539 JitCodeEvent event; | 518 JitCodeEvent event; |
| 540 event.type = JitCodeEvent::CODE_MOVED; | 519 event.type = JitCodeEvent::CODE_MOVED; |
| 541 event.code_start = from_code->instruction_start(); | 520 event.code_start = from->instruction_start(); |
| 542 event.code_len = from_code->instruction_size(); | 521 event.code_len = from->instruction_size(); |
| 543 | 522 |
| 544 // Calculate the header size. | 523 // Calculate the header size. |
| 545 const size_t header_size = | 524 const size_t header_size = from->instruction_start() - from->address(); |
| 546 from_code->instruction_start() - reinterpret_cast<byte*>(from_code); | |
| 547 | 525 |
| 548 // Calculate the new start address of the instructions. | 526 // Calculate the new start address of the instructions. |
| 549 event.new_code_start = | 527 event.new_code_start = to + header_size; |
| 550 reinterpret_cast<byte*>(HeapObject::FromAddress(to)) + header_size; | |
| 551 | 528 |
| 552 code_event_handler_(&event); | 529 code_event_handler_(&event); |
| 553 } | 530 } |
| 554 | 531 |
| 555 | 532 void JitLogger::CodeDeleteEvent(AbstractCode* from) { |
| 556 void JitLogger::CodeDeleteEvent(Address from) { | |
| 557 Code* from_code = Code::cast(HeapObject::FromAddress(from)); | |
| 558 | |
| 559 JitCodeEvent event; | 533 JitCodeEvent event; |
| 560 event.type = JitCodeEvent::CODE_REMOVED; | 534 event.type = JitCodeEvent::CODE_REMOVED; |
| 561 event.code_start = from_code->instruction_start(); | 535 event.code_start = from->instruction_start(); |
| 562 event.code_len = from_code->instruction_size(); | 536 event.code_len = from->instruction_size(); |
| 563 | 537 |
| 564 code_event_handler_(&event); | 538 code_event_handler_(&event); |
| 565 } | 539 } |
| 566 | 540 |
| 567 void JitLogger::AddCodeLinePosInfoEvent( | 541 void JitLogger::AddCodeLinePosInfoEvent( |
| 568 void* jit_handler_data, | 542 void* jit_handler_data, |
| 569 int pc_offset, | 543 int pc_offset, |
| 570 int position, | 544 int position, |
| 571 JitCodeEvent::PositionType position_type) { | 545 JitCodeEvent::PositionType position_type) { |
| 572 JitCodeEvent event; | 546 JitCodeEvent event; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 583 | 557 |
| 584 void* JitLogger::StartCodePosInfoEvent() { | 558 void* JitLogger::StartCodePosInfoEvent() { |
| 585 JitCodeEvent event; | 559 JitCodeEvent event; |
| 586 memset(&event, 0, sizeof(event)); | 560 memset(&event, 0, sizeof(event)); |
| 587 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; | 561 event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING; |
| 588 | 562 |
| 589 code_event_handler_(&event); | 563 code_event_handler_(&event); |
| 590 return event.user_data; | 564 return event.user_data; |
| 591 } | 565 } |
| 592 | 566 |
| 593 | 567 void JitLogger::EndCodePosInfoEvent(AbstractCode* code, |
| 594 void JitLogger::EndCodePosInfoEvent(Code* code, void* jit_handler_data) { | 568 void* jit_handler_data) { |
| 595 JitCodeEvent event; | 569 JitCodeEvent event; |
| 596 memset(&event, 0, sizeof(event)); | 570 memset(&event, 0, sizeof(event)); |
| 597 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; | 571 event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING; |
| 598 event.code_start = code->instruction_start(); | 572 event.code_start = code->instruction_start(); |
| 599 event.user_data = jit_handler_data; | 573 event.user_data = jit_handler_data; |
| 600 | 574 |
| 601 code_event_handler_(&event); | 575 code_event_handler_(&event); |
| 602 } | 576 } |
| 603 | 577 |
| 604 | 578 |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1129 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); | 1103 PROFILER_LOG(GetterCallbackEvent(name, entry_point)); |
| 1130 CallbackEventInternal("get ", name, entry_point); | 1104 CallbackEventInternal("get ", name, entry_point); |
| 1131 } | 1105 } |
| 1132 | 1106 |
| 1133 | 1107 |
| 1134 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { | 1108 void Logger::SetterCallbackEvent(Name* name, Address entry_point) { |
| 1135 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); | 1109 PROFILER_LOG(SetterCallbackEvent(name, entry_point)); |
| 1136 CallbackEventInternal("set ", name, entry_point); | 1110 CallbackEventInternal("set ", name, entry_point); |
| 1137 } | 1111 } |
| 1138 | 1112 |
| 1139 | |
| 1140 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, | 1113 static void AppendCodeCreateHeader(Log::MessageBuilder* msg, |
| 1141 Logger::LogEventsAndTags tag, | 1114 Logger::LogEventsAndTags tag, |
| 1142 Code* code) { | 1115 AbstractCode* code) { |
| 1143 DCHECK(msg); | 1116 DCHECK(msg); |
| 1144 msg->Append("%s,%s,%d,", | 1117 msg->Append("%s,%s,%d,", |
| 1145 kLogEventsNames[Logger::CODE_CREATION_EVENT], | 1118 kLogEventsNames[Logger::CODE_CREATION_EVENT], |
| 1146 kLogEventsNames[tag], | 1119 kLogEventsNames[tag], |
| 1147 code->kind()); | 1120 code->kind()); |
| 1148 msg->AppendAddress(code->address()); | 1121 msg->AppendAddress(code->address()); |
| 1149 msg->Append(",%d,", code->ExecutableSize()); | 1122 msg->Append(",%d,", code->ExecutableSize()); |
| 1150 } | 1123 } |
| 1151 | 1124 |
| 1152 | 1125 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1153 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1154 Code* code, | |
| 1155 const char* comment) { | 1126 const char* comment) { |
| 1156 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); | 1127 PROFILER_LOG(CodeCreateEvent(tag, code, comment)); |
| 1157 | 1128 |
| 1158 if (!is_logging_code_events()) return; | 1129 if (!is_logging_code_events()) return; |
| 1159 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); | 1130 CALL_LISTENERS(CodeCreateEvent(tag, code, comment)); |
| 1160 | 1131 |
| 1161 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1132 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1162 Log::MessageBuilder msg(log_); | 1133 Log::MessageBuilder msg(log_); |
| 1163 AppendCodeCreateHeader(&msg, tag, code); | 1134 AppendCodeCreateHeader(&msg, tag, code); |
| 1164 msg.AppendDoubleQuotedString(comment); | 1135 msg.AppendDoubleQuotedString(comment); |
| 1165 msg.WriteToLogFile(); | 1136 msg.WriteToLogFile(); |
| 1166 } | 1137 } |
| 1167 | 1138 |
| 1168 | 1139 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1169 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1170 Code* code, | |
| 1171 Name* name) { | 1140 Name* name) { |
| 1172 PROFILER_LOG(CodeCreateEvent(tag, code, name)); | 1141 PROFILER_LOG(CodeCreateEvent(tag, code, name)); |
| 1173 | 1142 |
| 1174 if (!is_logging_code_events()) return; | 1143 if (!is_logging_code_events()) return; |
| 1175 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); | 1144 CALL_LISTENERS(CodeCreateEvent(tag, code, name)); |
| 1176 | 1145 |
| 1177 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1146 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1178 Log::MessageBuilder msg(log_); | 1147 Log::MessageBuilder msg(log_); |
| 1179 AppendCodeCreateHeader(&msg, tag, code); | 1148 AppendCodeCreateHeader(&msg, tag, code); |
| 1180 if (name->IsString()) { | 1149 if (name->IsString()) { |
| 1181 msg.Append('"'); | 1150 msg.Append('"'); |
| 1182 msg.AppendDetailed(String::cast(name), false); | 1151 msg.AppendDetailed(String::cast(name), false); |
| 1183 msg.Append('"'); | 1152 msg.Append('"'); |
| 1184 } else { | 1153 } else { |
| 1185 msg.AppendSymbolName(Symbol::cast(name)); | 1154 msg.AppendSymbolName(Symbol::cast(name)); |
| 1186 } | 1155 } |
| 1187 msg.WriteToLogFile(); | 1156 msg.WriteToLogFile(); |
| 1188 } | 1157 } |
| 1189 | 1158 |
| 1190 | 1159 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1191 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1160 SharedFunctionInfo* shared, CompilationInfo* info, |
| 1192 Code* code, | |
| 1193 SharedFunctionInfo* shared, | |
| 1194 CompilationInfo* info, | |
| 1195 Name* name) { | 1161 Name* name) { |
| 1196 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); | 1162 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name)); |
| 1197 | 1163 |
| 1198 if (!is_logging_code_events()) return; | 1164 if (!is_logging_code_events()) return; |
| 1199 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); | 1165 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name)); |
| 1200 | 1166 |
| 1201 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1167 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1202 if (code == isolate_->builtins()->builtin(Builtins::kCompileLazy)) return; | 1168 if (code == AbstractCode::cast( |
| 1169 isolate_->builtins()->builtin(Builtins::kCompileLazy))) { | |
| 1170 return; | |
| 1171 } | |
| 1203 | 1172 |
| 1204 Log::MessageBuilder msg(log_); | 1173 Log::MessageBuilder msg(log_); |
| 1205 AppendCodeCreateHeader(&msg, tag, code); | 1174 AppendCodeCreateHeader(&msg, tag, code); |
| 1206 if (name->IsString()) { | 1175 if (name->IsString()) { |
| 1207 base::SmartArrayPointer<char> str = | 1176 base::SmartArrayPointer<char> str = |
| 1208 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1177 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1209 msg.Append("\"%s\"", str.get()); | 1178 msg.Append("\"%s\"", str.get()); |
| 1210 } else { | 1179 } else { |
| 1211 msg.AppendSymbolName(Symbol::cast(name)); | 1180 msg.AppendSymbolName(Symbol::cast(name)); |
| 1212 } | 1181 } |
| 1213 msg.Append(','); | 1182 msg.Append(','); |
| 1214 msg.AppendAddress(shared->address()); | 1183 msg.AppendAddress(shared->address()); |
| 1215 msg.Append(",%s", ComputeMarker(shared, code)); | 1184 msg.Append(",%s", ComputeMarker(shared, code)); |
| 1216 msg.WriteToLogFile(); | 1185 msg.WriteToLogFile(); |
| 1217 } | 1186 } |
| 1218 | 1187 |
| 1219 | 1188 |
| 1220 // Although, it is possible to extract source and line from | 1189 // Although, it is possible to extract source and line from |
| 1221 // the SharedFunctionInfo object, we left it to caller | 1190 // the SharedFunctionInfo object, we left it to caller |
| 1222 // to leave logging functions free from heap allocations. | 1191 // to leave logging functions free from heap allocations. |
| 1223 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 1192 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1224 Code* code, | 1193 SharedFunctionInfo* shared, CompilationInfo* info, |
| 1225 SharedFunctionInfo* shared, | |
| 1226 CompilationInfo* info, | |
| 1227 Name* source, int line, int column) { | 1194 Name* source, int line, int column) { |
| 1228 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column)); | 1195 PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column)); |
| 1229 | 1196 |
| 1230 if (!is_logging_code_events()) return; | 1197 if (!is_logging_code_events()) return; |
| 1231 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line, | 1198 CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line, |
| 1232 column)); | 1199 column)); |
| 1233 | 1200 |
| 1234 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1201 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1235 Log::MessageBuilder msg(log_); | 1202 Log::MessageBuilder msg(log_); |
| 1236 AppendCodeCreateHeader(&msg, tag, code); | 1203 AppendCodeCreateHeader(&msg, tag, code); |
| 1237 base::SmartArrayPointer<char> name = | 1204 base::SmartArrayPointer<char> name = |
| 1238 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1205 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1239 msg.Append("\"%s ", name.get()); | 1206 msg.Append("\"%s ", name.get()); |
| 1240 if (source->IsString()) { | 1207 if (source->IsString()) { |
| 1241 base::SmartArrayPointer<char> sourcestr = String::cast(source)->ToCString( | 1208 base::SmartArrayPointer<char> sourcestr = String::cast(source)->ToCString( |
| 1242 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1209 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1243 msg.Append("%s", sourcestr.get()); | 1210 msg.Append("%s", sourcestr.get()); |
| 1244 } else { | 1211 } else { |
| 1245 msg.AppendSymbolName(Symbol::cast(source)); | 1212 msg.AppendSymbolName(Symbol::cast(source)); |
| 1246 } | 1213 } |
| 1247 msg.Append(":%d:%d\",", line, column); | 1214 msg.Append(":%d:%d\",", line, column); |
| 1248 msg.AppendAddress(shared->address()); | 1215 msg.AppendAddress(shared->address()); |
| 1249 msg.Append(",%s", ComputeMarker(shared, code)); | 1216 msg.Append(",%s", ComputeMarker(shared, code)); |
| 1250 msg.WriteToLogFile(); | 1217 msg.WriteToLogFile(); |
| 1251 } | 1218 } |
| 1252 | 1219 |
| 1253 | 1220 void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
| 1254 void Logger::CodeCreateEvent(LogEventsAndTags tag, | |
| 1255 Code* code, | |
| 1256 int args_count) { | 1221 int args_count) { |
| 1257 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); | 1222 PROFILER_LOG(CodeCreateEvent(tag, code, args_count)); |
| 1258 | 1223 |
| 1259 if (!is_logging_code_events()) return; | 1224 if (!is_logging_code_events()) return; |
| 1260 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); | 1225 CALL_LISTENERS(CodeCreateEvent(tag, code, args_count)); |
| 1261 | 1226 |
| 1262 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1227 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1263 Log::MessageBuilder msg(log_); | 1228 Log::MessageBuilder msg(log_); |
| 1264 AppendCodeCreateHeader(&msg, tag, code); | 1229 AppendCodeCreateHeader(&msg, tag, code); |
| 1265 msg.Append("\"args_count: %d\"", args_count); | 1230 msg.Append("\"args_count: %d\"", args_count); |
| 1266 msg.WriteToLogFile(); | 1231 msg.WriteToLogFile(); |
| 1267 } | 1232 } |
| 1268 | 1233 |
| 1269 | 1234 void Logger::CodeDisableOptEvent(AbstractCode* code, |
| 1270 void Logger::CodeDisableOptEvent(Code* code, | |
| 1271 SharedFunctionInfo* shared) { | 1235 SharedFunctionInfo* shared) { |
| 1272 PROFILER_LOG(CodeDisableOptEvent(code, shared)); | 1236 PROFILER_LOG(CodeDisableOptEvent(code, shared)); |
| 1273 | 1237 |
| 1274 if (!is_logging_code_events()) return; | 1238 if (!is_logging_code_events()) return; |
| 1275 CALL_LISTENERS(CodeDisableOptEvent(code, shared)); | 1239 CALL_LISTENERS(CodeDisableOptEvent(code, shared)); |
| 1276 | 1240 |
| 1277 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1241 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1278 Log::MessageBuilder msg(log_); | 1242 Log::MessageBuilder msg(log_); |
| 1279 msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]); | 1243 msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]); |
| 1280 base::SmartArrayPointer<char> name = | 1244 base::SmartArrayPointer<char> name = |
| 1281 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1245 shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 1282 msg.Append("\"%s\",", name.get()); | 1246 msg.Append("\"%s\",", name.get()); |
| 1283 msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason())); | 1247 msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason())); |
| 1284 msg.WriteToLogFile(); | 1248 msg.WriteToLogFile(); |
| 1285 } | 1249 } |
| 1286 | 1250 |
| 1287 | 1251 |
| 1288 void Logger::CodeMovingGCEvent() { | 1252 void Logger::CodeMovingGCEvent() { |
| 1289 PROFILER_LOG(CodeMovingGCEvent()); | 1253 PROFILER_LOG(CodeMovingGCEvent()); |
| 1290 | 1254 |
| 1291 if (!is_logging_code_events()) return; | 1255 if (!is_logging_code_events()) return; |
| 1292 if (!log_->IsEnabled() || !FLAG_ll_prof) return; | 1256 if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| 1293 CALL_LISTENERS(CodeMovingGCEvent()); | 1257 CALL_LISTENERS(CodeMovingGCEvent()); |
| 1294 base::OS::SignalCodeMovingGC(); | 1258 base::OS::SignalCodeMovingGC(); |
| 1295 } | 1259 } |
| 1296 | 1260 |
| 1297 | 1261 void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) { |
| 1298 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { | |
| 1299 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); | 1262 PROFILER_LOG(RegExpCodeCreateEvent(code, source)); |
| 1300 | 1263 |
| 1301 if (!is_logging_code_events()) return; | 1264 if (!is_logging_code_events()) return; |
| 1302 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); | 1265 CALL_LISTENERS(RegExpCodeCreateEvent(code, source)); |
| 1303 | 1266 |
| 1304 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1267 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1305 Log::MessageBuilder msg(log_); | 1268 Log::MessageBuilder msg(log_); |
| 1306 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); | 1269 AppendCodeCreateHeader(&msg, REG_EXP_TAG, code); |
| 1307 msg.Append('"'); | 1270 msg.Append('"'); |
| 1308 msg.AppendDetailed(source, false); | 1271 msg.AppendDetailed(source, false); |
| 1309 msg.Append('"'); | 1272 msg.Append('"'); |
| 1310 msg.WriteToLogFile(); | 1273 msg.WriteToLogFile(); |
| 1311 } | 1274 } |
| 1312 | 1275 |
| 1313 | 1276 void Logger::CodeMoveEvent(AbstractCode* from, Address to) { |
| 1314 void Logger::CodeMoveEvent(Address from, Address to) { | |
| 1315 PROFILER_LOG(CodeMoveEvent(from, to)); | 1277 PROFILER_LOG(CodeMoveEvent(from, to)); |
| 1316 | 1278 |
| 1317 if (!is_logging_code_events()) return; | 1279 if (!is_logging_code_events()) return; |
| 1318 CALL_LISTENERS(CodeMoveEvent(from, to)); | 1280 CALL_LISTENERS(CodeMoveEvent(from, to)); |
| 1319 MoveEventInternal(CODE_MOVE_EVENT, from, to); | 1281 MoveEventInternal(CODE_MOVE_EVENT, from->address(), to); |
| 1320 } | 1282 } |
| 1321 | 1283 |
| 1322 | 1284 void Logger::CodeDeleteEvent(AbstractCode* from) { |
| 1323 void Logger::CodeDeleteEvent(Address from) { | |
| 1324 PROFILER_LOG(CodeDeleteEvent(from)); | 1285 PROFILER_LOG(CodeDeleteEvent(from)); |
| 1325 | 1286 |
| 1326 if (!is_logging_code_events()) return; | 1287 if (!is_logging_code_events()) return; |
| 1327 CALL_LISTENERS(CodeDeleteEvent(from)); | 1288 CALL_LISTENERS(CodeDeleteEvent(from)); |
| 1328 | 1289 |
| 1329 if (!FLAG_log_code || !log_->IsEnabled()) return; | 1290 if (!FLAG_log_code || !log_->IsEnabled()) return; |
| 1330 Log::MessageBuilder msg(log_); | 1291 Log::MessageBuilder msg(log_); |
| 1331 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); | 1292 msg.Append("%s,", kLogEventsNames[CODE_DELETE_EVENT]); |
| 1332 msg.AppendAddress(from); | 1293 msg.AppendAddress(from->address()); |
| 1333 msg.WriteToLogFile(); | 1294 msg.WriteToLogFile(); |
| 1334 } | 1295 } |
| 1335 | 1296 |
| 1336 | |
| 1337 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, | 1297 void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 1338 int pc_offset, | 1298 int pc_offset, int position) { |
| 1339 int position) { | |
| 1340 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1299 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1341 pc_offset, | 1300 pc_offset, |
| 1342 position, | 1301 position, |
| 1343 JitCodeEvent::POSITION)); | 1302 JitCodeEvent::POSITION)); |
| 1344 } | 1303 } |
| 1345 | 1304 |
| 1346 | 1305 |
| 1347 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, | 1306 void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, |
| 1348 int pc_offset, | 1307 int pc_offset, |
| 1349 int position) { | 1308 int position) { |
| 1350 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, | 1309 JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data, |
| 1351 pc_offset, | 1310 pc_offset, |
| 1352 position, | 1311 position, |
| 1353 JitCodeEvent::STATEMENT_POSITION)); | 1312 JitCodeEvent::STATEMENT_POSITION)); |
| 1354 } | 1313 } |
| 1355 | 1314 |
| 1356 | 1315 |
| 1357 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { | 1316 void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) { |
| 1358 if (jit_logger_ != NULL) { | 1317 if (jit_logger_ != NULL) { |
| 1359 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); | 1318 pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent()); |
| 1360 } | 1319 } |
| 1361 } | 1320 } |
| 1362 | 1321 |
| 1363 | 1322 void Logger::CodeEndLinePosInfoRecordEvent(AbstractCode* code, |
| 1364 void Logger::CodeEndLinePosInfoRecordEvent(Code* code, | |
| 1365 void* jit_handler_data) { | 1323 void* jit_handler_data) { |
| 1366 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); | 1324 JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data)); |
| 1367 } | 1325 } |
| 1368 | 1326 |
| 1369 | 1327 |
| 1370 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { | 1328 void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { |
| 1371 if (code_name == NULL) return; // Not a code object. | 1329 if (code_name == NULL) return; // Not a code object. |
| 1372 Log::MessageBuilder msg(log_); | 1330 Log::MessageBuilder msg(log_); |
| 1373 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); | 1331 msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| 1374 msg.AppendDoubleQuotedString(code_name); | 1332 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, | 1490 // This function can be called when Log's mutex is acquired, |
| 1533 // either from main or Profiler's thread. | 1491 // either from main or Profiler's thread. |
| 1534 void Logger::LogFailure() { | 1492 void Logger::LogFailure() { |
| 1535 StopProfiler(); | 1493 StopProfiler(); |
| 1536 } | 1494 } |
| 1537 | 1495 |
| 1538 | 1496 |
| 1539 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor { | 1497 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor { |
| 1540 public: | 1498 public: |
| 1541 EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis, | 1499 EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis, |
| 1542 Handle<Code>* code_objects, | 1500 Handle<AbstractCode>* code_objects, |
| 1543 int* count) | 1501 int* count) |
| 1544 : sfis_(sfis), code_objects_(code_objects), count_(count) { } | 1502 : sfis_(sfis), code_objects_(code_objects), count_(count) {} |
| 1545 | 1503 |
| 1546 virtual void EnterContext(Context* context) {} | 1504 virtual void EnterContext(Context* context) {} |
| 1547 virtual void LeaveContext(Context* context) {} | 1505 virtual void LeaveContext(Context* context) {} |
| 1548 | 1506 |
| 1549 virtual void VisitFunction(JSFunction* function) { | 1507 virtual void VisitFunction(JSFunction* function) { |
| 1550 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared()); | 1508 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared()); |
| 1551 Object* maybe_script = sfi->script(); | 1509 Object* maybe_script = sfi->script(); |
| 1552 if (maybe_script->IsScript() | 1510 if (maybe_script->IsScript() |
| 1553 && !Script::cast(maybe_script)->HasValidSource()) return; | 1511 && !Script::cast(maybe_script)->HasValidSource()) return; |
| 1554 if (sfis_ != NULL) { | 1512 if (sfis_ != NULL) { |
| 1555 sfis_[*count_] = Handle<SharedFunctionInfo>(sfi); | 1513 sfis_[*count_] = Handle<SharedFunctionInfo>(sfi); |
| 1556 } | 1514 } |
| 1557 if (code_objects_ != NULL) { | 1515 if (code_objects_ != NULL) { |
| 1558 DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 1516 DCHECK(function->abstract_code()->kind() == |
| 1559 code_objects_[*count_] = Handle<Code>(function->code()); | 1517 AbstractCode::OPTIMIZED_FUNCTION); |
| 1518 code_objects_[*count_] = Handle<AbstractCode>(function->abstract_code()); | |
| 1560 } | 1519 } |
| 1561 *count_ = *count_ + 1; | 1520 *count_ = *count_ + 1; |
| 1562 } | 1521 } |
| 1563 | 1522 |
| 1564 private: | 1523 private: |
| 1565 Handle<SharedFunctionInfo>* sfis_; | 1524 Handle<SharedFunctionInfo>* sfis_; |
| 1566 Handle<Code>* code_objects_; | 1525 Handle<AbstractCode>* code_objects_; |
| 1567 int* count_; | 1526 int* count_; |
| 1568 }; | 1527 }; |
| 1569 | 1528 |
| 1570 | |
| 1571 static int EnumerateCompiledFunctions(Heap* heap, | 1529 static int EnumerateCompiledFunctions(Heap* heap, |
| 1572 Handle<SharedFunctionInfo>* sfis, | 1530 Handle<SharedFunctionInfo>* sfis, |
| 1573 Handle<Code>* code_objects) { | 1531 Handle<AbstractCode>* code_objects) { |
| 1574 HeapIterator iterator(heap); | 1532 HeapIterator iterator(heap); |
| 1575 DisallowHeapAllocation no_gc; | 1533 DisallowHeapAllocation no_gc; |
| 1576 int compiled_funcs_count = 0; | 1534 int compiled_funcs_count = 0; |
| 1577 | 1535 |
| 1578 // Iterate the heap to find shared function info objects and record | 1536 // Iterate the heap to find shared function info objects and record |
| 1579 // the unoptimized code for them. | 1537 // the unoptimized code for them. |
| 1580 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1538 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1581 if (!obj->IsSharedFunctionInfo()) continue; | 1539 if (!obj->IsSharedFunctionInfo()) continue; |
| 1582 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); | 1540 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); |
| 1583 if (sfi->is_compiled() | 1541 if (sfi->is_compiled() |
| 1584 && (!sfi->script()->IsScript() | 1542 && (!sfi->script()->IsScript() |
| 1585 || Script::cast(sfi->script())->HasValidSource())) { | 1543 || Script::cast(sfi->script())->HasValidSource())) { |
| 1586 if (sfis != NULL) { | 1544 if (sfis != NULL) { |
| 1587 sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); | 1545 sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi); |
| 1588 } | 1546 } |
| 1589 if (code_objects != NULL) { | 1547 if (code_objects != NULL) { |
| 1590 code_objects[compiled_funcs_count] = Handle<Code>(sfi->code()); | 1548 code_objects[compiled_funcs_count] = |
| 1549 Handle<AbstractCode>(sfi->abstract_code()); | |
| 1591 } | 1550 } |
| 1592 ++compiled_funcs_count; | 1551 ++compiled_funcs_count; |
| 1593 } | 1552 } |
| 1594 } | 1553 } |
| 1595 | 1554 |
| 1596 // Iterate all optimized functions in all contexts. | 1555 // Iterate all optimized functions in all contexts. |
| 1597 EnumerateOptimizedFunctionsVisitor visitor(sfis, | 1556 EnumerateOptimizedFunctionsVisitor visitor(sfis, |
| 1598 code_objects, | 1557 code_objects, |
| 1599 &compiled_funcs_count); | 1558 &compiled_funcs_count); |
| 1600 Deoptimizer::VisitAllOptimizedFunctions(heap->isolate(), &visitor); | 1559 Deoptimizer::VisitAllOptimizedFunctions(heap->isolate(), &visitor); |
| 1601 | 1560 |
| 1602 return compiled_funcs_count; | 1561 return compiled_funcs_count; |
| 1603 } | 1562 } |
| 1604 | 1563 |
| 1605 | 1564 |
| 1606 void Logger::LogCodeObject(Object* object) { | 1565 void Logger::LogCodeObject(Object* object) { |
| 1607 Code* code_object = Code::cast(object); | 1566 AbstractCode* code_object = AbstractCode::cast(object); |
| 1608 LogEventsAndTags tag = Logger::STUB_TAG; | 1567 LogEventsAndTags tag = Logger::STUB_TAG; |
| 1609 const char* description = "Unknown code from the snapshot"; | 1568 const char* description = "Unknown code from the snapshot"; |
| 1610 switch (code_object->kind()) { | 1569 switch (code_object->kind()) { |
| 1611 case Code::FUNCTION: | 1570 case AbstractCode::FUNCTION: |
| 1612 case Code::OPTIMIZED_FUNCTION: | 1571 case AbstractCode::INTERPRETED_FUNCTION: |
| 1572 case AbstractCode::OPTIMIZED_FUNCTION: | |
| 1613 return; // We log this later using LogCompiledFunctions. | 1573 return; // We log this later using LogCompiledFunctions. |
| 1614 case Code::BINARY_OP_IC: | 1574 case AbstractCode::BINARY_OP_IC: |
| 1615 case Code::COMPARE_IC: // fall through | 1575 case AbstractCode::COMPARE_IC: // fall through |
| 1616 case Code::COMPARE_NIL_IC: // fall through | 1576 case AbstractCode::COMPARE_NIL_IC: // fall through |
| 1617 case Code::TO_BOOLEAN_IC: // fall through | 1577 case AbstractCode::TO_BOOLEAN_IC: // fall through |
| 1618 case Code::STUB: | 1578 case AbstractCode::STUB: |
| 1619 description = CodeStub::MajorName(CodeStub::GetMajorKey(code_object)); | 1579 description = |
| 1580 CodeStub::MajorName(CodeStub::GetMajorKey(code_object->GetCode())); | |
| 1620 if (description == NULL) | 1581 if (description == NULL) |
| 1621 description = "A stub from the snapshot"; | 1582 description = "A stub from the snapshot"; |
| 1622 tag = Logger::STUB_TAG; | 1583 tag = Logger::STUB_TAG; |
| 1623 break; | 1584 break; |
| 1624 case Code::REGEXP: | 1585 case AbstractCode::REGEXP: |
| 1625 description = "Regular expression code"; | 1586 description = "Regular expression code"; |
| 1626 tag = Logger::REG_EXP_TAG; | 1587 tag = Logger::REG_EXP_TAG; |
| 1627 break; | 1588 break; |
| 1628 case Code::BUILTIN: | 1589 case AbstractCode::BUILTIN: |
| 1629 description = isolate_->builtins()->name(code_object->builtin_index()); | 1590 description = |
| 1591 isolate_->builtins()->name(code_object->GetCode()->builtin_index()); | |
| 1630 tag = Logger::BUILTIN_TAG; | 1592 tag = Logger::BUILTIN_TAG; |
| 1631 break; | 1593 break; |
| 1632 case Code::HANDLER: | 1594 case AbstractCode::HANDLER: |
| 1633 description = "An IC handler from the snapshot"; | 1595 description = "An IC handler from the snapshot"; |
| 1634 tag = Logger::HANDLER_TAG; | 1596 tag = Logger::HANDLER_TAG; |
| 1635 break; | 1597 break; |
| 1636 case Code::KEYED_LOAD_IC: | 1598 case AbstractCode::KEYED_LOAD_IC: |
| 1637 description = "A keyed load IC from the snapshot"; | 1599 description = "A keyed load IC from the snapshot"; |
| 1638 tag = Logger::KEYED_LOAD_IC_TAG; | 1600 tag = Logger::KEYED_LOAD_IC_TAG; |
| 1639 break; | 1601 break; |
| 1640 case Code::LOAD_IC: | 1602 case AbstractCode::LOAD_IC: |
| 1641 description = "A load IC from the snapshot"; | 1603 description = "A load IC from the snapshot"; |
| 1642 tag = Logger::LOAD_IC_TAG; | 1604 tag = Logger::LOAD_IC_TAG; |
| 1643 break; | 1605 break; |
| 1644 case Code::CALL_IC: | 1606 case AbstractCode::CALL_IC: |
| 1645 description = "A call IC from the snapshot"; | 1607 description = "A call IC from the snapshot"; |
| 1646 tag = Logger::CALL_IC_TAG; | 1608 tag = Logger::CALL_IC_TAG; |
| 1647 break; | 1609 break; |
| 1648 case Code::STORE_IC: | 1610 case AbstractCode::STORE_IC: |
| 1649 description = "A store IC from the snapshot"; | 1611 description = "A store IC from the snapshot"; |
| 1650 tag = Logger::STORE_IC_TAG; | 1612 tag = Logger::STORE_IC_TAG; |
| 1651 break; | 1613 break; |
| 1652 case Code::KEYED_STORE_IC: | 1614 case AbstractCode::KEYED_STORE_IC: |
| 1653 description = "A keyed store IC from the snapshot"; | 1615 description = "A keyed store IC from the snapshot"; |
| 1654 tag = Logger::KEYED_STORE_IC_TAG; | 1616 tag = Logger::KEYED_STORE_IC_TAG; |
| 1655 break; | 1617 break; |
| 1656 case Code::WASM_FUNCTION: | 1618 case AbstractCode::WASM_FUNCTION: |
| 1657 description = "A wasm function"; | 1619 description = "A wasm function"; |
| 1658 tag = Logger::STUB_TAG; | 1620 tag = Logger::STUB_TAG; |
| 1659 break; | 1621 break; |
| 1660 case Code::NUMBER_OF_KINDS: | |
| 1661 break; | |
| 1662 } | 1622 } |
| 1663 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); | 1623 PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); |
| 1664 } | 1624 } |
| 1665 | 1625 |
| 1666 | 1626 |
| 1667 void Logger::LogCodeObjects() { | 1627 void Logger::LogCodeObjects() { |
| 1668 Heap* heap = isolate_->heap(); | 1628 Heap* heap = isolate_->heap(); |
| 1669 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1629 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1670 "Logger::LogCodeObjects"); | 1630 "Logger::LogCodeObjects"); |
| 1671 HeapIterator iterator(heap); | 1631 HeapIterator iterator(heap); |
| 1672 DisallowHeapAllocation no_gc; | 1632 DisallowHeapAllocation no_gc; |
| 1673 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1633 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1674 if (obj->IsCode()) LogCodeObject(obj); | 1634 if (obj->IsCode()) LogCodeObject(obj); |
| 1635 if (obj->IsBytecodeArray()) LogCodeObject(obj); | |
| 1675 } | 1636 } |
| 1676 } | 1637 } |
| 1677 | 1638 |
| 1678 | |
| 1679 void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, | 1639 void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, |
| 1680 Handle<Code> code) { | 1640 Handle<AbstractCode> code) { |
| 1681 Handle<String> func_name(shared->DebugName()); | 1641 Handle<String> func_name(shared->DebugName()); |
| 1682 if (shared->script()->IsScript()) { | 1642 if (shared->script()->IsScript()) { |
| 1683 Handle<Script> script(Script::cast(shared->script())); | 1643 Handle<Script> script(Script::cast(shared->script())); |
| 1684 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 1644 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
| 1685 int column_num = | 1645 int column_num = |
| 1686 Script::GetColumnNumber(script, shared->start_position()) + 1; | 1646 Script::GetColumnNumber(script, shared->start_position()) + 1; |
| 1687 if (script->name()->IsString()) { | 1647 if (script->name()->IsString()) { |
| 1688 Handle<String> script_name(String::cast(script->name())); | 1648 Handle<String> script_name(String::cast(script->name())); |
| 1689 if (line_num > 0) { | 1649 if (line_num > 0) { |
| 1690 PROFILE(isolate_, | 1650 PROFILE(isolate_, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1724 } | 1684 } |
| 1725 | 1685 |
| 1726 | 1686 |
| 1727 void Logger::LogCompiledFunctions() { | 1687 void Logger::LogCompiledFunctions() { |
| 1728 Heap* heap = isolate_->heap(); | 1688 Heap* heap = isolate_->heap(); |
| 1729 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 1689 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 1730 "Logger::LogCompiledFunctions"); | 1690 "Logger::LogCompiledFunctions"); |
| 1731 HandleScope scope(isolate_); | 1691 HandleScope scope(isolate_); |
| 1732 const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL); | 1692 const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL); |
| 1733 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); | 1693 ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count); |
| 1734 ScopedVector< Handle<Code> > code_objects(compiled_funcs_count); | 1694 ScopedVector<Handle<AbstractCode> > code_objects(compiled_funcs_count); |
| 1735 EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start()); | 1695 EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start()); |
| 1736 | 1696 |
| 1737 // During iteration, there can be heap allocation due to | 1697 // During iteration, there can be heap allocation due to |
| 1738 // GetScriptLineNumber call. | 1698 // GetScriptLineNumber call. |
| 1739 for (int i = 0; i < compiled_funcs_count; ++i) { | 1699 for (int i = 0; i < compiled_funcs_count; ++i) { |
| 1740 if (code_objects[i].is_identical_to(isolate_->builtins()->CompileLazy())) | 1700 if (code_objects[i].is_identical_to(isolate_->builtins()->CompileLazy())) |
| 1741 continue; | 1701 continue; |
| 1742 LogExistingFunction(sfis[i], code_objects[i]); | 1702 LogExistingFunction(sfis[i], code_objects[i]); |
| 1743 } | 1703 } |
| 1744 } | 1704 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1915 removeCodeEventListener(jit_logger_); | 1875 removeCodeEventListener(jit_logger_); |
| 1916 delete jit_logger_; | 1876 delete jit_logger_; |
| 1917 jit_logger_ = NULL; | 1877 jit_logger_ = NULL; |
| 1918 } | 1878 } |
| 1919 | 1879 |
| 1920 return log_->Close(); | 1880 return log_->Close(); |
| 1921 } | 1881 } |
| 1922 | 1882 |
| 1923 } // namespace internal | 1883 } // namespace internal |
| 1924 } // namespace v8 | 1884 } // namespace v8 |
| OLD | NEW |