From: mikhail.naganov@gmail.com Date: Wed, 20 Oct 2010 08:32:24 +0000 (+0000) Subject: CPU Profiler: postpone moved functions registration until GC completes. X-Git-Tag: upstream/4.7.83~21059 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5feede6667f3dcbc337f1551e4bae2bf86b31886;p=platform%2Fupstream%2Fv8.git CPU Profiler: postpone moved functions registration until GC completes. An attempt to retrieve security context for a function may fail if the destination heap space is in an incomplete state. To fix this, we only record unknown functions discovered at GC object moves, and then register them after GC completes. BUG=crbug/59627 Review URL: http://codereview.chromium.org/3763012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5667 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc index acf3349..da19a45 100644 --- a/src/cpu-profiler.cc +++ b/src/cpu-profiler.cc @@ -188,6 +188,20 @@ bool ProfilerEventsProcessor::IsKnownFunction(Address start) { } +void ProfilerEventsProcessor::ProcessMovedFunctions() { + for (int i = 0; i < moved_functions_.length(); ++i) { + JSFunction* function = moved_functions_[i]; + CpuProfiler::FunctionCreateEvent(function); + } + moved_functions_.Clear(); +} + + +void ProfilerEventsProcessor::RememberMovedFunction(JSFunction* function) { + moved_functions_.Add(function); +} + + void ProfilerEventsProcessor::RegExpCodeCreateEvent( Logger::LogEventsAndTags tag, const char* prefix, @@ -426,8 +440,12 @@ void CpuProfiler::FunctionCreateEvent(JSFunction* function) { } -void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function, - HeapObject* source) { +void CpuProfiler::ProcessMovedFunctions() { + singleton_->processor_->ProcessMovedFunctions(); +} + + +void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function) { // This function is 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. @@ -436,27 +454,7 @@ void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function, if (function->unchecked_code() == Builtins::builtin(Builtins::LazyCompile) || singleton_->processor_->IsKnownFunction(function->address())) return; - int security_token_id = TokenEnumerator::kNoSecurityToken; - // In debug mode, assertions may fail for contexts, - // and we can live without security tokens in debug mode. -#ifndef DEBUG - if (function->unchecked_context()->IsContext()) { - security_token_id = singleton_->token_enumerator_->GetTokenId( - function->context()->global_context()->security_token()); - } - // Security token may not be moved yet. - if (security_token_id == TokenEnumerator::kNoSecurityToken) { - JSFunction* old_function = reinterpret_cast(source); - if (old_function->unchecked_context()->IsContext()) { - security_token_id = singleton_->token_enumerator_->GetTokenId( - old_function->context()->global_context()->security_token()); - } - } -#endif - singleton_->processor_->FunctionCreateEvent( - function->address(), - function->unchecked_code()->address(), - security_token_id); + singleton_->processor_->RememberMovedFunction(function); } diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h index f52bd67..d3158d7 100644 --- a/src/cpu-profiler.h +++ b/src/cpu-profiler.h @@ -165,6 +165,8 @@ class ProfilerEventsProcessor : public Thread { // Puts current stack into tick sample events buffer. void AddCurrentStack(); bool IsKnownFunction(Address start); + void ProcessMovedFunctions(); + void RememberMovedFunction(JSFunction* function); // Tick sample events are filled directly in the buffer of the circular // queue (because the structure is of fixed width, but usually not all @@ -202,6 +204,7 @@ class ProfilerEventsProcessor : public Thread { // Used from the VM thread. HashMap* known_functions_; + List moved_functions_; }; } } // namespace v8::internal @@ -257,12 +260,12 @@ class CpuProfiler { static void FunctionCreateEvent(JSFunction* function); // Reports function creation in case we had missed it (e.g. // if it was created from compiled code). - static void FunctionCreateEventFromMove(JSFunction* function, - HeapObject* source); + static void FunctionCreateEventFromMove(JSFunction* function); static void FunctionMoveEvent(Address from, Address to); static void FunctionDeleteEvent(Address from); static void GetterCallbackEvent(String* name, Address entry_point); static void RegExpCodeCreateEvent(Code* code, String* source); + static void ProcessMovedFunctions(); static void SetterCallbackEvent(String* name, Address entry_point); static INLINE(bool is_profiling()) { diff --git a/src/heap.cc b/src/heap.cc index d1cf4e9..675639a 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -469,6 +469,7 @@ void Heap::CollectGarbage(AllocationSpace space, #ifdef ENABLE_LOGGING_AND_PROFILING if (FLAG_log_gc) HeapProfiler::WriteSample(); + if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions(); #endif } @@ -1260,7 +1261,7 @@ class ScavengingVisitor : public StaticVisitorBase { if (Logger::is_logging() || CpuProfiler::is_profiling()) { if (target->IsJSFunction()) { PROFILE(FunctionMoveEvent(source->address(), target->address())); - PROFILE(FunctionCreateEventFromMove(JSFunction::cast(target), source)); + PROFILE(FunctionCreateEventFromMove(JSFunction::cast(target))); } } #endif diff --git a/src/log.cc b/src/log.cc index fdc1180..1b0fdeb 100644 --- a/src/log.cc +++ b/src/log.cc @@ -926,8 +926,7 @@ void Logger::FunctionCreateEvent(JSFunction* function) { } -void Logger::FunctionCreateEventFromMove(JSFunction* function, - HeapObject*) { +void Logger::FunctionCreateEventFromMove(JSFunction* function) { #ifdef ENABLE_LOGGING_AND_PROFILING if (function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile)) { FunctionCreateEvent(function); diff --git a/src/log.h b/src/log.h index e95f3d9..3a4d79b 100644 --- a/src/log.h +++ b/src/log.h @@ -219,8 +219,7 @@ class Logger { static void CodeDeleteEvent(Address from); // Emits a function object create event. static void FunctionCreateEvent(JSFunction* function); - static void FunctionCreateEventFromMove(JSFunction* function, - HeapObject*); + static void FunctionCreateEventFromMove(JSFunction* function); // Emits a function move event. static void FunctionMoveEvent(Address from, Address to); // Emits a function delete event. diff --git a/src/mark-compact.cc b/src/mark-compact.cc index c817251..ad928ea 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -2553,7 +2553,7 @@ int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, HeapObject* copied_to = HeapObject::FromAddress(new_addr); if (copied_to->IsJSFunction()) { PROFILE(FunctionMoveEvent(old_addr, new_addr)); - PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to), obj)); + PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to))); } HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr)); @@ -2646,7 +2646,7 @@ int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { HeapObject* copied_to = HeapObject::FromAddress(new_addr); if (copied_to->IsJSFunction()) { PROFILE(FunctionMoveEvent(old_addr, new_addr)); - PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to), obj)); + PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to))); } HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));