Revision: 5667
Author: [email protected]
Date: Wed Oct 20 01:32:24 2010
Log: 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
http://code.google.com/p/v8/source/detail?r=5667
Modified:
/branches/bleeding_edge/src/cpu-profiler.cc
/branches/bleeding_edge/src/cpu-profiler.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/log.cc
/branches/bleeding_edge/src/log.h
/branches/bleeding_edge/src/mark-compact.cc
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Fri Sep 24 04:50:50 2010
+++ /branches/bleeding_edge/src/cpu-profiler.cc Wed Oct 20 01:32:24 2010
@@ -186,6 +186,20 @@
known_functions_->Lookup(start, AddressHash(start), false);
return entry != NULL;
}
+
+
+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(
@@ -426,8 +440,12 @@
}
-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 @@
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);
}
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h Tue Oct 19 09:45:11 2010
+++ /branches/bleeding_edge/src/cpu-profiler.h Wed Oct 20 01:32:24 2010
@@ -165,6 +165,8 @@
// 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 @@
// Used from the VM thread.
HashMap* known_functions_;
+ List<JSFunction*> moved_functions_;
};
} } // namespace v8::internal
@@ -257,12 +260,12 @@
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()) {
=======================================
--- /branches/bleeding_edge/src/heap.cc Tue Oct 19 09:45:11 2010
+++ /branches/bleeding_edge/src/heap.cc Wed Oct 20 01:32:24 2010
@@ -469,6 +469,7 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
if (FLAG_log_gc) HeapProfiler::WriteSample();
+ if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions();
#endif
}
@@ -1260,7 +1261,7 @@
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
=======================================
--- /branches/bleeding_edge/src/log.cc Tue Oct 19 09:45:11 2010
+++ /branches/bleeding_edge/src/log.cc Wed Oct 20 01:32:24 2010
@@ -926,8 +926,7 @@
}
-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);
=======================================
--- /branches/bleeding_edge/src/log.h Tue Oct 19 09:45:11 2010
+++ /branches/bleeding_edge/src/log.h Wed Oct 20 01:32:24 2010
@@ -219,8 +219,7 @@
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.
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Mon Oct 18 07:59:03 2010
+++ /branches/bleeding_edge/src/mark-compact.cc Wed Oct 20 01:32:24 2010
@@ -2553,7 +2553,7 @@
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 @@
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));
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev