}
+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,
}
-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.
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<JSFunction*>(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);
}
// 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
// Used from the VM thread.
HashMap* known_functions_;
+ List<JSFunction*> moved_functions_;
};
} } // namespace v8::internal
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()) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (FLAG_log_gc) HeapProfiler::WriteSample();
+ if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions();
#endif
}
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
}
-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);
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.
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));
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));