Chromium Code Reviews| Index: src/serialize.cc |
| diff --git a/src/serialize.cc b/src/serialize.cc |
| index ad56d3613289a4c673c9f2b1b2c0fa4e7a206129..4958ade1a4532a73699324fb5450aa5fbf0f4c5d 100644 |
| --- a/src/serialize.cc |
| +++ b/src/serialize.cc |
| @@ -665,6 +665,139 @@ 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()->addLogger(this); |
| + } |
| + |
| + virtual ~CodeAddressMap() { |
| + isolate_->logger()->removeLogger(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_); |
| + } |
|
yurys
2013/07/26 08:04:54
Should return early in else branch.
|
| + i::Isolate* isolate = Isolate::Current(); |
| + isolate->InitializeLoggingAndCounters(); |
| + code_address_map_ = new CodeAddressMap(isolate); |
| + serialization_enabled_ = true; |
| +} |
| + |
| + |
| +void Serializer::Disable() { |
| + serialization_enabled_ = false; |
|
yurys
2013/07/26 08:04:54
ASSERT(serialization_enabled_) ?
|
| + delete code_address_map_; |
| + code_address_map_ = NULL; |
| +} |
| + |
| + |
| Deserializer::Deserializer(SnapshotByteSource* source) |
| : isolate_(NULL), |
| source_(source), |
| @@ -1458,6 +1591,10 @@ void Serializer::ObjectSerializer::Serialize() { |
| "ObjectSerialization"); |
| sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
| + ASSERT(code_address_map_); |
| + const char* code_name = code_address_map_->Lookup(object_->address()); |
| + LOG(i::Isolate::Current(), |
| + CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
| LOG(i::Isolate::Current(), |
| SnapshotPositionEvent(object_->address(), sink_->Position())); |