Chromium Code Reviews| Index: src/serialize.cc |
| =================================================================== |
| --- src/serialize.cc (revision 3358) |
| +++ src/serialize.cc (working copy) |
| @@ -44,6 +44,70 @@ |
| namespace v8 { |
| namespace internal { |
| +// Mapping objects to their location after deserialization. |
| +// This is used during building, but not at runtime by V8. |
| +class SerializationAddressMapper { |
| + public: |
| + static bool IsMapped(HeapObject* obj) { |
| + MapExists(); |
| + return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; |
| + } |
| + |
| + static int MappedTo(HeapObject* obj) { |
| + ASSERT(IsMapped(obj)); |
| + return reinterpret_cast<int>(serialization_map_->Lookup(Key(obj), |
| + Hash(obj), |
| + false)->value); |
| + } |
| + |
| + static void Map(HeapObject* obj, int to) { |
| + MapExists(); |
| + ASSERT(!IsMapped(obj)); |
| + HashMap::Entry* entry = |
| + serialization_map_->Lookup(Key(obj), Hash(obj), true); |
| + entry->value = Value(to); |
| + } |
| + |
| + static void Zap() { |
| + if (serialization_map_ != NULL) { |
| + delete serialization_map_; |
| + } |
| + serialization_map_ = NULL; |
| + } |
| + |
| + private: |
| + static bool SerializationMatchFun(void* key1, void* key2) { |
| + return key1 == key2; |
| + } |
| + |
| + static uint32_t Hash(HeapObject* obj) { |
| + return reinterpret_cast<uint32_t>(obj->address()); |
| + } |
| + |
| + static void* Key(HeapObject* obj) { |
| + return reinterpret_cast<void*>(obj->address()); |
| + } |
| + |
| + static void* Value(int v) { |
| + return reinterpret_cast<void*>(v); |
| + } |
| + |
| + // Saying it makes it so. |
| + static void MapExists() { |
|
Kasper Lund
2009/11/25 12:52:03
EnsureMapExists?
|
| + if (serialization_map_ == NULL) { |
| + serialization_map_ = new HashMap(&SerializationMatchFun); |
| + } |
| + } |
| + |
| + static HashMap* serialization_map_; |
| +}; |
| + |
| + |
| +HashMap* SerializationAddressMapper::serialization_map_ = NULL; |
| + |
| + |
| + |
| + |
| // ----------------------------------------------------------------------------- |
| // Coding of external references. |
| @@ -871,6 +935,7 @@ |
| Heap::IterateRoots(this, VISIT_ONLY_STRONG); |
| delete external_reference_encoder_; |
| external_reference_encoder_ = NULL; |
| + SerializationAddressMapper::Zap(); |
| } |
| @@ -894,10 +959,9 @@ |
| ReferenceRepresentation reference_representation) { |
| CHECK(o->IsHeapObject()); |
| HeapObject* heap_object = HeapObject::cast(o); |
| - MapWord map_word = heap_object->map_word(); |
| - if (map_word.IsSerializationAddress()) { |
| + if (SerializationAddressMapper::IsMapped(heap_object)) { |
| int space = SpaceOfAlreadySerializedObject(heap_object); |
| - int address = map_word.ToSerializationAddress(); |
| + int address = SerializationAddressMapper::MappedTo(heap_object); |
| int offset = CurrentAllocationAddress(space) - address; |
| bool from_start = true; |
| if (SpaceIsPaged(space)) { |
| @@ -965,24 +1029,23 @@ |
| } |
| sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
| - // Get the map before overwriting it. |
| - Map* map = object_->map(); |
| // Mark this object as already serialized. |
| bool start_new_page; |
| - object_->set_map_word(MapWord::FromSerializationAddress( |
| - serializer_->Allocate(space, size, &start_new_page))); |
| + SerializationAddressMapper::Map( |
| + object_, |
| + serializer_->Allocate(space, size, &start_new_page)); |
| if (start_new_page) { |
| sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage"); |
| sink_->PutSection(space, "NewPageSpace"); |
| } |
| // Serialize the map (first word of the object). |
| - serializer_->SerializeObject(map, TAGGED_REPRESENTATION); |
| + serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION); |
| // Serialize the rest of the object. |
| CHECK_EQ(0, bytes_processed_so_far_); |
| bytes_processed_so_far_ = kPointerSize; |
| - object_->IterateBody(map->instance_type(), size, this); |
| + object_->IterateBody(object_->map()->instance_type(), size, this); |
| OutputRawData(object_->address() + size); |
| } |
| @@ -1044,12 +1107,9 @@ |
| Address references_start = reinterpret_cast<Address>(resource_pointer); |
| OutputRawData(references_start); |
| for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { |
| - // Use raw_unchecked when maps are munged. |
| - Object* source = Heap::raw_unchecked_natives_source_cache()->get(i); |
| + Object* source = Heap::natives_source_cache()->get(i); |
| if (!source->IsUndefined()) { |
| - // Don't use cast when maps are munged. |
| - ExternalAsciiString* string = |
| - reinterpret_cast<ExternalAsciiString*>(source); |
| + ExternalAsciiString* string = ExternalAsciiString::cast(source); |
| typedef v8::String::ExternalAsciiStringResource Resource; |
| Resource* resource = string->resource(); |
| if (resource == *resource_pointer) { |