diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-02-03 09:06:03 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-02-03 09:07:02 -0800 |
commit | c7cb4daa25966e4f9af3c6d5499d762736454da9 (patch) | |
tree | 27c6541f5a1207eb74797ed63a43126c9bf2ba81 /deps/v8/src/serialize.h | |
parent | c723acc72192334a62bea6ff4baa33aab0da50ad (diff) | |
download | node-new-c7cb4daa25966e4f9af3c6d5499d762736454da9.tar.gz |
Upgrade V8 to 2.1.0
Diffstat (limited to 'deps/v8/src/serialize.h')
-rw-r--r-- | deps/v8/src/serialize.h | 169 |
1 files changed, 150 insertions, 19 deletions
diff --git a/deps/v8/src/serialize.h b/deps/v8/src/serialize.h index b32f4e811c..ce3b0061c2 100644 --- a/deps/v8/src/serialize.h +++ b/deps/v8/src/serialize.h @@ -147,6 +147,8 @@ class SnapshotByteSource { return position_ == length_; } + int position() { return position_; } + private: const byte* data_; int length_; @@ -183,9 +185,14 @@ class SnapshotByteSource { f(14, 32) \ f(15, 36) -// The SerDes class is a common superclass for Serializer and Deserializer -// which is used to store common constants and methods used by both. -class SerDes: public ObjectVisitor { +// The Serializer/Deserializer class is a common superclass for Serializer and +// Deserializer which is used to store common constants and methods used by +// both. +class SerializerDeserializer: public ObjectVisitor { + public: + static void Iterate(ObjectVisitor* visitor); + static void SetSnapshotCacheSize(int size); + protected: enum DataType { RAW_DATA_SERIALIZATION = 0, @@ -200,7 +207,8 @@ class SerDes: public ObjectVisitor { START_NEW_PAGE_SERIALIZATION = 37, NATIVES_STRING_RESOURCE = 38, ROOT_SERIALIZATION = 39, - // Free: 40-47. + PARTIAL_SNAPSHOT_CACHE_ENTRY = 40, + // Free: 41-47. BACKREF_SERIALIZATION = 48, // One per space, must be kSpaceMask aligned. // Free: 57-63. @@ -225,20 +233,28 @@ class SerDes: public ObjectVisitor { static inline bool SpaceIsPaged(int space) { return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; } + + static int partial_snapshot_cache_length_; + static const int kPartialSnapshotCacheCapacity = 1024; + static Object* partial_snapshot_cache_[]; }; // A Deserializer reads a snapshot and reconstructs the Object graph it defines. -class Deserializer: public SerDes { +class Deserializer: public SerializerDeserializer { public: // Create a deserializer from a snapshot byte source. explicit Deserializer(SnapshotByteSource* source); - virtual ~Deserializer() { } + virtual ~Deserializer(); // Deserialize the snapshot into an empty heap. void Deserialize(); + + // Deserialize a single object and the objects reachable from it. + void DeserializePartial(Object** root); + #ifdef DEBUG virtual void Synchronize(const char* tag); #endif @@ -264,10 +280,10 @@ class Deserializer: public SerDes { // (In large object space we are keeping track of individual objects // rather than pages.) In new space we just need the address of the // first object and the others will flow from that. - List<Address> pages_[SerDes::kNumberOfSpaces]; + List<Address> pages_[SerializerDeserializer::kNumberOfSpaces]; SnapshotByteSource* source_; - ExternalReferenceDecoder* external_reference_decoder_; + static ExternalReferenceDecoder* external_reference_decoder_; // This is the address of the next object that will be allocated in each // space. It is used to calculate the addresses of back-references. Address high_water_[LAST_SPACE + 1]; @@ -288,21 +304,71 @@ class SnapshotByteSink { Put(byte, description); } void PutInt(uintptr_t integer, const char* description); + virtual int Position() = 0; }; -class Serializer : public SerDes { +// Mapping objects to their location after deserialization. +// This is used during building, but not at runtime by V8. +class SerializationAddressMapper { + public: + SerializationAddressMapper() + : serialization_map_(new HashMap(&SerializationMatchFun)), + no_allocation_(new AssertNoAllocation()) { } + + ~SerializationAddressMapper() { + delete serialization_map_; + delete no_allocation_; + } + + bool IsMapped(HeapObject* obj) { + return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; + } + + int MappedTo(HeapObject* obj) { + ASSERT(IsMapped(obj)); + return static_cast<int>(reinterpret_cast<intptr_t>( + serialization_map_->Lookup(Key(obj), Hash(obj), false)->value)); + } + + void AddMapping(HeapObject* obj, int to) { + ASSERT(!IsMapped(obj)); + HashMap::Entry* entry = + serialization_map_->Lookup(Key(obj), Hash(obj), true); + entry->value = Value(to); + } + + private: + static bool SerializationMatchFun(void* key1, void* key2) { + return key1 == key2; + } + + static uint32_t Hash(HeapObject* obj) { + return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); + } + + static void* Key(HeapObject* obj) { + return reinterpret_cast<void*>(obj->address()); + } + + static void* Value(int v) { + return reinterpret_cast<void*>(v); + } + + HashMap* serialization_map_; + AssertNoAllocation* no_allocation_; + DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper); +}; + + +class Serializer : public SerializerDeserializer { public: explicit Serializer(SnapshotByteSink* sink); - // Serialize the current state of the heap. - void Serialize(); - // Serialize a single object and the objects reachable from it. - void SerializePartial(Object** obj); void VisitPointers(Object** start, Object** end); // You can call this after serialization to find out how much space was used // in each space. int CurrentAllocationAddress(int space) { - if (SpaceIsLarge(space)) space = LO_SPACE; + if (SpaceIsLarge(space)) return large_object_total_; return fullness_[space]; } @@ -318,15 +384,20 @@ class Serializer : public SerDes { // going on. static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } static bool enabled() { return serialization_enabled_; } + SerializationAddressMapper* address_mapper() { return &address_mapper_; } #ifdef DEBUG virtual void Synchronize(const char* tag); #endif - private: + protected: enum ReferenceRepresentation { TAGGED_REPRESENTATION, // A tagged object reference. CODE_TARGET_REPRESENTATION // A reference to first instruction in target. }; + static const int kInvalidRootIndex = -1; + virtual int RootIndex(HeapObject* heap_object) = 0; + virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; + class ObjectSerializer : public ObjectVisitor { public: ObjectSerializer(Serializer* serializer, @@ -362,7 +433,12 @@ class Serializer : public SerDes { int bytes_processed_so_far_; }; - void SerializeObject(Object* o, ReferenceRepresentation representation); + virtual void SerializeObject(Object* o, + ReferenceRepresentation representation) = 0; + void SerializeReferenceToPreviousObject( + int space, + int address, + ReferenceRepresentation reference_representation); void InitializeAllocators(); // This will return the space for an object. If the object is in large // object space it may return kLargeCode or kLargeFixedArray in order @@ -377,8 +453,6 @@ class Serializer : public SerDes { int EncodeExternalReference(Address addr) { return external_reference_encoder_->Encode(addr); } - int RootIndex(HeapObject* heap_object); - static const int kInvalidRootIndex = -1; // Keep track of the fullness of each space in order to generate // relative addresses for back references. Large objects are @@ -388,10 +462,11 @@ class Serializer : public SerDes { SnapshotByteSink* sink_; int current_root_index_; ExternalReferenceEncoder* external_reference_encoder_; - bool partial_; static bool serialization_enabled_; // Did we already make use of the fact that serialization was not enabled? static bool too_late_to_enable_now_; + int large_object_total_; + SerializationAddressMapper address_mapper_; friend class ObjectSerializer; friend class Deserializer; @@ -399,6 +474,62 @@ class Serializer : public SerDes { DISALLOW_COPY_AND_ASSIGN(Serializer); }; + +class PartialSerializer : public Serializer { + public: + PartialSerializer(Serializer* startup_snapshot_serializer, + SnapshotByteSink* sink) + : Serializer(sink), + startup_serializer_(startup_snapshot_serializer) { + } + + // Serialize the objects reachable from a single object pointer. + virtual void Serialize(Object** o); + virtual void SerializeObject(Object* o, + ReferenceRepresentation representation); + + protected: + virtual int RootIndex(HeapObject* o); + virtual int PartialSnapshotCacheIndex(HeapObject* o); + virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { + return o->IsString() || o->IsSharedFunctionInfo(); + } + + private: + Serializer* startup_serializer_; + DISALLOW_COPY_AND_ASSIGN(PartialSerializer); +}; + + +class StartupSerializer : public Serializer { + public: + explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) { + // Clear the cache of objects used by the partial snapshot. After the + // strong roots have been serialized we can create a partial snapshot + // which will repopulate the cache with objects neede by that partial + // snapshot. + partial_snapshot_cache_length_ = 0; + } + // Serialize the current state of the heap. The order is: + // 1) Strong references. + // 2) Partial snapshot cache. + // 3) Weak references (eg the symbol table). + virtual void SerializeStrongReferences(); + virtual void SerializeObject(Object* o, + ReferenceRepresentation representation); + void SerializeWeakReferences(); + void Serialize() { + SerializeStrongReferences(); + SerializeWeakReferences(); + } + + private: + virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } + virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { + return false; + } +}; + } } // namespace v8::internal #endif // V8_SERIALIZE_H_ |