Index: src/serialize.cc |
diff --git a/src/serialize.cc b/src/serialize.cc |
index ad56d3613289a4c673c9f2b1b2c0fa4e7a206129..6c5a620a4181def5ac64f7daff5bb89e78b5f87b 100644 |
--- a/src/serialize.cc |
+++ b/src/serialize.cc |
@@ -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. |