Chromium Code Reviews| Index: src/log.cc |
| diff --git a/src/log.cc b/src/log.cc |
| index 3ce207229a515ea8bbafa6b99da9fcf184db4b5e..7331e7a07b58373180f9e55ab5c51e4be29934b9 100644 |
| --- a/src/log.cc |
| +++ b/src/log.cc |
| @@ -334,10 +334,119 @@ void Profiler::Run() { |
| } |
| +// Low-level profiling event structures. |
| + |
| +struct LowLevelCodeCreateStruct { |
| + static const char kTag = 'C'; |
| + |
| + int32_t name_size; |
| + Address code_address; |
| + int32_t code_size; |
| +}; |
| + |
| + |
| +struct LowLevelCodeMoveStruct { |
| + static const char kTag = 'M'; |
| + |
| + Address from_address; |
| + Address to_address; |
| +}; |
| + |
| + |
| +struct LowLevelCodeDeleteStruct { |
| + static const char kTag = 'D'; |
| + |
| + Address address; |
| +}; |
| + |
| + |
| +struct LowLevelSnapshotPositionStruct { |
| + static const char kTag = 'P'; |
| + |
| + Address address; |
| + int32_t position; |
| +}; |
| + |
| + |
| +static const char kCodeMovingGCTag = 'G'; |
| + |
| + |
| // |
| // Logger class implementation. |
| // |
| +class Logger::NameBuffer { |
| + public: |
| + NameBuffer() { Reset(); } |
| + |
| + void Reset() { |
| + utf8_pos_ = 0; |
| + } |
| + |
| + void AppendString(String* str) { |
| + if (str == NULL) return; |
| + if (str->HasOnlyAsciiChars()) { |
| + int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_); |
| + String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length); |
| + utf8_pos_ += utf8_length; |
| + return; |
| + } |
| + int uc16_length = Min(str->length(), kUc16BufferSize); |
| + String::WriteToFlat(str, uc16_buffer_, 0, uc16_length); |
| + for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) { |
| + uc16 c = uc16_buffer_[i]; |
| + if (c <= String::kMaxAsciiCharCodeU) { |
| + utf8_buffer_[utf8_pos_++] = c; |
| + } else { |
| + int char_length = unibrow::Utf8::Length(c); |
| + if (utf8_pos_ + char_length > kUtf8BufferSize) break; |
| + unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c); |
| + utf8_pos_ += char_length; |
| + } |
| + } |
| + } |
| + |
| + void AppendBytes(const char* bytes, int size) { |
| + size = Min(size, kUtf8BufferSize - utf8_pos_); |
| + memcpy(utf8_buffer_ + utf8_pos_, bytes, size); |
| + utf8_pos_ += size; |
| + } |
| + |
| + void AppendBytes(const char* bytes) { |
| + AppendBytes(bytes, StrLength(bytes)); |
| + } |
| + |
| + void AppendByte(char c) { |
| + if (utf8_pos_ >= kUtf8BufferSize) return; |
| + utf8_buffer_[utf8_pos_++] = c; |
| + } |
| + |
| + void AppendInt(int n) { |
| + Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_); |
| + int size = OS::SNPrintF(buffer, "%d", n); |
| + if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) { |
| + utf8_pos_ += size; |
| + } |
| + } |
| + |
| + const char* get() { return utf8_buffer_; } |
| + int size() const { return utf8_pos_; } |
| + |
| + private: |
| + static const int kUtf8BufferSize = 512; |
| + static const int kUc16BufferSize = 128; |
| + |
| + int utf8_pos_; |
| + char utf8_buffer_[kUtf8BufferSize]; |
| + uc16 uc16_buffer_[kUc16BufferSize]; |
| +}; |
| + |
| + |
| +static bool PointerEquals(void* lhs, void* rhs) { |
| + return lhs == rhs; |
| +} |
| + |
| + |
| Logger::Logger() |
| : ticker_(NULL), |
| profiler_(NULL), |
| @@ -347,6 +456,8 @@ Logger::Logger() |
| cpu_profiler_nesting_(0), |
| heap_profiler_nesting_(0), |
| log_(new Log(this)), |
| + name_buffer_(new NameBuffer), |
| + address_to_name_map_(NULL), |
| is_initialized_(false), |
| last_address_(NULL), |
| prev_sp_(NULL), |
| @@ -355,10 +466,21 @@ Logger::Logger() |
| prev_code_(NULL) { |
| } |
| + |
| Logger::~Logger() { |
| + if (address_to_name_map_ != NULL) { |
| + for (HashMap::Entry* p = address_to_name_map_->Start(); |
| + p != NULL; |
| + p = address_to_name_map_->Next(p)) { |
| + DeleteArray(static_cast<const char*>(p->value)); |
| + } |
| + delete address_to_name_map_; |
| + } |
| + delete name_buffer_; |
| delete log_; |
| } |
| + |
| #define DECLARE_EVENT(ignore1, name) name, |
| static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = { |
| LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT) |
| @@ -735,7 +857,20 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| Code* code, |
| const char* comment) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendBytes(comment); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (!FLAG_log_code) return; |
| LogMessageBuilder msg(this); |
| msg.Append("%s,%s,", |
| kLogEventsNames[CODE_CREATION_EVENT], |
| @@ -749,7 +884,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| msg.Append(*p); |
| } |
| msg.Append('"'); |
| - LowLevelCodeCreateEvent(code, &msg); |
| msg.Append('\n'); |
| msg.WriteToLogFile(); |
| #endif |
| @@ -760,13 +894,30 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| Code* code, |
| String* name) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (name != NULL) { |
| - SmartPointer<char> str = |
| - name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| - CodeCreateEvent(tag, code, *str); |
| - } else { |
| - CodeCreateEvent(tag, code, ""); |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendString(name); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| } |
| + if (!FLAG_log_code) return; |
| + LogMessageBuilder msg(this); |
| + msg.Append("%s,%s,", |
| + kLogEventsNames[CODE_CREATION_EVENT], |
| + kLogEventsNames[tag]); |
| + msg.AppendAddress(code->address()); |
| + msg.Append(",%d,\"", code->ExecutableSize()); |
| + msg.AppendDetailed(name, false); |
| + msg.Append('"'); |
| + msg.Append('\n'); |
| + msg.WriteToLogFile(); |
| #endif |
| } |
| @@ -788,7 +939,20 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| SharedFunctionInfo* shared, |
| String* name) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendString(name); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (!FLAG_log_code) return; |
| if (code == Isolate::Current()->builtins()->builtin( |
| Builtins::kLazyCompile)) |
| return; |
| @@ -803,7 +967,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str); |
| msg.AppendAddress(shared->address()); |
| msg.Append(",%s", ComputeMarker(code)); |
| - LowLevelCodeCreateEvent(code, &msg); |
| msg.Append('\n'); |
| msg.WriteToLogFile(); |
| #endif |
| @@ -818,7 +981,24 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| SharedFunctionInfo* shared, |
| String* source, int line) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendString(shared->DebugName()); |
| + name_buffer_->AppendByte(' '); |
| + name_buffer_->AppendString(source); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendInt(line); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (!FLAG_log_code) return; |
| LogMessageBuilder msg(this); |
| SmartPointer<char> name = |
| shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| @@ -835,7 +1015,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| line); |
| msg.AppendAddress(shared->address()); |
| msg.Append(",%s", ComputeMarker(code)); |
| - LowLevelCodeCreateEvent(code, &msg); |
| msg.Append('\n'); |
| msg.WriteToLogFile(); |
| #endif |
| @@ -844,14 +1023,26 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, |
| void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[tag]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendInt(args_count); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (!FLAG_log_code) return; |
| LogMessageBuilder msg(this); |
| msg.Append("%s,%s,", |
| kLogEventsNames[CODE_CREATION_EVENT], |
| kLogEventsNames[tag]); |
| msg.AppendAddress(code->address()); |
| msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count); |
| - LowLevelCodeCreateEvent(code, &msg); |
| msg.Append('\n'); |
| msg.WriteToLogFile(); |
| #endif |
| @@ -860,10 +1051,8 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) { |
| void Logger::CodeMovingGCEvent() { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return; |
| - LogMessageBuilder msg(this); |
| - msg.Append("%s\n", kLogEventsNames[CODE_MOVING_GC]); |
| - msg.WriteToLogFile(); |
| + if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| + LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag)); |
| OS::SignalCodeMovingGC(); |
| #endif |
| } |
| @@ -871,7 +1060,20 @@ void Logger::CodeMovingGCEvent() { |
| void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof || Serializer::enabled()) { |
| + name_buffer_->Reset(); |
| + name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]); |
| + name_buffer_->AppendByte(':'); |
| + name_buffer_->AppendString(source); |
| + } |
| + if (FLAG_ll_prof) { |
| + LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (Serializer::enabled()) { |
| + RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size()); |
| + } |
| + if (!FLAG_log_code) return; |
| LogMessageBuilder msg(this); |
| msg.Append("%s,%s,", |
| kLogEventsNames[CODE_CREATION_EVENT], |
| @@ -880,7 +1082,6 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| msg.Append(",%d,\"", code->ExecutableSize()); |
| msg.AppendDetailed(source, false); |
| msg.Append('\"'); |
| - LowLevelCodeCreateEvent(code, &msg); |
| msg.Append('\n'); |
| msg.WriteToLogFile(); |
| #endif |
| @@ -889,6 +1090,21 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) { |
| void Logger::CodeMoveEvent(Address from, Address to) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to); |
| + if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| + Address code_address = from + Code::kHeaderSize; |
| + uint32_t hash = ComputePointerHash(code_address); |
| + HashMap::Entry* entry = address_to_name_map_->Lookup( |
|
mnaganov (inactive)
2011/04/29 14:20:28
This code is repeated several times. Worth extract
Vitaly Repeshko
2011/04/29 15:50:40
Created a class. It's +20 lines overall, but the c
|
| + code_address, hash, false); |
| + ASSERT(entry != NULL); |
| + void* value = entry->value; |
| + address_to_name_map_->Remove(code_address, hash); |
| + entry = address_to_name_map_->Lookup(code_address, hash, true); |
| + ASSERT(entry->value == NULL); |
| + entry->value = value; |
| + return; |
| + } |
| MoveEventInternal(CODE_MOVE_EVENT, from, to); |
| #endif |
| } |
| @@ -896,6 +1112,19 @@ void Logger::CodeMoveEvent(Address from, Address to) { |
| void Logger::CodeDeleteEvent(Address from) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from); |
| + if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| + Address code_address = from + Code::kHeaderSize; |
| + uint32_t hash = ComputePointerHash(code_address); |
| + HashMap::Entry* entry = address_to_name_map_->Lookup( |
| + code_address, hash, false); |
| + if (entry != NULL) { |
| + DeleteArray(static_cast<const char*>(entry->value)); |
| + } |
| + address_to_name_map_->Remove(code_address, hash); |
| + return; |
| + } |
| DeleteEventInternal(CODE_DELETE_EVENT, from); |
| #endif |
| } |
| @@ -903,7 +1132,25 @@ void Logger::CodeDeleteEvent(Address from) { |
| void Logger::SnapshotPositionEvent(Address addr, int pos) { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_snapshot_positions) return; |
| + if (!log_->IsEnabled()) return; |
| + if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos); |
| + if (Serializer::enabled() && address_to_name_map_ != NULL) { |
| + Address code_address = addr + Code::kHeaderSize; |
| + HashMap::Entry* entry = address_to_name_map_->Lookup( |
| + code_address, ComputePointerHash(code_address), false); |
| + if (entry == NULL) return; // Not a code object. |
| + LogMessageBuilder msg(this); |
| + msg.Append("%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos); |
| + for (const char* p = static_cast<const char*>(entry->value); |
| + *p != '\0'; |
| + ++p) { |
| + if (*p == '"') msg.Append('\\'); |
| + msg.Append(*p); |
| + } |
| + msg.Append("\"\n"); |
| + msg.WriteToLogFile(); |
| + } |
| + if (!FLAG_log_snapshot_positions) return; |
| LogMessageBuilder msg(this); |
| msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]); |
| msg.AppendAddress(addr); |
| @@ -1308,7 +1555,7 @@ static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis, |
| void Logger::LogCodeObject(Object* object) { |
| - if (FLAG_log_code) { |
| + if (FLAG_log_code || FLAG_ll_prof) { |
| Code* code_object = Code::cast(object); |
| LogEventsAndTags tag = Logger::STUB_TAG; |
| const char* description = "Unknown code from the snapshot"; |
| @@ -1369,7 +1616,7 @@ void Logger::LogCodeObject(Object* object) { |
| void Logger::LogCodeInfo() { |
| #ifdef ENABLE_LOGGING_AND_PROFILING |
| - if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return; |
| + if (!log_->IsEnabled() || !FLAG_ll_prof) return; |
| #if V8_TARGET_ARCH_IA32 |
| const char arch[] = "ia32"; |
| #elif V8_TARGET_ARCH_X64 |
| @@ -1379,21 +1626,86 @@ void Logger::LogCodeInfo() { |
| #else |
| const char arch[] = "unknown"; |
| #endif |
| - LogMessageBuilder msg(this); |
| - msg.Append("code-info,%s,%d\n", arch, Code::kHeaderSize); |
| - msg.WriteToLogFile(); |
| + LowLevelLogWriteBytes(arch, sizeof(arch)); |
| #endif // ENABLE_LOGGING_AND_PROFILING |
| } |
| -void Logger::LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg) { |
| - if (!FLAG_ll_prof || log_->output_code_handle_ == NULL) return; |
| - int pos = static_cast<int>(ftell(log_->output_code_handle_)); |
| - size_t rv = fwrite(code->instruction_start(), 1, code->instruction_size(), |
| - log_->output_code_handle_); |
| - ASSERT(static_cast<size_t>(code->instruction_size()) == rv); |
| +static char* CopyName(const char* name, int name_size) { |
| + char* result = NewArray<char>(name_size + 1); |
| + for (int i = 0; i < name_size; ++i) { |
| + char c = name[i]; |
| + if (c == '\0') c = ' '; |
| + result[i] = c; |
| + } |
| + result[name_size] = '\0'; |
| + return result; |
| +} |
| + |
| + |
| +void Logger::RegisterSnapshotCodeName(Code* code, |
| + const char* name, |
| + int name_size) { |
| + ASSERT(Serializer::enabled()); |
| + if (address_to_name_map_ == NULL) { |
| + address_to_name_map_ = new HashMap(&PointerEquals); |
| + } |
| + Address code_address = code->instruction_start(); |
| + HashMap::Entry* entry = address_to_name_map_->Lookup( |
| + code_address, ComputePointerHash(code_address), true); |
| + if (entry->value == NULL) { |
| + entry->value = CopyName(name, name_size); |
| + } |
| +} |
| + |
| + |
| +void Logger::LowLevelCodeCreateEvent(Code* code, |
| + const char* name, |
| + int name_size) { |
| + if (log_->ll_output_handle_ == NULL) return; |
| + LowLevelCodeCreateStruct event; |
| + event.name_size = name_size; |
| + event.code_address = code->instruction_start(); |
| + ASSERT(event.code_address == code->address() + Code::kHeaderSize); |
| + event.code_size = code->instruction_size(); |
| + LowLevelLogWriteStruct(event); |
| + LowLevelLogWriteBytes(name, name_size); |
| + LowLevelLogWriteBytes( |
| + reinterpret_cast<const char*>(code->instruction_start()), |
| + code->instruction_size()); |
| +} |
| + |
| + |
| +void Logger::LowLevelCodeMoveEvent(Address from, Address to) { |
| + if (log_->ll_output_handle_ == NULL) return; |
| + LowLevelCodeMoveStruct event; |
| + event.from_address = from + Code::kHeaderSize; |
| + event.to_address = to + Code::kHeaderSize; |
| + LowLevelLogWriteStruct(event); |
| +} |
| + |
| + |
| +void Logger::LowLevelCodeDeleteEvent(Address from) { |
| + if (log_->ll_output_handle_ == NULL) return; |
| + LowLevelCodeDeleteStruct event; |
| + event.address = from + Code::kHeaderSize; |
| + LowLevelLogWriteStruct(event); |
| +} |
| + |
| + |
| +void Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) { |
| + if (log_->ll_output_handle_ == NULL) return; |
| + LowLevelSnapshotPositionStruct event; |
| + event.address = addr + Code::kHeaderSize; |
| + event.position = pos; |
| + LowLevelLogWriteStruct(event); |
| +} |
| + |
| + |
| +void Logger::LowLevelLogWriteBytes(const char* bytes, int size) { |
| + size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_); |
| + ASSERT(static_cast<size_t>(size) == rv); |
| USE(rv); |
| - msg->Append(",%d", pos); |
| } |
| @@ -1496,7 +1808,6 @@ bool Logger::Setup() { |
| // --ll-prof implies --log-code and --log-snapshot-positions. |
| if (FLAG_ll_prof) { |
| - FLAG_log_code = true; |
| FLAG_log_snapshot_positions = true; |
| } |
| @@ -1523,7 +1834,7 @@ bool Logger::Setup() { |
| bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api |
| || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect |
| - || FLAG_log_regexp || FLAG_log_state_changes; |
| + || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof; |
| if (start_logging) { |
| logging_nesting_ = 1; |