| Index: src/log.cc
|
| ===================================================================
|
| --- src/log.cc (revision 7006)
|
| +++ src/log.cc (working copy)
|
| @@ -145,7 +145,7 @@
|
| // StackTracer implementation
|
| //
|
| void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
|
| - sample->function = NULL;
|
| + sample->tos = NULL;
|
| sample->frames_count = 0;
|
|
|
| // Avoid collecting traces while doing GC.
|
| @@ -158,15 +158,9 @@
|
| return;
|
| }
|
|
|
| - const Address function_address =
|
| - sample->fp + JavaScriptFrameConstants::kFunctionOffset;
|
| - if (SafeStackFrameIterator::IsWithinBounds(sample->sp, js_entry_sp,
|
| - function_address)) {
|
| - Object* object = Memory::Object_at(function_address);
|
| - if (object->IsHeapObject()) {
|
| - sample->function = HeapObject::cast(object)->address();
|
| - }
|
| - }
|
| + // Sample potential return address value for frameless invocation of
|
| + // stubs (we'll figure out later, if this value makes sense).
|
| + sample->tos = Memory::Address_at(sample->sp);
|
|
|
| int i = 0;
|
| const Address callback = isolate->external_callback();
|
| @@ -181,10 +175,7 @@
|
| sample->fp, sample->sp,
|
| sample->sp, js_entry_sp);
|
| while (!it.done() && i < TickSample::kMaxFramesCount) {
|
| - Object* object = it.frame()->function_slot_object();
|
| - if (object->IsHeapObject()) {
|
| - sample->stack[i++] = HeapObject::cast(object)->address();
|
| - }
|
| + sample->stack[i++] = it.frame()->pc();
|
| it.Advance();
|
| }
|
| sample->frames_count = i;
|
| @@ -735,17 +726,6 @@
|
| }
|
|
|
|
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| -static const char* ComputeMarker(Code* code) {
|
| - switch (code->kind()) {
|
| - case Code::FUNCTION: return code->optimizable() ? "~" : "";
|
| - case Code::OPTIMIZED_FUNCTION: return "*";
|
| - default: return "";
|
| - }
|
| -}
|
| -#endif
|
| -
|
| -
|
| void Logger::CodeCreateEvent(LogEventsAndTags tag,
|
| Code* code,
|
| const char* comment) {
|
| @@ -756,7 +736,7 @@
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[tag]);
|
| msg.AppendAddress(code->address());
|
| - msg.Append(",%d,\"%s", code->ExecutableSize(), ComputeMarker(code));
|
| + msg.Append(",%d,\"", code->ExecutableSize());
|
| for (const char* p = comment; *p != '\0'; p++) {
|
| if (*p == '"') {
|
| msg.Append('\\');
|
| @@ -771,9 +751,43 @@
|
| }
|
|
|
|
|
| -void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name) {
|
| +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, "");
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +
|
| +#ifdef ENABLE_LOGGING_AND_PROFILING
|
| +// ComputeMarker must only be used when SharedFunctionInfo is known.
|
| +static const char* ComputeMarker(Code* code) {
|
| + switch (code->kind()) {
|
| + case Code::FUNCTION: return code->optimizable() ? "~" : "";
|
| + case Code::OPTIMIZED_FUNCTION: return "*";
|
| + default: return "";
|
| + }
|
| +}
|
| +#endif
|
| +
|
| +
|
| +void Logger::CodeCreateEvent(LogEventsAndTags tag,
|
| + Code* code,
|
| + SharedFunctionInfo* shared,
|
| + String* name) {
|
| +#ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + if (code == Isolate::Current()->builtins()->builtin(
|
| + Builtins::LazyCompile))
|
| + return;
|
| +
|
| LogMessageBuilder msg(this);
|
| SmartPointer<char> str =
|
| name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| @@ -781,7 +795,9 @@
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[tag]);
|
| msg.AppendAddress(code->address());
|
| - msg.Append(",%d,\"%s%s\"", code->ExecutableSize(), ComputeMarker(code), *str);
|
| + msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str);
|
| + msg.AppendAddress(shared->address());
|
| + msg.Append(",%s", ComputeMarker(code));
|
| LowLevelCodeCreateEvent(code, &msg);
|
| msg.Append('\n');
|
| msg.WriteToLogFile();
|
| @@ -789,26 +805,31 @@
|
| }
|
|
|
|
|
| +// Although, it is possible to extract source and line from
|
| +// the SharedFunctionInfo object, we left it to caller
|
| +// to leave logging functions free from heap allocations.
|
| void Logger::CodeCreateEvent(LogEventsAndTags tag,
|
| - Code* code, String* name,
|
| + Code* code,
|
| + SharedFunctionInfo* shared,
|
| String* source, int line) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| LogMessageBuilder msg(this);
|
| - SmartPointer<char> str =
|
| - name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| + SmartPointer<char> name =
|
| + shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| SmartPointer<char> sourcestr =
|
| source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| msg.Append("%s,%s,",
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[tag]);
|
| msg.AppendAddress(code->address());
|
| - msg.Append(",%d,\"%s%s %s:%d\"",
|
| + msg.Append(",%d,\"%s %s:%d\",",
|
| code->ExecutableSize(),
|
| - ComputeMarker(code),
|
| - *str,
|
| + *name,
|
| *sourcestr,
|
| line);
|
| + msg.AppendAddress(shared->address());
|
| + msg.Append(",%s", ComputeMarker(code));
|
| LowLevelCodeCreateEvent(code, &msg);
|
| msg.Append('\n');
|
| msg.WriteToLogFile();
|
| @@ -888,48 +909,14 @@
|
| }
|
|
|
|
|
| -void Logger::FunctionCreateEvent(JSFunction* function) {
|
| +void Logger::SFIMoveEvent(Address from, Address to) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - // This function can be called from GC iterators (during Scavenge,
|
| - // MC, and MS), so marking bits can be set on objects. That's
|
| - // why unchecked accessors are used here.
|
| - if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg(this);
|
| - msg.Append("%s,", kLogEventsNames[FUNCTION_CREATION_EVENT]);
|
| - msg.AppendAddress(function->address());
|
| - msg.Append(',');
|
| - msg.AppendAddress(function->unchecked_code()->address());
|
| - msg.Append('\n');
|
| - msg.WriteToLogFile();
|
| + MoveEventInternal(SFI_MOVE_EVENT, from, to);
|
| #endif
|
| }
|
|
|
|
|
| -void Logger::FunctionCreateEventFromMove(Heap* heap, JSFunction* function) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (function->unchecked_code() !=
|
| - heap->isolate()->builtins()->builtin(Builtins::LazyCompile)) {
|
| - FunctionCreateEvent(function);
|
| - }
|
| -#endif
|
| -}
|
| -
|
| -
|
| -void Logger::FunctionMoveEvent(Heap* heap, Address from, Address to) {
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| - MoveEventInternal(FUNCTION_MOVE_EVENT, from, to);
|
| -#endif
|
| -}
|
| -
|
| -
|
| -void Logger::FunctionDeleteEvent(Address from) {
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| - DeleteEventInternal(FUNCTION_DELETE_EVENT, from);
|
| -#endif
|
| -}
|
| -
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::MoveEventInternal(LogEventsAndTags event,
|
| Address from,
|
| Address to) {
|
| @@ -1144,7 +1131,7 @@
|
| msg.Append(',');
|
| msg.AppendAddress(sample->sp);
|
| msg.Append(',');
|
| - msg.AppendAddress(sample->function);
|
| + msg.AppendAddress(sample->tos);
|
| msg.Append(",%d", static_cast<int>(sample->state));
|
| if (overflow) {
|
| msg.Append(",overflow");
|
| @@ -1213,7 +1200,6 @@
|
| LOG(UncheckedStringEvent("profiler", "resume"));
|
| FLAG_log_code = true;
|
| LogCompiledFunctions();
|
| - LogFunctionObjects();
|
| LogAccessorCallbacks();
|
| if (!FLAG_sliding_state_window && !ticker_->IsActive()) {
|
| ticker_->Start();
|
| @@ -1413,10 +1399,11 @@
|
| // During iteration, there can be heap allocation due to
|
| // GetScriptLineNumber call.
|
| for (int i = 0; i < compiled_funcs_count; ++i) {
|
| + if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
|
| + Builtins::LazyCompile))
|
| + continue;
|
| Handle<SharedFunctionInfo> shared = sfis[i];
|
| - Handle<String> name(String::cast(shared->name()));
|
| - Handle<String> func_name(name->length() > 0 ?
|
| - *name : shared->inferred_name());
|
| + Handle<String> func_name(shared->DebugName());
|
| if (shared->script()->IsScript()) {
|
| Handle<Script> script(Script::cast(shared->script()));
|
| if (script->name()->IsString()) {
|
| @@ -1425,18 +1412,18 @@
|
| if (line_num > 0) {
|
| PROFILE(CodeCreateEvent(
|
| Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| - *code_objects[i], *func_name,
|
| + *code_objects[i], *shared,
|
| *script_name, line_num + 1));
|
| } else {
|
| // Can't distinguish eval and script here, so always use Script.
|
| PROFILE(CodeCreateEvent(
|
| Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
|
| - *code_objects[i], *script_name));
|
| + *code_objects[i], *shared, *script_name));
|
| }
|
| } else {
|
| PROFILE(CodeCreateEvent(
|
| Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| - *code_objects[i], *func_name));
|
| + *code_objects[i], *shared, *func_name));
|
| }
|
| } else if (shared->IsApiFunction()) {
|
| // API function.
|
| @@ -1450,24 +1437,12 @@
|
| }
|
| } else {
|
| PROFILE(CodeCreateEvent(
|
| - Logger::LAZY_COMPILE_TAG, *code_objects[i], *func_name));
|
| + Logger::LAZY_COMPILE_TAG, *code_objects[i], *shared, *func_name));
|
| }
|
| }
|
| }
|
|
|
|
|
| -void Logger::LogFunctionObjects() {
|
| - AssertNoAllocation no_alloc;
|
| - HeapIterator iterator;
|
| - for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
|
| - if (!obj->IsJSFunction()) continue;
|
| - JSFunction* jsf = JSFunction::cast(obj);
|
| - if (!jsf->is_compiled()) continue;
|
| - PROFILE(FunctionCreateEvent(jsf));
|
| - }
|
| -}
|
| -
|
| -
|
| void Logger::LogAccessorCallbacks() {
|
| AssertNoAllocation no_alloc;
|
| HeapIterator iterator;
|
|
|