Revision: 3343 Author: [email protected] Date: Mon Nov 23 01:19:24 2009 Log: Reimplement logging of API callbacks entry points in an easier way.
Now they are logging during "LogCompiledFunctions" cycle. API functions are detected by examining SFI's "function_data" field. Review URL: http://codereview.chromium.org/414036 http://code.google.com/p/v8/source/detail?r=3343 Modified: /branches/bleeding_edge/src/log.cc /branches/bleeding_edge/src/log.h /branches/bleeding_edge/test/cctest/test-log.cc ======================================= --- /branches/bleeding_edge/src/log.cc Fri Nov 20 04:15:46 2009 +++ /branches/bleeding_edge/src/log.cc Mon Nov 23 01:19:24 2009 @@ -638,25 +638,7 @@ } -void Logger::CallbackEvent(const char* class_name, const char* method_name, - Address entry_point) { #ifdef ENABLE_LOGGING_AND_PROFILING - if (!Log::IsEnabled() || !FLAG_log_code) return; - LogMessageBuilder msg; - msg.Append("%s,%s,", - log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]); - msg.AppendAddress(entry_point); - msg.Append(",0,\""); - if (class_name != NULL) { - msg.Append("%s.", class_name); - } - msg.Append("%s\"\n", method_name); - msg.WriteToLogFile(); -#endif -} - - -#ifdef ENABLE_LOGGING_AND_PROFILING // A class that contains all common code dealing with record compression. class CompressionHelper { @@ -692,6 +674,26 @@ #endif // ENABLE_LOGGING_AND_PROFILING +void Logger::CallbackEvent(String* name, Address entry_point) { +#ifdef ENABLE_LOGGING_AND_PROFILING + if (!Log::IsEnabled() || !FLAG_log_code) return; + LogMessageBuilder msg; + msg.Append("%s,%s,", + log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]); + msg.AppendAddress(entry_point); + SmartPointer<char> str = + name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); + msg.Append(",0,\"%s\"", *str); + if (FLAG_compress_log) { + ASSERT(compression_helper_ != NULL); + if (!compression_helper_->HandleMessage(&msg)) return; + } + msg.Append('\n'); + msg.WriteToLogFile(); +#endif +} + + void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, const char* comment) { @@ -1090,7 +1092,6 @@ LOG(UncheckedStringEvent("profiler", "resume")); FLAG_log_code = true; LogCompiledFunctions(); - LogCallbacks(); if (!FLAG_sliding_state_window) ticker_->Start(); } profiler_->resume(); @@ -1211,78 +1212,29 @@ LOG(CodeCreateEvent(Logger::SCRIPT_TAG, shared->code(), *script_name)); } - continue; - } - } - // If no script or script has no name. - LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); + } else { + LOG(CodeCreateEvent( + Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); + } + } else if (shared->function_data()->IsFunctionTemplateInfo()) { + // API function. + FunctionTemplateInfo* fun_data = + FunctionTemplateInfo::cast(shared->function_data()); + Object* raw_call_data = fun_data->call_code(); + if (!raw_call_data->IsUndefined()) { + CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); + Object* callback_obj = call_data->callback(); + Address entry_point = v8::ToCData<Address>(callback_obj); + LOG(CallbackEvent(*func_name, entry_point)); + } + } else { + LOG(CodeCreateEvent( + Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); + } } DeleteArray(sfis); } - - -namespace { - -class FunctionTemplateInfosVisitor : public ObjectVisitor { - public: - virtual ~FunctionTemplateInfosVisitor() {} - virtual void VisitPointers(Object** start, Object** end) { - for (Object** p = start; p < end; ++p) { - VisitFTI(*p); - } - } - - private: - void VisitFTI(Object* o) { - // The data about callbacks is in fact dynamically typed - // (Object ptrs are used), so we use runtime type checking - // to be sure that we retrieve the right thing. - if (!o->IsFunctionTemplateInfo()) - return; - AssertNoAllocation no_alloc; - FunctionTemplateInfo* fti = FunctionTemplateInfo::cast(o); - if (!fti->prototype_template()->IsObjectTemplateInfo()) - return; - SmartPointer<char> class_name; - if (fti->class_name()->IsString()) { - class_name = String::cast(fti->class_name())-> - ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); - } - ObjectTemplateInfo* proto = - ObjectTemplateInfo::cast(fti->prototype_template()); - NeanderArray props(Handle<Object>(proto->property_list())); - // Properties are triples: [property name, entry point, attributes]. - // See Template::Set in api.cc. - for (int i = 0; i < props.length(); i += 3) { - if (!props.get(i)->IsString() - || !props.get(i + 1)->IsFunctionTemplateInfo()) - continue; - FunctionTemplateInfo* native_fti = - FunctionTemplateInfo::cast(props.get(i + 1)); - Object* raw_call_data = native_fti->call_code(); - if (raw_call_data->IsUndefined()) - continue; - CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); - Object* callback_obj = call_data->callback(); - Address entry_point = v8::ToCData<Address>(callback_obj); - SmartPointer<char> method_name( - String::cast(props.get(i))-> - ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); - LOG(CallbackEvent(*class_name, *method_name, entry_point)); - } - } -}; - -} // anonymous namespace - - -void Logger::LogCallbacks() { - // We are looking for callbacks information exposed via persistent - // FunctionTemplate objects. - FunctionTemplateInfosVisitor visitor; - GlobalHandles::IterateStrongRoots(&visitor); -} #endif ======================================= --- /branches/bleeding_edge/src/log.h Fri Nov 20 04:15:46 2009 +++ /branches/bleeding_edge/src/log.h Mon Nov 23 01:19:24 2009 @@ -202,8 +202,7 @@ // ==== Events logged by --log-code. ==== // Emits a code event for a callback function. - static void CallbackEvent(const char* class_name, const char* method_name, - Address entry_point); + static void CallbackEvent(String* name, Address entry_point); // Emits a code create event. static void CodeCreateEvent(LogEventsAndTags tag, Code* code, const char* source); @@ -271,10 +270,6 @@ static void LogCompiledFunctions(); // Used for logging stubs found in the snapshot. static void LogCodeObject(Object* code_object); - // Used for logging callback entry points to be able to reveal their - // names in call stacks when information about native code exports is - // inaccessible. - static void LogCallbacks(); private: ======================================= --- /branches/bleeding_edge/test/cctest/test-log.cc Fri Nov 20 04:15:46 2009 +++ /branches/bleeding_edge/test/cctest/test-log.cc Mon Nov 23 01:19:24 2009 @@ -510,18 +510,22 @@ signature), static_cast<v8::PropertyAttribute>(v8::DontDelete)); - i::Logger::LogCallbacks(); + env->Global()->Set(v8_str("Obj"), obj->GetFunction()); + CompileAndRunScript("Obj.prototype.method1.toString();"); + + i::Logger::LogCompiledFunctions(); log_pos = GetLogLines(log_pos, &buffer); CHECK_GT(log_pos, 0); buffer[log_pos] = 0; const char* callback_rec = "code-creation,Callback,"; - const char* pos = strstr(buffer.start(), callback_rec); + char* pos = strstr(buffer.start(), callback_rec); CHECK_NE(NULL, pos); pos += strlen(callback_rec); EmbeddedVector<char, 100> ref_data; i::OS::SNPrintF(ref_data, - "0x%" V8PRIxPTR ",0,\"Obj.method1\"\n", ObjMethod1); + "0x%" V8PRIxPTR ",0,\"method1\"", ObjMethod1); + *(pos + strlen(ref_data.start())) = '\0'; CHECK_EQ(ref_data.start(), pos); obj.Dispose(); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
