| Index: src/log.cc
|
| ===================================================================
|
| --- src/log.cc (revision 1284)
|
| +++ src/log.cc (working copy)
|
| @@ -268,7 +268,10 @@
|
| ~LogMessageBuilder() { }
|
|
|
| void Append(const char* format, ...);
|
| + void Append(const char* format, va_list args);
|
| void Append(const char c);
|
| + void Append(String *str);
|
| + void AppendDetailed(String* str, bool show_impl_info);
|
|
|
| void WriteToLogFile();
|
|
|
| @@ -291,9 +294,18 @@
|
| Logger::kMessageBufferSize - pos_);
|
| va_list args;
|
| va_start(args, format);
|
| - int result = v8::internal::OS::VSNPrintF(buf, format, args);
|
| + Append(format, args);
|
| va_end(args);
|
| + ASSERT(pos_ <= Logger::kMessageBufferSize);
|
| +}
|
|
|
| +
|
| +// Append string data to the log message.
|
| +void LogMessageBuilder::Append(const char* format, va_list args) {
|
| + Vector<char> buf(Logger::message_buffer_ + pos_,
|
| + Logger::kMessageBufferSize - pos_);
|
| + int result = v8::internal::OS::VSNPrintF(buf, format, args);
|
| +
|
| // Result is -1 if output was truncated.
|
| if (result >= 0) {
|
| pos_ += result;
|
| @@ -313,6 +325,46 @@
|
| }
|
|
|
|
|
| +// Append a heap string.
|
| +void LogMessageBuilder::Append(String* str) {
|
| + AssertNoAllocation no_heap_allocation; // Ensure string stay valid.
|
| + StringShape shape(str);
|
| + int length = str->length(shape);
|
| + for (int i = 0; i < length; i++) {
|
| + Append(static_cast<char>(str->Get(shape, i)));
|
| + }
|
| +}
|
| +
|
| +void LogMessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
|
| + AssertNoAllocation no_heap_allocation; // Ensure string stay valid.
|
| + StringShape shape(str);
|
| + int len = str->length(shape);
|
| + if (len > 0x1000)
|
| + len = 0x1000;
|
| + if (show_impl_info) {
|
| + Append(shape.IsAsciiRepresentation() ? 'a' : '2');
|
| + if (shape.IsExternal())
|
| + Append('e');
|
| + if (shape.IsSymbol())
|
| + Append('#');
|
| + Append(":%i:", str->length());
|
| + }
|
| + for (int i = 0; i < len; i++) {
|
| + uc32 c = str->Get(shape, i);
|
| + if (c > 0xff) {
|
| + Append("\\u%04x", c);
|
| + } else if (c < 32 || c > 126) {
|
| + Append("\\x%02x", c);
|
| + } else if (c == ',') {
|
| + Append("\\,");
|
| + } else if (c == '\\') {
|
| + Append("\\\\");
|
| + } else {
|
| + Append("%lc", c);
|
| + }
|
| + }
|
| +}
|
| +
|
| // Write the log message to the log file currently opened.
|
| void LogMessageBuilder::WriteToLogFile() {
|
| ASSERT(pos_ <= Logger::kMessageBufferSize);
|
| @@ -338,8 +390,9 @@
|
| void Logger::Preamble(const char* content) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_code) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "%s", content);
|
| + LogMessageBuilder msg;
|
| + msg.Append("%s", content);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -354,8 +407,9 @@
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::UncheckedStringEvent(const char* name, const char* value) {
|
| if (logfile_ == NULL) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "%s,\"%s\"\n", name, value);
|
| + LogMessageBuilder msg;
|
| + msg.Append("%s,\"%s\"\n", name, value);
|
| + msg.WriteToLogFile();
|
| }
|
| #endif
|
|
|
| @@ -363,8 +417,9 @@
|
| void Logger::IntEvent(const char* name, int value) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "%s,%d\n", name, value);
|
| + LogMessageBuilder msg;
|
| + msg.Append("%s,%d\n", name, value);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -372,9 +427,10 @@
|
| void Logger::HandleEvent(const char* name, Object** location) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_handles) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "%s,0x%x\n", name,
|
| - reinterpret_cast<unsigned int>(location));
|
| + LogMessageBuilder msg;
|
| + msg.Append("%s,0x%x\n", name,
|
| + reinterpret_cast<unsigned int>(location));
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -385,10 +441,12 @@
|
| // FLAG_log_api is true.
|
| void Logger::ApiEvent(const char* format, ...) {
|
| ASSERT(logfile_ != NULL && FLAG_log_api);
|
| - ScopedLock sl(mutex_);
|
| + LogMessageBuilder msg;
|
| va_list ap;
|
| va_start(ap, format);
|
| - vfprintf(logfile_, format, ap);
|
| + msg.Append(format, ap);
|
| + va_end(ap);
|
| + msg.WriteToLogFile();
|
| }
|
| #endif
|
|
|
| @@ -414,9 +472,10 @@
|
| unsigned end) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_prof) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "shared-library,\"%s\",0x%08x,0x%08x\n", library_path,
|
| - start, end);
|
| + LogMessageBuilder msg;
|
| + msg.Append("shared-library,\"%s\",0x%08x,0x%08x\n", library_path,
|
| + start, end);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -426,79 +485,54 @@
|
| unsigned end) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_prof) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "shared-library,\"%ls\",0x%08x,0x%08x\n", library_path,
|
| - start, end);
|
| + LogMessageBuilder msg;
|
| + msg.Append("shared-library,\"%ls\",0x%08x,0x%08x\n", library_path,
|
| + start, end);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| -void Logger::LogString(Handle<String> str, bool show_impl_info) {
|
| - StringShape shape(*str);
|
| - int len = str->length(shape);
|
| - if (len > 0x1000)
|
| - len = 0x1000;
|
| - if (show_impl_info) {
|
| - fputc(shape.IsAsciiRepresentation() ? 'a' : '2', logfile_);
|
| - if (shape.IsExternal())
|
| - fputc('e', logfile_);
|
| - if (shape.IsSymbol())
|
| - fputc('#', logfile_);
|
| - fprintf(logfile_, ":%i:", str->length());
|
| - }
|
| - for (int i = 0; i < len; i++) {
|
| - uc32 c = str->Get(shape, i);
|
| - if (c > 0xff) {
|
| - fprintf(logfile_, "\\u%04x", c);
|
| - } else if (c < 32 || c > 126) {
|
| - fprintf(logfile_, "\\x%02x", c);
|
| - } else if (c == ',') {
|
| - fprintf(logfile_, "\\,");
|
| - } else if (c == '\\') {
|
| - fprintf(logfile_, "\\\\");
|
| - } else {
|
| - fprintf(logfile_, "%lc", c);
|
| - }
|
| - }
|
| -}
|
| -
|
| void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
|
| // Prints "/" + re.source + "/" +
|
| // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
|
| + LogMessageBuilder msg;
|
|
|
| Handle<Object> source = GetProperty(regexp, "source");
|
| if (!source->IsString()) {
|
| - fprintf(logfile_, "no source");
|
| + msg.Append("no source");
|
| return;
|
| }
|
|
|
| switch (regexp->TypeTag()) {
|
| case JSRegExp::ATOM:
|
| - fprintf(logfile_, "a");
|
| + msg.Append('a');
|
| break;
|
| default:
|
| break;
|
| }
|
| - fprintf(logfile_, "/");
|
| - LogString(Handle<String>::cast(source), false);
|
| - fprintf(logfile_, "/");
|
| + msg.Append('/');
|
| + msg.AppendDetailed(*Handle<String>::cast(source), false);
|
| + msg.Append('/');
|
|
|
| // global flag
|
| Handle<Object> global = GetProperty(regexp, "global");
|
| if (global->IsTrue()) {
|
| - fprintf(logfile_, "g");
|
| + msg.Append('g');
|
| }
|
| // ignorecase flag
|
| Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");
|
| if (ignorecase->IsTrue()) {
|
| - fprintf(logfile_, "i");
|
| + msg.Append('i');
|
| }
|
| // multiline flag
|
| Handle<Object> multiline = GetProperty(regexp, "multiline");
|
| if (multiline->IsTrue()) {
|
| - fprintf(logfile_, "m");
|
| + msg.Append('m');
|
| }
|
| +
|
| + msg.WriteToLogFile();
|
| }
|
| #endif // ENABLE_LOGGING_AND_PROFILING
|
|
|
| @@ -506,19 +540,20 @@
|
| void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_regexp) return;
|
| - ScopedLock sl(mutex_);
|
| -
|
| - fprintf(logfile_, "regexp-compile,");
|
| + LogMessageBuilder msg;
|
| + msg.Append("regexp-compile,");
|
| LogRegExpSource(regexp);
|
| - fprintf(logfile_, in_cache ? ",hit\n" : ",miss\n");
|
| + msg.Append(in_cache ? ",hit\n" : ",miss\n");
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
|
|
| void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - ScopedLock sl(mutex_);
|
| + if (logfile_ == NULL || !FLAG_log_runtime) return;
|
| HandleScope scope;
|
| + LogMessageBuilder msg;
|
| for (int i = 0; i < format.length(); i++) {
|
| char c = format[i];
|
| if (c == '%' && i <= format.length() - 2) {
|
| @@ -528,28 +563,29 @@
|
| i++;
|
| switch (format[i]) {
|
| case 's':
|
| - Logger::LogString(Handle<String>(String::cast(obj)), false);
|
| + msg.AppendDetailed(String::cast(obj), false);
|
| break;
|
| case 'S':
|
| - Logger::LogString(Handle<String>(String::cast(obj)), true);
|
| + msg.AppendDetailed(String::cast(obj), true);
|
| break;
|
| case 'r':
|
| Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj)));
|
| break;
|
| case 'x':
|
| - fprintf(logfile_, "0x%x", Smi::cast(obj)->value());
|
| + msg.Append("0x%x", Smi::cast(obj)->value());
|
| break;
|
| case 'i':
|
| - fprintf(logfile_, "%i", Smi::cast(obj)->value());
|
| + msg.Append("%i", Smi::cast(obj)->value());
|
| break;
|
| default:
|
| UNREACHABLE();
|
| }
|
| } else {
|
| - fputc(c, logfile_);
|
| + msg.Append(c);
|
| }
|
| }
|
| - fputc('\n', logfile_);
|
| + msg.Append('\n');
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -611,10 +647,11 @@
|
| void Logger::NewEvent(const char* name, void* object, size_t size) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "new,%s,0x%x,%u\n", name,
|
| - reinterpret_cast<unsigned int>(object),
|
| - static_cast<unsigned int>(size));
|
| + LogMessageBuilder msg;
|
| + msg.Append("new,%s,0x%x,%u\n", name,
|
| + reinterpret_cast<unsigned int>(object),
|
| + static_cast<unsigned int>(size));
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -622,9 +659,10 @@
|
| void Logger::DeleteEvent(const char* name, void* object) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "delete,%s,0x%x\n", name,
|
| - reinterpret_cast<unsigned int>(object));
|
| + LogMessageBuilder msg;
|
| + msg.Append("delete,%s,0x%x\n", name,
|
| + reinterpret_cast<unsigned int>(object));
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -637,7 +675,9 @@
|
| reinterpret_cast<unsigned int>(code->address()),
|
| code->instruction_size());
|
| for (const char* p = comment; *p != '\0'; p++) {
|
| - if (*p == '\"') fprintf(logfile_, "\\");
|
| + if (*p == '"') {
|
| + msg.Append('\\');
|
| + }
|
| msg.Append(*p);
|
| }
|
| msg.Append('"');
|
| @@ -757,16 +797,17 @@
|
| void Logger::ResourceEvent(const char* name, const char* tag) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "%s,%s,", name, tag);
|
| + LogMessageBuilder msg;
|
| + msg.Append("%s,%s,", name, tag);
|
|
|
| uint32_t sec, usec;
|
| if (OS::GetUserTime(&sec, &usec) != -1) {
|
| - fprintf(logfile_, "%d,%d,", sec, usec);
|
| + msg.Append("%d,%d,", sec, usec);
|
| }
|
| - fprintf(logfile_, "%.0f", OS::TimeCurrentMillis());
|
| + msg.Append("%.0f", OS::TimeCurrentMillis());
|
|
|
| - fprintf(logfile_, "\n");
|
| + msg.Append('\n');
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -774,15 +815,19 @@
|
| void Logger::SuspectReadEvent(String* name, Object* obj) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_suspect) return;
|
| + LogMessageBuilder msg;
|
| String* class_name = obj->IsJSObject()
|
| ? JSObject::cast(obj)->class_name()
|
| : Heap::empty_string();
|
| ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "suspect-read,");
|
| - class_name->PrintOn(logfile_);
|
| - fprintf(logfile_, ",\"");
|
| - name->PrintOn(logfile_);
|
| - fprintf(logfile_, "\"\n");
|
| + msg.Append("suspect-read,");
|
| + msg.Append(class_name);
|
| + msg.Append(',');
|
| + msg.Append('"');
|
| + msg.Append(name);
|
| + msg.Append('"');
|
| + msg.Append('\n');
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -790,8 +835,9 @@
|
| void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_gc) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "heap-sample-begin,\"%s\",\"%s\"\n", space, kind);
|
| + LogMessageBuilder msg;
|
| + msg.Append("heap-sample-begin,\"%s\",\"%s\"\n", space, kind);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -799,8 +845,9 @@
|
| void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_gc) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "heap-sample-end,\"%s\",\"%s\"\n", space, kind);
|
| + LogMessageBuilder msg;
|
| + msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -808,8 +855,9 @@
|
| void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log_gc) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "heap-sample-item,%s,%d,%d\n", type, number, bytes);
|
| + LogMessageBuilder msg;
|
| + msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -817,8 +865,9 @@
|
| void Logger::DebugTag(const char* call_site_tag) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (logfile_ == NULL || !FLAG_log) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "debug-tag,%s\n", call_site_tag);
|
| + LogMessageBuilder msg;
|
| + msg.Append("debug-tag,%s\n", call_site_tag);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -831,13 +880,13 @@
|
| s.AddCharacter(static_cast<char>(parameter[i]));
|
| }
|
| char* parameter_string = s.Finalize();
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_,
|
| - "debug-queue-event,%s,%15.3f,%s\n",
|
| - event_type,
|
| - OS::TimeCurrentMillis(),
|
| - parameter_string);
|
| + LogMessageBuilder msg;
|
| + msg.Append("debug-queue-event,%s,%15.3f,%s\n",
|
| + event_type,
|
| + OS::TimeCurrentMillis(),
|
| + parameter_string);
|
| DeleteArray(parameter_string);
|
| + msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| @@ -845,11 +894,14 @@
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::TickEvent(TickSample* sample, bool overflow) {
|
| if (logfile_ == NULL || !FLAG_prof) return;
|
| - ScopedLock sl(mutex_);
|
| - fprintf(logfile_, "tick,0x%x,0x%x,%d", sample->pc, sample->sp,
|
| - static_cast<int>(sample->state));
|
| - if (overflow) fprintf(logfile_, ",overflow");
|
| - fprintf(logfile_, "\n");
|
| + LogMessageBuilder msg;
|
| + msg.Append("tick,0x%x,0x%x,%d", sample->pc, sample->sp,
|
| + static_cast<int>(sample->state));
|
| + if (overflow) {
|
| + msg.Append(",overflow");
|
| + }
|
| + msg.Append('\n');
|
| + msg.WriteToLogFile();
|
| }
|
|
|
|
|
| @@ -873,6 +925,7 @@
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| // --log-all enables all the log flags.
|
| if (FLAG_log_all) {
|
| + FLAG_log_runtime = true;
|
| FLAG_log_api = true;
|
| FLAG_log_code = true;
|
| FLAG_log_gc = true;
|
| @@ -884,8 +937,8 @@
|
| // --prof implies --log-code.
|
| if (FLAG_prof) FLAG_log_code = true;
|
|
|
| - bool open_log_file = FLAG_log || FLAG_log_api || FLAG_log_code
|
| - || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
|
| + bool open_log_file = 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;
|
|
|
| // If we're logging anything, we need to open the log file.
|
|
|