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 |