Commit 141ada02 authored by loislo@chromium.org's avatar loislo@chromium.org

Logger: introduce abstract interface for CodeEvent listeners.

New abstract class CodeEventListener was created.

CodeEventLogger which is the base class for Jit, LowLevel
and CodeAddressMap loggers was inherited from CodeEventListener.

CodeAddressMap class was moved to serializer.cc because serializer is the only user for it. Actually it collects code names and pushes them to the standard log as SnapshotCodeNameEvent. So I extracted this code into separate function CodeNameEvent. It happens that this method works only when Serializer serializes an object. So I added direct log call there.

CodeEventLogger class declaration was moved to the header
because CodeAddressMap needs it.
The code for the nested class CodeEventLogger::NameBuffer was left in the cc file.

CpuProfiler now is inherit CodeEventListener but not used
the loggers infrastructure yet due to the complex initialization schema. I'd like to fix that in a separate cl.

BUG=none
TEST=current test set.
R=yangguo@chromium.org, yurys@chromium.org

Review URL: https://codereview.chromium.org/19724007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15911 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7471ae89
......@@ -184,7 +184,7 @@ class ProfilerEventsProcessor : public Thread {
} while (false)
class CpuProfiler {
class CpuProfiler : public CodeEventListener {
public:
explicit CpuProfiler(Isolate* isolate);
......@@ -193,7 +193,7 @@ class CpuProfiler {
ProfileGenerator* test_generator,
ProfilerEventsProcessor* test_processor);
~CpuProfiler();
virtual ~CpuProfiler();
void StartProfiling(const char* title, bool record_samples = false);
void StartProfiling(String* title, bool record_samples);
......@@ -209,30 +209,30 @@ class CpuProfiler {
// Must be called via PROFILE macro, otherwise will crash when
// profiling is not enabled.
void CallbackEvent(Name* name, Address entry_point);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, const char* comment);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, Name* name);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* name);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* source, int line);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, int args_count);
void CodeMovingGCEvent() {}
void CodeMoveEvent(Address from, Address to);
void CodeDeleteEvent(Address from);
void GetterCallbackEvent(Name* name, Address entry_point);
void RegExpCodeCreateEvent(Code* code, String* source);
void SetterCallbackEvent(Name* name, Address entry_point);
void SharedFunctionInfoMoveEvent(Address from, Address to);
virtual void CallbackEvent(Name* name, Address entry_point);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, const char* comment);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, Name* name);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* name);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* source, int line);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, int args_count);
virtual void CodeMovingGCEvent() {}
virtual void CodeMoveEvent(Address from, Address to);
virtual void CodeDeleteEvent(Address from);
virtual void GetterCallbackEvent(Name* name, Address entry_point);
virtual void RegExpCodeCreateEvent(Code* code, String* source);
virtual void SetterCallbackEvent(Name* name, Address entry_point);
virtual void SharedFunctionInfoMoveEvent(Address from, Address to);
INLINE(bool is_profiling() const) { return is_profiling_; }
bool* is_profiling_address() {
......
This diff is collapsed.
......@@ -70,7 +70,7 @@ namespace internal {
// tick profiler requires code events, so --prof implies --log-code.
// Forward declarations.
class CodeAddressMap;
class CodeEventListener;
class CompilationInfo;
class CpuProfiler;
class Isolate;
......@@ -155,7 +155,6 @@ class JitLogger;
class LowLevelLogger;
class Sampler;
class Logger {
public:
#define DECLARE_ENUM(enum_item, ignore) enum_item,
......@@ -226,6 +225,11 @@ class Logger {
// ==== Events logged by --log-code. ====
void addCodeEventListener(CodeEventListener* listener);
void removeCodeEventListener(CodeEventListener* listener);
bool hasCodeEventListener(CodeEventListener* listener);
// Emits a code event for a callback function.
void CallbackEvent(Name* name, Address entry_point);
void GetterCallbackEvent(Name* name, Address entry_point);
......@@ -269,6 +273,7 @@ class Logger {
void SharedFunctionInfoMoveEvent(Address from, Address to);
void CodeNameEvent(Address addr, int pos, const char* code_name);
void SnapshotPositionEvent(Address addr, int pos);
// ==== Events logged by --log-gc. ====
......@@ -439,7 +444,7 @@ class Logger {
Log* log_;
LowLevelLogger* ll_logger_;
JitLogger* jit_logger_;
CodeAddressMap* code_address_map_;
List<CodeEventListener*> listeners_;
// Guards against multiple calls to TearDown() that can happen in some tests.
// 'true' between SetUp() and TearDown().
......@@ -462,6 +467,86 @@ class Logger {
};
class CodeEventListener {
public:
virtual ~CodeEventListener() {}
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
const char* comment) = 0;
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
Name* name) = 0;
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* name) = 0;
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* source,
int line) = 0;
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
int args_count) = 0;
virtual void CallbackEvent(Name* name, Address entry_point) = 0;
virtual void GetterCallbackEvent(Name* name, Address entry_point) = 0;
virtual void SetterCallbackEvent(Name* name, Address entry_point) = 0;
virtual void RegExpCodeCreateEvent(Code* code, String* source) = 0;
virtual void CodeMoveEvent(Address from, Address to) = 0;
virtual void CodeDeleteEvent(Address from) = 0;
virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
virtual void CodeMovingGCEvent() = 0;
};
class CodeEventLogger : public CodeEventListener {
public:
CodeEventLogger();
virtual ~CodeEventLogger();
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
const char* comment);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
Name* name);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
int args_count);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* name);
virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
CompilationInfo* info,
Name* source,
int line);
virtual void RegExpCodeCreateEvent(Code* code, String* source);
virtual void CallbackEvent(Name* name, Address entry_point) { }
virtual void GetterCallbackEvent(Name* name, Address entry_point) { }
virtual void SetterCallbackEvent(Name* name, Address entry_point) { }
virtual void SharedFunctionInfoMoveEvent(Address from, Address to) { }
virtual void CodeMovingGCEvent() { }
private:
class NameBuffer;
virtual void LogRecordedBuffer(Code* code,
SharedFunctionInfo* shared,
const char* name,
int length) = 0;
NameBuffer* name_buffer_;
};
} } // namespace v8::internal
......
......@@ -665,6 +665,141 @@ bool Serializer::serialization_enabled_ = false;
bool Serializer::too_late_to_enable_now_ = false;
class CodeAddressMap: public CodeEventLogger {
public:
explicit CodeAddressMap(Isolate* isolate)
: isolate_(isolate) {
isolate->logger()->addCodeEventListener(this);
}
virtual ~CodeAddressMap() {
isolate_->logger()->removeCodeEventListener(this);
}
virtual void CodeMoveEvent(Address from, Address to) {
address_to_name_map_.Move(from, to);
}
virtual void CodeDeleteEvent(Address from) {
address_to_name_map_.Remove(from);
}
const char* Lookup(Address address) {
return address_to_name_map_.Lookup(address);
}
private:
class NameMap {
public:
NameMap() : impl_(&PointerEquals) {}
~NameMap() {
for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
DeleteArray(static_cast<const char*>(p->value));
}
}
void Insert(Address code_address, const char* name, int name_size) {
HashMap::Entry* entry = FindOrCreateEntry(code_address);
if (entry->value == NULL) {
entry->value = CopyName(name, name_size);
}
}
const char* Lookup(Address code_address) {
HashMap::Entry* entry = FindEntry(code_address);
return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
}
void Remove(Address code_address) {
HashMap::Entry* entry = FindEntry(code_address);
if (entry != NULL) {
DeleteArray(static_cast<char*>(entry->value));
RemoveEntry(entry);
}
}
void Move(Address from, Address to) {
if (from == to) return;
HashMap::Entry* from_entry = FindEntry(from);
ASSERT(from_entry != NULL);
void* value = from_entry->value;
RemoveEntry(from_entry);
HashMap::Entry* to_entry = FindOrCreateEntry(to);
ASSERT(to_entry->value == NULL);
to_entry->value = value;
}
private:
static bool PointerEquals(void* lhs, void* rhs) {
return lhs == rhs;
}
static char* CopyName(const char* name, int name_size) {
char* result = NewArray<char>(name_size + 1);
for (int i = 0; i < name_size; ++i) {
char c = name[i];
if (c == '\0') c = ' ';
result[i] = c;
}
result[name_size] = '\0';
return result;
}
HashMap::Entry* FindOrCreateEntry(Address code_address) {
return impl_.Lookup(code_address, ComputePointerHash(code_address), true);
}
HashMap::Entry* FindEntry(Address code_address) {
return impl_.Lookup(code_address,
ComputePointerHash(code_address),
false);
}
void RemoveEntry(HashMap::Entry* entry) {
impl_.Remove(entry->key, entry->hash);
}
HashMap impl_;
DISALLOW_COPY_AND_ASSIGN(NameMap);
};
virtual void LogRecordedBuffer(Code* code,
SharedFunctionInfo*,
const char* name,
int length) {
address_to_name_map_.Insert(code->address(), name, length);
}
NameMap address_to_name_map_;
Isolate* isolate_;
};
CodeAddressMap* Serializer::code_address_map_ = NULL;
void Serializer::Enable() {
if (!serialization_enabled_) {
ASSERT(!too_late_to_enable_now_);
}
if (serialization_enabled_) return;
serialization_enabled_ = true;
i::Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
code_address_map_ = new CodeAddressMap(isolate);
}
void Serializer::Disable() {
if (!serialization_enabled_) return;
serialization_enabled_ = false;
delete code_address_map_;
code_address_map_ = NULL;
}
Deserializer::Deserializer(SnapshotByteSource* source)
: isolate_(NULL),
source_(source),
......@@ -1458,7 +1593,11 @@ void Serializer::ObjectSerializer::Serialize() {
"ObjectSerialization");
sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
LOG(i::Isolate::Current(),
ASSERT(code_address_map_);
const char* code_name = code_address_map_->Lookup(object_->address());
LOG(serializer_->isolate_,
CodeNameEvent(object_->address(), sink_->Position(), code_name));
LOG(serializer_->isolate_,
SnapshotPositionEvent(object_->address(), sink_->Position()));
// Mark this object as already serialized.
......
......@@ -459,6 +459,8 @@ class SerializationAddressMapper {
};
class CodeAddressMap;
// There can be only one serializer per V8 process.
class Serializer : public SerializerDeserializer {
public:
......@@ -472,14 +474,9 @@ class Serializer : public SerializerDeserializer {
return fullness_[space];
}
static void Enable() {
if (!serialization_enabled_) {
ASSERT(!too_late_to_enable_now_);
}
serialization_enabled_ = true;
}
static void Enable();
static void Disable();
static void Disable() { serialization_enabled_ = false; }
// Call this when you have made use of the fact that there is no serialization
// going on.
static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
......@@ -589,6 +586,7 @@ class Serializer : public SerializerDeserializer {
friend class Deserializer;
private:
static CodeAddressMap* code_address_map_;
DISALLOW_COPY_AND_ASSIGN(Serializer);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment