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

Side by Side Diff: src/log.cc

Issue 108011: Introduce internal Log class that handles writing log messages, enable logging to memory buffer. (Closed)
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 TickSample sample; 278 TickSample sample;
279 bool overflow = Logger::profiler_->Remove(&sample); 279 bool overflow = Logger::profiler_->Remove(&sample);
280 while (running_) { 280 while (running_) {
281 LOG(TickEvent(&sample, overflow)); 281 LOG(TickEvent(&sample, overflow));
282 overflow = Logger::profiler_->Remove(&sample); 282 overflow = Logger::profiler_->Remove(&sample);
283 } 283 }
284 } 284 }
285 285
286 286
287 #ifdef ENABLE_LOGGING_AND_PROFILING 287 #ifdef ENABLE_LOGGING_AND_PROFILING
288
289 // Functions and data for performing output of log messages.
290 class Log : public AllStatic {
291 public:
292 // Opens stdout for logging.
293 static void OpenStdout();
294
295 // Opens file for logging.
296 static void OpenFile(const char* name);
297
298 // Opens memory buffer for logging.
299 static void OpenMemoryBuffer();
300
301 // Frees all resources acquired in Open... functions.
302 static void Close();
303
304 // See description in v8.h.
305 static int GetLogLines(int from_pos, char* dest_buf, int max_size);
306
307 static bool is_enabled() { return output_.handle != NULL; }
308
309 typedef int (*WritePtr)(const char* msg, int length);
310 private:
311 static void Init();
312
313 // Write functions assume that mutex_ is acquired by the caller.
314 static WritePtr Write;
315
316 static int WriteToFile(const char* msg, int length) {
317 ASSERT(output_.handle != NULL);
318 int rv = fwrite(msg, 1, length, output_.handle);
319 ASSERT(length == rv);
320 return rv;
321 }
322
323 static int WriteToMemory(const char* msg, int length) {
324 ASSERT(output_.buffer != NULL);
325 ASSERT(output_buffer_write_pos_ >= output_.buffer);
326 if (output_buffer_write_pos_ + length
327 <= output_.buffer + kOutputBufferSize) {
328 memcpy(output_buffer_write_pos_, msg, length);
329 output_buffer_write_pos_ += length;
330 return length;
331 } else {
332 // Memory buffer is full, ignore write.
333 return 0;
334 }
335 }
336
337 // When logging is active, output_ refers the file or memory buffer
338 // events are written to.
339 // mutex_ should be acquired before using output_.
340 union Output {
341 FILE* handle;
342 char* buffer;
343 };
344 static Output output_;
345
346 // mutex_ is a Mutex used for enforcing exclusive
347 // access to the formatting buffer and the log file or log memory buffer.
348 static Mutex* mutex_;
349
350 // Size of buffer used for memory logging.
351 static const int kOutputBufferSize = 2 * 1024 * 1024;
352
353 // Writing position in a memory buffer.
354 static char* output_buffer_write_pos_;
355
356 // Size of buffer used for formatting log messages.
357 static const int kMessageBufferSize = 2048;
358
359 // Buffer used for formatting log messages. This is a singleton buffer and
360 // mutex_ should be acquired before using it.
361 static char* message_buffer_;
362
363 friend class LogMessageBuilder;
364 };
365
366
367 Log::WritePtr Log::Write = NULL;
368 Log::Output Log::output_ = {NULL};
369 Mutex* Log::mutex_ = NULL;
370 char* Log::output_buffer_write_pos_ = NULL;
371 char* Log::message_buffer_ = NULL;
372
373
374 void Log::Init() {
375 mutex_ = OS::CreateMutex();
376 message_buffer_ = NewArray<char>(kMessageBufferSize);
377 }
378
379
380 void Log::OpenStdout() {
381 ASSERT(output_.handle == NULL);
382 output_.handle = stdout;
383 Write = WriteToFile;
384 Init();
385 }
386
387
388 void Log::OpenFile(const char* name) {
389 ASSERT(output_.handle == NULL);
390 output_.handle = OS::FOpen(name, OS::LogFileOpenMode);
391 Write = WriteToFile;
392 Init();
393 }
394
395
396 void Log::OpenMemoryBuffer() {
397 ASSERT(output_.buffer == NULL);
398 output_.buffer = NewArray<char>(kOutputBufferSize);
399 output_buffer_write_pos_ = output_.buffer;
400 Write = WriteToMemory;
401 Init();
402 }
403
404
405 void Log::Close() {
406 if (Write == WriteToFile) {
407 fclose(output_.handle);
408 output_.handle = NULL;
409 } else if (Write == WriteToMemory) {
410 DeleteArray(output_.buffer);
411 output_.buffer = NULL;
412 } else {
413 ASSERT(Write == NULL);
414 }
415 Write = NULL;
416
417 delete mutex_;
418 mutex_ = NULL;
419
420 DeleteArray(message_buffer_);
421 message_buffer_ = NULL;
422 }
423
424
425 int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
426 ASSERT(output_.buffer != NULL);
427 ASSERT(output_buffer_write_pos_ >= output_.buffer);
428 ASSERT(from_pos >= 0);
429 ASSERT(max_size >= 0);
430 int actual_size = max_size;
431 char* buffer_read_pos = output_.buffer + from_pos;
432 ScopedLock sl(mutex_);
433 if (actual_size == 0
434 || output_buffer_write_pos_ == output_.buffer
435 || buffer_read_pos >= output_buffer_write_pos_) {
436 // No data requested or can be returned.
437 return 0;
438 }
439 if (buffer_read_pos + actual_size > output_buffer_write_pos_) {
440 // Requested size overlaps with current writing position and
441 // needs to be truncated.
442 actual_size = output_buffer_write_pos_ - buffer_read_pos;
443 ASSERT(actual_size == 0 || buffer_read_pos[actual_size - 1] == '\n');
444 } else {
445 // Find previous log line boundary.
446 char* end_pos = buffer_read_pos + actual_size - 1;
447 while (end_pos >= buffer_read_pos && *end_pos != '\n') --end_pos;
448 actual_size = end_pos - buffer_read_pos + 1;
449 }
450 ASSERT(actual_size <= max_size);
451 if (actual_size > 0) {
452 memcpy(dest_buf, buffer_read_pos, actual_size);
453 }
454 return actual_size;
455 }
456
457
288 // Utility class for formatting log messages. It fills the message into the 458 // Utility class for formatting log messages. It fills the message into the
289 // static buffer in Logger. 459 // static buffer in Log.
290 class LogMessageBuilder BASE_EMBEDDED { 460 class LogMessageBuilder BASE_EMBEDDED {
291 public: 461 public:
292 explicit LogMessageBuilder(); 462 explicit LogMessageBuilder();
293 ~LogMessageBuilder() { } 463 ~LogMessageBuilder() { }
294 464
295 void Append(const char* format, ...); 465 void Append(const char* format, ...);
296 void Append(const char* format, va_list args); 466 void Append(const char* format, va_list args);
297 void Append(const char c); 467 void Append(const char c);
298 void Append(String *str); 468 void Append(String *str);
299 void AppendDetailed(String* str, bool show_impl_info); 469 void AppendDetailed(String* str, bool show_impl_info);
300 470
301 void WriteToLogFile(); 471 void WriteToLogFile();
302 void WriteCStringToLogFile(const char* str); 472 void WriteCStringToLogFile(const char* str);
303 473
304 private: 474 private:
305 ScopedLock sl; 475 ScopedLock sl;
306 int pos_; 476 int pos_;
307 }; 477 };
308 478
309 479
310 // Create a message builder starting from position 0. This acquires the mutex 480 // Create a message builder starting from position 0. This acquires the mutex
311 // in the logger as well. 481 // in the logger as well.
312 LogMessageBuilder::LogMessageBuilder(): sl(Logger::mutex_), pos_(0) { 482 LogMessageBuilder::LogMessageBuilder(): sl(Log::mutex_), pos_(0) {
313 ASSERT(Logger::message_buffer_ != NULL); 483 ASSERT(Log::message_buffer_ != NULL);
314 } 484 }
315 485
316 486
317 // Append string data to the log message. 487 // Append string data to the log message.
318 void LogMessageBuilder::Append(const char* format, ...) { 488 void LogMessageBuilder::Append(const char* format, ...) {
319 Vector<char> buf(Logger::message_buffer_ + pos_, 489 Vector<char> buf(Log::message_buffer_ + pos_,
320 Logger::kMessageBufferSize - pos_); 490 Log::kMessageBufferSize - pos_);
321 va_list args; 491 va_list args;
322 va_start(args, format); 492 va_start(args, format);
323 Append(format, args); 493 Append(format, args);
324 va_end(args); 494 va_end(args);
325 ASSERT(pos_ <= Logger::kMessageBufferSize); 495 ASSERT(pos_ <= Log::kMessageBufferSize);
326 } 496 }
327 497
328 498
329 // Append string data to the log message. 499 // Append string data to the log message.
330 void LogMessageBuilder::Append(const char* format, va_list args) { 500 void LogMessageBuilder::Append(const char* format, va_list args) {
331 Vector<char> buf(Logger::message_buffer_ + pos_, 501 Vector<char> buf(Log::message_buffer_ + pos_,
332 Logger::kMessageBufferSize - pos_); 502 Log::kMessageBufferSize - pos_);
333 int result = v8::internal::OS::VSNPrintF(buf, format, args); 503 int result = v8::internal::OS::VSNPrintF(buf, format, args);
334 504
335 // Result is -1 if output was truncated. 505 // Result is -1 if output was truncated.
336 if (result >= 0) { 506 if (result >= 0) {
337 pos_ += result; 507 pos_ += result;
338 } else { 508 } else {
339 pos_ = Logger::kMessageBufferSize; 509 pos_ = Log::kMessageBufferSize;
340 } 510 }
341 ASSERT(pos_ <= Logger::kMessageBufferSize); 511 ASSERT(pos_ <= Log::kMessageBufferSize);
342 } 512 }
343 513
344 514
345 // Append a character to the log message. 515 // Append a character to the log message.
346 void LogMessageBuilder::Append(const char c) { 516 void LogMessageBuilder::Append(const char c) {
347 if (pos_ < Logger::kMessageBufferSize) { 517 if (pos_ < Log::kMessageBufferSize) {
348 Logger::message_buffer_[pos_++] = c; 518 Log::message_buffer_[pos_++] = c;
349 } 519 }
350 ASSERT(pos_ <= Logger::kMessageBufferSize); 520 ASSERT(pos_ <= Log::kMessageBufferSize);
351 } 521 }
352 522
353 523
354 // Append a heap string. 524 // Append a heap string.
355 void LogMessageBuilder::Append(String* str) { 525 void LogMessageBuilder::Append(String* str) {
356 AssertNoAllocation no_heap_allocation; // Ensure string stay valid. 526 AssertNoAllocation no_heap_allocation; // Ensure string stay valid.
357 int length = str->length(); 527 int length = str->length();
358 for (int i = 0; i < length; i++) { 528 for (int i = 0; i < length; i++) {
359 Append(static_cast<char>(str->Get(i))); 529 Append(static_cast<char>(str->Get(i)));
360 } 530 }
(...skipping 23 matching lines...) Expand all
384 } else if (c == '\\') { 554 } else if (c == '\\') {
385 Append("\\\\"); 555 Append("\\\\");
386 } else { 556 } else {
387 Append("%lc", c); 557 Append("%lc", c);
388 } 558 }
389 } 559 }
390 } 560 }
391 561
392 // Write the log message to the log file currently opened. 562 // Write the log message to the log file currently opened.
393 void LogMessageBuilder::WriteToLogFile() { 563 void LogMessageBuilder::WriteToLogFile() {
394 ASSERT(pos_ <= Logger::kMessageBufferSize); 564 ASSERT(pos_ <= Log::kMessageBufferSize);
395 size_t rv = fwrite(Logger::message_buffer_, 1, pos_, Logger::logfile_); 565 Log::Write(Log::message_buffer_, pos_);
396 ASSERT(rv == static_cast<size_t>(pos_));
397 USE(rv);
398 } 566 }
399 567
400 // Write a null-terminated string to to the log file currently opened. 568 // Write a null-terminated string to to the log file currently opened.
401 void LogMessageBuilder::WriteCStringToLogFile(const char* str) { 569 void LogMessageBuilder::WriteCStringToLogFile(const char* str) {
402 size_t len = strlen(str); 570 int len = strlen(str);
403 size_t rv = fwrite(str, 1, len, Logger::logfile_); 571 Log::Write(str, len);
404 ASSERT(rv == len);
405 USE(rv);
406 } 572 }
407 #endif 573 #endif
408 574
409 575
410 // 576 //
411 // Logger class implementation. 577 // Logger class implementation.
412 // 578 //
413 Ticker* Logger::ticker_ = NULL; 579 Ticker* Logger::ticker_ = NULL;
414 char* Logger::message_buffer_ = NULL;
415 FILE* Logger::logfile_ = NULL;
416 Profiler* Logger::profiler_ = NULL; 580 Profiler* Logger::profiler_ = NULL;
417 Mutex* Logger::mutex_ = NULL;
418 VMState* Logger::current_state_ = NULL; 581 VMState* Logger::current_state_ = NULL;
419 VMState Logger::bottom_state_(EXTERNAL); 582 VMState Logger::bottom_state_(EXTERNAL);
420 SlidingStateWindow* Logger::sliding_state_window_ = NULL; 583 SlidingStateWindow* Logger::sliding_state_window_ = NULL;
421 584
585
586 bool Logger::is_enabled() {
587 return Log::is_enabled();
588 }
589
422 #endif // ENABLE_LOGGING_AND_PROFILING 590 #endif // ENABLE_LOGGING_AND_PROFILING
423 591
424 592
425 void Logger::Preamble(const char* content) { 593 void Logger::Preamble(const char* content) {
426 #ifdef ENABLE_LOGGING_AND_PROFILING 594 #ifdef ENABLE_LOGGING_AND_PROFILING
427 if (logfile_ == NULL || !FLAG_log_code) return; 595 if (!Log::is_enabled() || !FLAG_log_code) return;
428 LogMessageBuilder msg; 596 LogMessageBuilder msg;
429 msg.WriteCStringToLogFile(content); 597 msg.WriteCStringToLogFile(content);
430 #endif 598 #endif
431 } 599 }
432 600
433 601
434 void Logger::StringEvent(const char* name, const char* value) { 602 void Logger::StringEvent(const char* name, const char* value) {
435 #ifdef ENABLE_LOGGING_AND_PROFILING 603 #ifdef ENABLE_LOGGING_AND_PROFILING
436 if (FLAG_log) UncheckedStringEvent(name, value); 604 if (FLAG_log) UncheckedStringEvent(name, value);
437 #endif 605 #endif
438 } 606 }
439 607
440 608
441 #ifdef ENABLE_LOGGING_AND_PROFILING 609 #ifdef ENABLE_LOGGING_AND_PROFILING
442 void Logger::UncheckedStringEvent(const char* name, const char* value) { 610 void Logger::UncheckedStringEvent(const char* name, const char* value) {
443 if (logfile_ == NULL) return; 611 if (!Log::is_enabled()) return;
444 LogMessageBuilder msg; 612 LogMessageBuilder msg;
445 msg.Append("%s,\"%s\"\n", name, value); 613 msg.Append("%s,\"%s\"\n", name, value);
446 msg.WriteToLogFile(); 614 msg.WriteToLogFile();
447 } 615 }
448 #endif 616 #endif
449 617
450 618
451 void Logger::IntEvent(const char* name, int value) { 619 void Logger::IntEvent(const char* name, int value) {
452 #ifdef ENABLE_LOGGING_AND_PROFILING 620 #ifdef ENABLE_LOGGING_AND_PROFILING
453 if (logfile_ == NULL || !FLAG_log) return; 621 if (!Log::is_enabled() || !FLAG_log) return;
454 LogMessageBuilder msg; 622 LogMessageBuilder msg;
455 msg.Append("%s,%d\n", name, value); 623 msg.Append("%s,%d\n", name, value);
456 msg.WriteToLogFile(); 624 msg.WriteToLogFile();
457 #endif 625 #endif
458 } 626 }
459 627
460 628
461 void Logger::HandleEvent(const char* name, Object** location) { 629 void Logger::HandleEvent(const char* name, Object** location) {
462 #ifdef ENABLE_LOGGING_AND_PROFILING 630 #ifdef ENABLE_LOGGING_AND_PROFILING
463 if (logfile_ == NULL || !FLAG_log_handles) return; 631 if (!Log::is_enabled() || !FLAG_log_handles) return;
464 LogMessageBuilder msg; 632 LogMessageBuilder msg;
465 msg.Append("%s,0x%x\n", name, 633 msg.Append("%s,0x%x\n", name,
466 reinterpret_cast<unsigned int>(location)); 634 reinterpret_cast<unsigned int>(location));
467 msg.WriteToLogFile(); 635 msg.WriteToLogFile();
468 #endif 636 #endif
469 } 637 }
470 638
471 639
472 #ifdef ENABLE_LOGGING_AND_PROFILING 640 #ifdef ENABLE_LOGGING_AND_PROFILING
473 // ApiEvent is private so all the calls come from the Logger class. It is the 641 // ApiEvent is private so all the calls come from the Logger class. It is the
474 // caller's responsibility to ensure that logfile_ is not NULL and that 642 // caller's responsibility to ensure that log is enabled and that
475 // FLAG_log_api is true. 643 // FLAG_log_api is true.
476 void Logger::ApiEvent(const char* format, ...) { 644 void Logger::ApiEvent(const char* format, ...) {
477 ASSERT(logfile_ != NULL && FLAG_log_api); 645 ASSERT(Log::is_enabled() && FLAG_log_api);
478 LogMessageBuilder msg; 646 LogMessageBuilder msg;
479 va_list ap; 647 va_list ap;
480 va_start(ap, format); 648 va_start(ap, format);
481 msg.Append(format, ap); 649 msg.Append(format, ap);
482 va_end(ap); 650 va_end(ap);
483 msg.WriteToLogFile(); 651 msg.WriteToLogFile();
484 } 652 }
485 #endif 653 #endif
486 654
487 655
488 void Logger::ApiNamedSecurityCheck(Object* key) { 656 void Logger::ApiNamedSecurityCheck(Object* key) {
489 #ifdef ENABLE_LOGGING_AND_PROFILING 657 #ifdef ENABLE_LOGGING_AND_PROFILING
490 if (logfile_ == NULL || !FLAG_log_api) return; 658 if (!Log::is_enabled() || !FLAG_log_api) return;
491 if (key->IsString()) { 659 if (key->IsString()) {
492 SmartPointer<char> str = 660 SmartPointer<char> str =
493 String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 661 String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
494 ApiEvent("api,check-security,\"%s\"\n", *str); 662 ApiEvent("api,check-security,\"%s\"\n", *str);
495 } else if (key->IsUndefined()) { 663 } else if (key->IsUndefined()) {
496 ApiEvent("api,check-security,undefined\n"); 664 ApiEvent("api,check-security,undefined\n");
497 } else { 665 } else {
498 ApiEvent("api,check-security,['no-name']\n"); 666 ApiEvent("api,check-security,['no-name']\n");
499 } 667 }
500 #endif 668 #endif
501 } 669 }
502 670
503 671
504 void Logger::SharedLibraryEvent(const char* library_path, 672 void Logger::SharedLibraryEvent(const char* library_path,
505 unsigned start, 673 unsigned start,
506 unsigned end) { 674 unsigned end) {
507 #ifdef ENABLE_LOGGING_AND_PROFILING 675 #ifdef ENABLE_LOGGING_AND_PROFILING
508 if (logfile_ == NULL || !FLAG_prof) return; 676 if (!Log::is_enabled() || !FLAG_prof) return;
509 LogMessageBuilder msg; 677 LogMessageBuilder msg;
510 msg.Append("shared-library,\"%s\",0x%08x,0x%08x\n", library_path, 678 msg.Append("shared-library,\"%s\",0x%08x,0x%08x\n", library_path,
511 start, end); 679 start, end);
512 msg.WriteToLogFile(); 680 msg.WriteToLogFile();
513 #endif 681 #endif
514 } 682 }
515 683
516 684
517 void Logger::SharedLibraryEvent(const wchar_t* library_path, 685 void Logger::SharedLibraryEvent(const wchar_t* library_path,
518 unsigned start, 686 unsigned start,
519 unsigned end) { 687 unsigned end) {
520 #ifdef ENABLE_LOGGING_AND_PROFILING 688 #ifdef ENABLE_LOGGING_AND_PROFILING
521 if (logfile_ == NULL || !FLAG_prof) return; 689 if (!Log::is_enabled() || !FLAG_prof) return;
522 LogMessageBuilder msg; 690 LogMessageBuilder msg;
523 msg.Append("shared-library,\"%ls\",0x%08x,0x%08x\n", library_path, 691 msg.Append("shared-library,\"%ls\",0x%08x,0x%08x\n", library_path,
524 start, end); 692 start, end);
525 msg.WriteToLogFile(); 693 msg.WriteToLogFile();
526 #endif 694 #endif
527 } 695 }
528 696
529 697
530 #ifdef ENABLE_LOGGING_AND_PROFILING 698 #ifdef ENABLE_LOGGING_AND_PROFILING
531 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) { 699 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 msg.Append('m'); 734 msg.Append('m');
567 } 735 }
568 736
569 msg.WriteToLogFile(); 737 msg.WriteToLogFile();
570 } 738 }
571 #endif // ENABLE_LOGGING_AND_PROFILING 739 #endif // ENABLE_LOGGING_AND_PROFILING
572 740
573 741
574 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) { 742 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
575 #ifdef ENABLE_LOGGING_AND_PROFILING 743 #ifdef ENABLE_LOGGING_AND_PROFILING
576 if (logfile_ == NULL || !FLAG_log_regexp) return; 744 if (!Log::is_enabled() || !FLAG_log_regexp) return;
577 LogMessageBuilder msg; 745 LogMessageBuilder msg;
578 msg.Append("regexp-compile,"); 746 msg.Append("regexp-compile,");
579 LogRegExpSource(regexp); 747 LogRegExpSource(regexp);
580 msg.Append(in_cache ? ",hit\n" : ",miss\n"); 748 msg.Append(in_cache ? ",hit\n" : ",miss\n");
581 msg.WriteToLogFile(); 749 msg.WriteToLogFile();
582 #endif 750 #endif
583 } 751 }
584 752
585 753
586 void Logger::LogRuntime(Vector<const char> format, JSArray* args) { 754 void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
587 #ifdef ENABLE_LOGGING_AND_PROFILING 755 #ifdef ENABLE_LOGGING_AND_PROFILING
588 if (logfile_ == NULL || !FLAG_log_runtime) return; 756 if (!Log::is_enabled() || !FLAG_log_runtime) return;
589 HandleScope scope; 757 HandleScope scope;
590 LogMessageBuilder msg; 758 LogMessageBuilder msg;
591 for (int i = 0; i < format.length(); i++) { 759 for (int i = 0; i < format.length(); i++) {
592 char c = format[i]; 760 char c = format[i];
593 if (c == '%' && i <= format.length() - 2) { 761 if (c == '%' && i <= format.length() - 2) {
594 i++; 762 i++;
595 ASSERT('0' <= format[i] && format[i] <= '9'); 763 ASSERT('0' <= format[i] && format[i] <= '9');
596 Object* obj = args->GetElement(format[i] - '0'); 764 Object* obj = args->GetElement(format[i] - '0');
597 i++; 765 i++;
598 switch (format[i]) { 766 switch (format[i]) {
(...skipping 20 matching lines...) Expand all
619 } 787 }
620 } 788 }
621 msg.Append('\n'); 789 msg.Append('\n');
622 msg.WriteToLogFile(); 790 msg.WriteToLogFile();
623 #endif 791 #endif
624 } 792 }
625 793
626 794
627 void Logger::ApiIndexedSecurityCheck(uint32_t index) { 795 void Logger::ApiIndexedSecurityCheck(uint32_t index) {
628 #ifdef ENABLE_LOGGING_AND_PROFILING 796 #ifdef ENABLE_LOGGING_AND_PROFILING
629 if (logfile_ == NULL || !FLAG_log_api) return; 797 if (!Log::is_enabled() || !FLAG_log_api) return;
630 ApiEvent("api,check-security,%u\n", index); 798 ApiEvent("api,check-security,%u\n", index);
631 #endif 799 #endif
632 } 800 }
633 801
634 802
635 void Logger::ApiNamedPropertyAccess(const char* tag, 803 void Logger::ApiNamedPropertyAccess(const char* tag,
636 JSObject* holder, 804 JSObject* holder,
637 Object* name) { 805 Object* name) {
638 #ifdef ENABLE_LOGGING_AND_PROFILING 806 #ifdef ENABLE_LOGGING_AND_PROFILING
639 ASSERT(name->IsString()); 807 ASSERT(name->IsString());
640 if (logfile_ == NULL || !FLAG_log_api) return; 808 if (!Log::is_enabled() || !FLAG_log_api) return;
641 String* class_name_obj = holder->class_name(); 809 String* class_name_obj = holder->class_name();
642 SmartPointer<char> class_name = 810 SmartPointer<char> class_name =
643 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 811 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
644 SmartPointer<char> property_name = 812 SmartPointer<char> property_name =
645 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 813 String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
646 Logger::ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name); 814 Logger::ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
647 #endif 815 #endif
648 } 816 }
649 817
650 void Logger::ApiIndexedPropertyAccess(const char* tag, 818 void Logger::ApiIndexedPropertyAccess(const char* tag,
651 JSObject* holder, 819 JSObject* holder,
652 uint32_t index) { 820 uint32_t index) {
653 #ifdef ENABLE_LOGGING_AND_PROFILING 821 #ifdef ENABLE_LOGGING_AND_PROFILING
654 if (logfile_ == NULL || !FLAG_log_api) return; 822 if (!Log::is_enabled() || !FLAG_log_api) return;
655 String* class_name_obj = holder->class_name(); 823 String* class_name_obj = holder->class_name();
656 SmartPointer<char> class_name = 824 SmartPointer<char> class_name =
657 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 825 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
658 Logger::ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index); 826 Logger::ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
659 #endif 827 #endif
660 } 828 }
661 829
662 void Logger::ApiObjectAccess(const char* tag, JSObject* object) { 830 void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
663 #ifdef ENABLE_LOGGING_AND_PROFILING 831 #ifdef ENABLE_LOGGING_AND_PROFILING
664 if (logfile_ == NULL || !FLAG_log_api) return; 832 if (!Log::is_enabled() || !FLAG_log_api) return;
665 String* class_name_obj = object->class_name(); 833 String* class_name_obj = object->class_name();
666 SmartPointer<char> class_name = 834 SmartPointer<char> class_name =
667 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 835 class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
668 Logger::ApiEvent("api,%s,\"%s\"\n", tag, *class_name); 836 Logger::ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
669 #endif 837 #endif
670 } 838 }
671 839
672 840
673 void Logger::ApiEntryCall(const char* name) { 841 void Logger::ApiEntryCall(const char* name) {
674 #ifdef ENABLE_LOGGING_AND_PROFILING 842 #ifdef ENABLE_LOGGING_AND_PROFILING
675 if (logfile_ == NULL || !FLAG_log_api) return; 843 if (!Log::is_enabled() || !FLAG_log_api) return;
676 Logger::ApiEvent("api,%s\n", name); 844 Logger::ApiEvent("api,%s\n", name);
677 #endif 845 #endif
678 } 846 }
679 847
680 848
681 void Logger::NewEvent(const char* name, void* object, size_t size) { 849 void Logger::NewEvent(const char* name, void* object, size_t size) {
682 #ifdef ENABLE_LOGGING_AND_PROFILING 850 #ifdef ENABLE_LOGGING_AND_PROFILING
683 if (logfile_ == NULL || !FLAG_log) return; 851 if (!Log::is_enabled() || !FLAG_log) return;
684 LogMessageBuilder msg; 852 LogMessageBuilder msg;
685 msg.Append("new,%s,0x%x,%u\n", name, 853 msg.Append("new,%s,0x%x,%u\n", name,
686 reinterpret_cast<unsigned int>(object), 854 reinterpret_cast<unsigned int>(object),
687 static_cast<unsigned int>(size)); 855 static_cast<unsigned int>(size));
688 msg.WriteToLogFile(); 856 msg.WriteToLogFile();
689 #endif 857 #endif
690 } 858 }
691 859
692 860
693 void Logger::DeleteEvent(const char* name, void* object) { 861 void Logger::DeleteEvent(const char* name, void* object) {
694 #ifdef ENABLE_LOGGING_AND_PROFILING 862 #ifdef ENABLE_LOGGING_AND_PROFILING
695 if (logfile_ == NULL || !FLAG_log) return; 863 if (!Log::is_enabled() || !FLAG_log) return;
696 LogMessageBuilder msg; 864 LogMessageBuilder msg;
697 msg.Append("delete,%s,0x%x\n", name, 865 msg.Append("delete,%s,0x%x\n", name,
698 reinterpret_cast<unsigned int>(object)); 866 reinterpret_cast<unsigned int>(object));
699 msg.WriteToLogFile(); 867 msg.WriteToLogFile();
700 #endif 868 #endif
701 } 869 }
702 870
703 871
704 void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) { 872 void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) {
705 #ifdef ENABLE_LOGGING_AND_PROFILING 873 #ifdef ENABLE_LOGGING_AND_PROFILING
706 if (logfile_ == NULL || !FLAG_log_code) return; 874 if (!Log::is_enabled() || !FLAG_log_code) return;
707 LogMessageBuilder msg; 875 LogMessageBuilder msg;
708 msg.Append("code-creation,%s,0x%x,%d,\"", tag, 876 msg.Append("code-creation,%s,0x%x,%d,\"", tag,
709 reinterpret_cast<unsigned int>(code->address()), 877 reinterpret_cast<unsigned int>(code->address()),
710 code->ExecutableSize()); 878 code->ExecutableSize());
711 for (const char* p = comment; *p != '\0'; p++) { 879 for (const char* p = comment; *p != '\0'; p++) {
712 if (*p == '"') { 880 if (*p == '"') {
713 msg.Append('\\'); 881 msg.Append('\\');
714 } 882 }
715 msg.Append(*p); 883 msg.Append(*p);
716 } 884 }
717 msg.Append('"'); 885 msg.Append('"');
718 msg.Append('\n'); 886 msg.Append('\n');
719 msg.WriteToLogFile(); 887 msg.WriteToLogFile();
720 #endif 888 #endif
721 } 889 }
722 890
723 891
724 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name) { 892 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name) {
725 #ifdef ENABLE_LOGGING_AND_PROFILING 893 #ifdef ENABLE_LOGGING_AND_PROFILING
726 if (logfile_ == NULL || !FLAG_log_code) return; 894 if (!Log::is_enabled() || !FLAG_log_code) return;
727 LogMessageBuilder msg; 895 LogMessageBuilder msg;
728 SmartPointer<char> str = 896 SmartPointer<char> str =
729 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 897 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
730 msg.Append("code-creation,%s,0x%x,%d,\"%s\"\n", tag, 898 msg.Append("code-creation,%s,0x%x,%d,\"%s\"\n", tag,
731 reinterpret_cast<unsigned int>(code->address()), 899 reinterpret_cast<unsigned int>(code->address()),
732 code->ExecutableSize(), *str); 900 code->ExecutableSize(), *str);
733 msg.WriteToLogFile(); 901 msg.WriteToLogFile();
734 #endif 902 #endif
735 } 903 }
736 904
737 905
738 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name, 906 void Logger::CodeCreateEvent(const char* tag, Code* code, String* name,
739 String* source, int line) { 907 String* source, int line) {
740 #ifdef ENABLE_LOGGING_AND_PROFILING 908 #ifdef ENABLE_LOGGING_AND_PROFILING
741 if (logfile_ == NULL || !FLAG_log_code) return; 909 if (!Log::is_enabled() || !FLAG_log_code) return;
742 LogMessageBuilder msg; 910 LogMessageBuilder msg;
743 SmartPointer<char> str = 911 SmartPointer<char> str =
744 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 912 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
745 SmartPointer<char> sourcestr = 913 SmartPointer<char> sourcestr =
746 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 914 source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
747 msg.Append("code-creation,%s,0x%x,%d,\"%s %s:%d\"\n", tag, 915 msg.Append("code-creation,%s,0x%x,%d,\"%s %s:%d\"\n", tag,
748 reinterpret_cast<unsigned int>(code->address()), 916 reinterpret_cast<unsigned int>(code->address()),
749 code->ExecutableSize(), 917 code->ExecutableSize(),
750 *str, *sourcestr, line); 918 *str, *sourcestr, line);
751 msg.WriteToLogFile(); 919 msg.WriteToLogFile();
752 #endif 920 #endif
753 } 921 }
754 922
755 923
756 void Logger::CodeCreateEvent(const char* tag, Code* code, int args_count) { 924 void Logger::CodeCreateEvent(const char* tag, Code* code, int args_count) {
757 #ifdef ENABLE_LOGGING_AND_PROFILING 925 #ifdef ENABLE_LOGGING_AND_PROFILING
758 if (logfile_ == NULL || !FLAG_log_code) return; 926 if (!Log::is_enabled() || !FLAG_log_code) return;
759 LogMessageBuilder msg; 927 LogMessageBuilder msg;
760 msg.Append("code-creation,%s,0x%x,%d,\"args_count: %d\"\n", tag, 928 msg.Append("code-creation,%s,0x%x,%d,\"args_count: %d\"\n", tag,
761 reinterpret_cast<unsigned int>(code->address()), 929 reinterpret_cast<unsigned int>(code->address()),
762 code->ExecutableSize(), 930 code->ExecutableSize(),
763 args_count); 931 args_count);
764 msg.WriteToLogFile(); 932 msg.WriteToLogFile();
765 #endif 933 #endif
766 } 934 }
767 935
768 936
769 void Logger::RegExpCodeCreateEvent(Code* code, String* source) { 937 void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
770 #ifdef ENABLE_LOGGING_AND_PROFILING 938 #ifdef ENABLE_LOGGING_AND_PROFILING
771 if (logfile_ == NULL || !FLAG_log_code) return; 939 if (!Log::is_enabled() || !FLAG_log_code) return;
772 LogMessageBuilder msg; 940 LogMessageBuilder msg;
773 msg.Append("code-creation,%s,0x%x,%d,\"", "RegExp", 941 msg.Append("code-creation,%s,0x%x,%d,\"", "RegExp",
774 reinterpret_cast<unsigned int>(code->address()), 942 reinterpret_cast<unsigned int>(code->address()),
775 code->ExecutableSize()); 943 code->ExecutableSize());
776 msg.AppendDetailed(source, false); 944 msg.AppendDetailed(source, false);
777 msg.Append("\"\n"); 945 msg.Append("\"\n");
778 msg.WriteToLogFile(); 946 msg.WriteToLogFile();
779 #endif 947 #endif
780 } 948 }
781 949
782 950
783 void Logger::CodeAllocateEvent(Code* code, Assembler* assem) { 951 void Logger::CodeAllocateEvent(Code* code, Assembler* assem) {
784 #ifdef ENABLE_LOGGING_AND_PROFILING 952 #ifdef ENABLE_LOGGING_AND_PROFILING
785 if (logfile_ == NULL || !FLAG_log_code) return; 953 if (!Log::is_enabled() || !FLAG_log_code) return;
786 LogMessageBuilder msg; 954 LogMessageBuilder msg;
787 msg.Append("code-allocate,0x%x,0x%x\n", 955 msg.Append("code-allocate,0x%x,0x%x\n",
788 reinterpret_cast<unsigned int>(code->address()), 956 reinterpret_cast<unsigned int>(code->address()),
789 reinterpret_cast<unsigned int>(assem)); 957 reinterpret_cast<unsigned int>(assem));
790 msg.WriteToLogFile(); 958 msg.WriteToLogFile();
791 #endif 959 #endif
792 } 960 }
793 961
794 962
795 void Logger::CodeMoveEvent(Address from, Address to) { 963 void Logger::CodeMoveEvent(Address from, Address to) {
796 #ifdef ENABLE_LOGGING_AND_PROFILING 964 #ifdef ENABLE_LOGGING_AND_PROFILING
797 if (logfile_ == NULL || !FLAG_log_code) return; 965 if (!Log::is_enabled() || !FLAG_log_code) return;
798 LogMessageBuilder msg; 966 LogMessageBuilder msg;
799 msg.Append("code-move,0x%x,0x%x\n", 967 msg.Append("code-move,0x%x,0x%x\n",
800 reinterpret_cast<unsigned int>(from), 968 reinterpret_cast<unsigned int>(from),
801 reinterpret_cast<unsigned int>(to)); 969 reinterpret_cast<unsigned int>(to));
802 msg.WriteToLogFile(); 970 msg.WriteToLogFile();
803 #endif 971 #endif
804 } 972 }
805 973
806 974
807 void Logger::CodeDeleteEvent(Address from) { 975 void Logger::CodeDeleteEvent(Address from) {
808 #ifdef ENABLE_LOGGING_AND_PROFILING 976 #ifdef ENABLE_LOGGING_AND_PROFILING
809 if (logfile_ == NULL || !FLAG_log_code) return; 977 if (!Log::is_enabled() || !FLAG_log_code) return;
810 LogMessageBuilder msg; 978 LogMessageBuilder msg;
811 msg.Append("code-delete,0x%x\n", reinterpret_cast<unsigned int>(from)); 979 msg.Append("code-delete,0x%x\n", reinterpret_cast<unsigned int>(from));
812 msg.WriteToLogFile(); 980 msg.WriteToLogFile();
813 #endif 981 #endif
814 } 982 }
815 983
816 984
817 void Logger::ResourceEvent(const char* name, const char* tag) { 985 void Logger::ResourceEvent(const char* name, const char* tag) {
818 #ifdef ENABLE_LOGGING_AND_PROFILING 986 #ifdef ENABLE_LOGGING_AND_PROFILING
819 if (logfile_ == NULL || !FLAG_log) return; 987 if (!Log::is_enabled() || !FLAG_log) return;
820 LogMessageBuilder msg; 988 LogMessageBuilder msg;
821 msg.Append("%s,%s,", name, tag); 989 msg.Append("%s,%s,", name, tag);
822 990
823 uint32_t sec, usec; 991 uint32_t sec, usec;
824 if (OS::GetUserTime(&sec, &usec) != -1) { 992 if (OS::GetUserTime(&sec, &usec) != -1) {
825 msg.Append("%d,%d,", sec, usec); 993 msg.Append("%d,%d,", sec, usec);
826 } 994 }
827 msg.Append("%.0f", OS::TimeCurrentMillis()); 995 msg.Append("%.0f", OS::TimeCurrentMillis());
828 996
829 msg.Append('\n'); 997 msg.Append('\n');
830 msg.WriteToLogFile(); 998 msg.WriteToLogFile();
831 #endif 999 #endif
832 } 1000 }
833 1001
834 1002
835 void Logger::SuspectReadEvent(String* name, Object* obj) { 1003 void Logger::SuspectReadEvent(String* name, Object* obj) {
836 #ifdef ENABLE_LOGGING_AND_PROFILING 1004 #ifdef ENABLE_LOGGING_AND_PROFILING
837 if (logfile_ == NULL || !FLAG_log_suspect) return; 1005 if (!Log::is_enabled() || !FLAG_log_suspect) return;
838 LogMessageBuilder msg; 1006 LogMessageBuilder msg;
839 String* class_name = obj->IsJSObject() 1007 String* class_name = obj->IsJSObject()
840 ? JSObject::cast(obj)->class_name() 1008 ? JSObject::cast(obj)->class_name()
841 : Heap::empty_string(); 1009 : Heap::empty_string();
842 ScopedLock sl(mutex_);
843 msg.Append("suspect-read,"); 1010 msg.Append("suspect-read,");
844 msg.Append(class_name); 1011 msg.Append(class_name);
845 msg.Append(','); 1012 msg.Append(',');
846 msg.Append('"'); 1013 msg.Append('"');
847 msg.Append(name); 1014 msg.Append(name);
848 msg.Append('"'); 1015 msg.Append('"');
849 msg.Append('\n'); 1016 msg.Append('\n');
850 msg.WriteToLogFile(); 1017 msg.WriteToLogFile();
851 #endif 1018 #endif
852 } 1019 }
853 1020
854 1021
855 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) { 1022 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
856 #ifdef ENABLE_LOGGING_AND_PROFILING 1023 #ifdef ENABLE_LOGGING_AND_PROFILING
857 if (logfile_ == NULL || !FLAG_log_gc) return; 1024 if (!Log::is_enabled() || !FLAG_log_gc) return;
858 LogMessageBuilder msg; 1025 LogMessageBuilder msg;
859 msg.Append("heap-sample-begin,\"%s\",\"%s\"\n", space, kind); 1026 msg.Append("heap-sample-begin,\"%s\",\"%s\"\n", space, kind);
860 msg.WriteToLogFile(); 1027 msg.WriteToLogFile();
861 #endif 1028 #endif
862 } 1029 }
863 1030
864 1031
865 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { 1032 void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
866 #ifdef ENABLE_LOGGING_AND_PROFILING 1033 #ifdef ENABLE_LOGGING_AND_PROFILING
867 if (logfile_ == NULL || !FLAG_log_gc) return; 1034 if (!Log::is_enabled() || !FLAG_log_gc) return;
868 LogMessageBuilder msg; 1035 LogMessageBuilder msg;
869 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); 1036 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
870 msg.WriteToLogFile(); 1037 msg.WriteToLogFile();
871 #endif 1038 #endif
872 } 1039 }
873 1040
874 1041
875 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { 1042 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
876 #ifdef ENABLE_LOGGING_AND_PROFILING 1043 #ifdef ENABLE_LOGGING_AND_PROFILING
877 if (logfile_ == NULL || !FLAG_log_gc) return; 1044 if (!Log::is_enabled() || !FLAG_log_gc) return;
878 LogMessageBuilder msg; 1045 LogMessageBuilder msg;
879 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); 1046 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
880 msg.WriteToLogFile(); 1047 msg.WriteToLogFile();
881 #endif 1048 #endif
882 } 1049 }
883 1050
884 1051
885 void Logger::DebugTag(const char* call_site_tag) { 1052 void Logger::DebugTag(const char* call_site_tag) {
886 #ifdef ENABLE_LOGGING_AND_PROFILING 1053 #ifdef ENABLE_LOGGING_AND_PROFILING
887 if (logfile_ == NULL || !FLAG_log) return; 1054 if (!Log::is_enabled() || !FLAG_log) return;
888 LogMessageBuilder msg; 1055 LogMessageBuilder msg;
889 msg.Append("debug-tag,%s\n", call_site_tag); 1056 msg.Append("debug-tag,%s\n", call_site_tag);
890 msg.WriteToLogFile(); 1057 msg.WriteToLogFile();
891 #endif 1058 #endif
892 } 1059 }
893 1060
894 1061
895 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) { 1062 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
896 #ifdef ENABLE_LOGGING_AND_PROFILING 1063 #ifdef ENABLE_LOGGING_AND_PROFILING
897 if (logfile_ == NULL || !FLAG_log) return; 1064 if (!Log::is_enabled() || !FLAG_log) return;
898 StringBuilder s(parameter.length() + 1); 1065 StringBuilder s(parameter.length() + 1);
899 for (int i = 0; i < parameter.length(); ++i) { 1066 for (int i = 0; i < parameter.length(); ++i) {
900 s.AddCharacter(static_cast<char>(parameter[i])); 1067 s.AddCharacter(static_cast<char>(parameter[i]));
901 } 1068 }
902 char* parameter_string = s.Finalize(); 1069 char* parameter_string = s.Finalize();
903 LogMessageBuilder msg; 1070 LogMessageBuilder msg;
904 msg.Append("debug-queue-event,%s,%15.3f,%s\n", 1071 msg.Append("debug-queue-event,%s,%15.3f,%s\n",
905 event_type, 1072 event_type,
906 OS::TimeCurrentMillis(), 1073 OS::TimeCurrentMillis(),
907 parameter_string); 1074 parameter_string);
908 DeleteArray(parameter_string); 1075 DeleteArray(parameter_string);
909 msg.WriteToLogFile(); 1076 msg.WriteToLogFile();
910 #endif 1077 #endif
911 } 1078 }
912 1079
913 1080
914 #ifdef ENABLE_LOGGING_AND_PROFILING 1081 #ifdef ENABLE_LOGGING_AND_PROFILING
915 void Logger::TickEvent(TickSample* sample, bool overflow) { 1082 void Logger::TickEvent(TickSample* sample, bool overflow) {
916 if (logfile_ == NULL || !FLAG_prof) return; 1083 if (!Log::is_enabled() || !FLAG_prof) return;
917 LogMessageBuilder msg; 1084 LogMessageBuilder msg;
918 msg.Append("tick,0x%x,0x%x,%d", sample->pc, sample->sp, 1085 msg.Append("tick,0x%x,0x%x,%d", sample->pc, sample->sp,
919 static_cast<int>(sample->state)); 1086 static_cast<int>(sample->state));
920 if (overflow) { 1087 if (overflow) {
921 msg.Append(",overflow"); 1088 msg.Append(",overflow");
922 } 1089 }
923 for (int i = 0; i < sample->frames_count; ++i) { 1090 for (int i = 0; i < sample->frames_count; ++i) {
924 msg.Append(",0x%x", reinterpret_cast<uint32_t>(sample->stack[i])); 1091 msg.Append(",0x%x", reinterpret_cast<uint32_t>(sample->stack[i]));
925 } 1092 }
926 msg.Append('\n'); 1093 msg.Append('\n');
927 msg.WriteToLogFile(); 1094 msg.WriteToLogFile();
928 } 1095 }
929 1096
930 1097
931 bool Logger::IsProfilerPaused() { 1098 bool Logger::IsProfilerPaused() {
932 return profiler_->paused(); 1099 return profiler_->paused();
933 } 1100 }
934 1101
935 1102
936 void Logger::PauseProfiler() { 1103 void Logger::PauseProfiler() {
937 profiler_->pause(); 1104 profiler_->pause();
938 } 1105 }
939 1106
940 1107
941 void Logger::ResumeProfiler() { 1108 void Logger::ResumeProfiler() {
942 profiler_->resume(); 1109 profiler_->resume();
943 } 1110 }
1111
1112
1113 int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
1114 return Log::GetLogLines(from_pos, dest_buf, max_size);
1115 }
1116
944 #endif 1117 #endif
945 1118
946 1119
947 bool Logger::Setup() { 1120 bool Logger::Setup() {
948 #ifdef ENABLE_LOGGING_AND_PROFILING 1121 #ifdef ENABLE_LOGGING_AND_PROFILING
949 // --log-all enables all the log flags. 1122 // --log-all enables all the log flags.
950 if (FLAG_log_all) { 1123 if (FLAG_log_all) {
951 FLAG_log_runtime = true; 1124 FLAG_log_runtime = true;
952 FLAG_log_api = true; 1125 FLAG_log_api = true;
953 FLAG_log_code = true; 1126 FLAG_log_code = true;
954 FLAG_log_gc = true; 1127 FLAG_log_gc = true;
955 FLAG_log_suspect = true; 1128 FLAG_log_suspect = true;
956 FLAG_log_handles = true; 1129 FLAG_log_handles = true;
957 FLAG_log_regexp = true; 1130 FLAG_log_regexp = true;
958 } 1131 }
959 1132
960 // --prof implies --log-code. 1133 // --prof implies --log-code.
961 if (FLAG_prof) FLAG_log_code = true; 1134 if (FLAG_prof) FLAG_log_code = true;
962 1135
963 bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api 1136 bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
964 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect 1137 || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
965 || FLAG_log_regexp || FLAG_log_state_changes; 1138 || FLAG_log_regexp || FLAG_log_state_changes;
966 1139
967 // If we're logging anything, we need to open the log file. 1140 // If we're logging anything, we need to open the log file.
968 if (open_log_file) { 1141 if (open_log_file) {
969 if (strcmp(FLAG_logfile, "-") == 0) { 1142 if (strcmp(FLAG_logfile, "-") == 0) {
970 logfile_ = stdout; 1143 Log::OpenStdout();
1144 } else if (strcmp(FLAG_logfile, "*") == 0) {
1145 Log::OpenMemoryBuffer();
971 } else if (strchr(FLAG_logfile, '%') != NULL) { 1146 } else if (strchr(FLAG_logfile, '%') != NULL) {
972 // If there's a '%' in the log file name we have to expand 1147 // If there's a '%' in the log file name we have to expand
973 // placeholders. 1148 // placeholders.
974 HeapStringAllocator allocator; 1149 HeapStringAllocator allocator;
975 StringStream stream(&allocator); 1150 StringStream stream(&allocator);
976 for (const char* p = FLAG_logfile; *p; p++) { 1151 for (const char* p = FLAG_logfile; *p; p++) {
977 if (*p == '%') { 1152 if (*p == '%') {
978 p++; 1153 p++;
979 switch (*p) { 1154 switch (*p) {
980 case '\0': 1155 case '\0':
(...skipping 15 matching lines...) Expand all
996 // All other %'s expand to themselves. 1171 // All other %'s expand to themselves.
997 stream.Put('%'); 1172 stream.Put('%');
998 stream.Put(*p); 1173 stream.Put(*p);
999 break; 1174 break;
1000 } 1175 }
1001 } else { 1176 } else {
1002 stream.Put(*p); 1177 stream.Put(*p);
1003 } 1178 }
1004 } 1179 }
1005 SmartPointer<const char> expanded = stream.ToCString(); 1180 SmartPointer<const char> expanded = stream.ToCString();
1006 logfile_ = OS::FOpen(*expanded, OS::LogFileOpenMode); 1181 Log::OpenFile(*expanded);
1007 } else { 1182 } else {
1008 logfile_ = OS::FOpen(FLAG_logfile, OS::LogFileOpenMode); 1183 Log::OpenFile(FLAG_logfile);
1009 } 1184 }
1010 message_buffer_ = NewArray<char>(kMessageBufferSize);
1011 mutex_ = OS::CreateMutex();
1012 } 1185 }
1013 1186
1014 current_state_ = &bottom_state_; 1187 current_state_ = &bottom_state_;
1015 1188
1016 // as log is initialized early with V8, we can assume that JS execution 1189 // as log is initialized early with V8, we can assume that JS execution
1017 // frames can never reach this point on stack 1190 // frames can never reach this point on stack
1018 int stack_var; 1191 int stack_var;
1019 ticker_ = new Ticker(1, reinterpret_cast<unsigned int>(&stack_var)); 1192 ticker_ = new Ticker(1, reinterpret_cast<unsigned int>(&stack_var));
1020 1193
1021 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) { 1194 if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
(...skipping 21 matching lines...) Expand all
1043 if (profiler_ != NULL) { 1216 if (profiler_ != NULL) {
1044 profiler_->Disengage(); 1217 profiler_->Disengage();
1045 delete profiler_; 1218 delete profiler_;
1046 profiler_ = NULL; 1219 profiler_ = NULL;
1047 } 1220 }
1048 1221
1049 delete sliding_state_window_; 1222 delete sliding_state_window_;
1050 1223
1051 delete ticker_; 1224 delete ticker_;
1052 1225
1053 if (logfile_ != NULL) { 1226 Log::Close();
1054 fclose(logfile_);
1055 logfile_ = NULL;
1056 delete mutex_;
1057 mutex_ = NULL;
1058 DeleteArray(message_buffer_);
1059 }
1060 #endif 1227 #endif
1061 } 1228 }
1062 1229
1063 1230
1064 void Logger::EnableSlidingStateWindow() { 1231 void Logger::EnableSlidingStateWindow() {
1065 #ifdef ENABLE_LOGGING_AND_PROFILING 1232 #ifdef ENABLE_LOGGING_AND_PROFILING
1066 // If the ticker is NULL, Logger::Setup has not been called yet. In 1233 // If the ticker is NULL, Logger::Setup has not been called yet. In
1067 // that case, we set the sliding_state_window flag so that the 1234 // that case, we set the sliding_state_window flag so that the
1068 // sliding window computation will be started when Logger::Setup is 1235 // sliding window computation will be started when Logger::Setup is
1069 // called. 1236 // called.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 } else if (previous_->state_ == EXTERNAL) { 1322 } else if (previous_->state_ == EXTERNAL) {
1156 // We are leaving V8. 1323 // We are leaving V8.
1157 Heap::Protect(); 1324 Heap::Protect();
1158 } 1325 }
1159 } 1326 }
1160 #endif 1327 #endif
1161 } 1328 }
1162 #endif 1329 #endif
1163 1330
1164 } } // namespace v8::internal 1331 } } // namespace v8::internal
OLDNEW
« include/v8.h ('K') | « src/log.h ('k') | test/cctest/SConscript » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698