| Index: src/serialize.cc
|
| diff --git a/src/serialize.cc b/src/serialize.cc
|
| index fe84894ef6f780dd7c2211e4483db5050692aa96..5e75ee569d373acebcfa466f8dc669fa4ccba508 100644
|
| --- a/src/serialize.cc
|
| +++ b/src/serialize.cc
|
| @@ -718,7 +718,7 @@ class CodeAddressMap: public CodeEventLogger {
|
|
|
| Deserializer::Deserializer(SnapshotByteSource* source)
|
| : isolate_(NULL),
|
| - deserialize_code_(false),
|
| + attached_objects_(NULL),
|
| source_(source),
|
| external_reference_decoder_(NULL) {
|
| for (int i = 0; i < LAST_SPACE + 1; i++) {
|
| @@ -905,7 +905,7 @@ void Deserializer::ReadObject(int space_number,
|
| if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
|
|
|
| // Fix up strings from serialized user code.
|
| - if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj);
|
| + if (deserializing_user_code()) obj = ProcessObjectFromSerializedCode(obj);
|
|
|
| *write_back = obj;
|
| #ifdef DEBUG
|
| @@ -971,13 +971,18 @@ void Deserializer::ReadChunk(Object** current,
|
| emit_write_barrier = (space_number == NEW_SPACE); \
|
| new_object = GetAddressFromEnd(data & kSpaceMask); \
|
| } else if (where == kBuiltin) { \
|
| - ASSERT(deserialize_code_); \
|
| + ASSERT(deserializing_user_code()); \
|
| int builtin_id = source_->GetInt(); \
|
| ASSERT_LE(0, builtin_id); \
|
| ASSERT_LT(builtin_id, Builtins::builtin_count); \
|
| Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
|
| new_object = isolate->builtins()->builtin(name); \
|
| emit_write_barrier = false; \
|
| + } else if (where == kAttachedReference) { \
|
| + ASSERT(deserializing_user_code()); \
|
| + int index = source_->GetInt(); \
|
| + new_object = attached_objects_->at(index); \
|
| + emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| } else { \
|
| ASSERT(where == kBackrefWithSkip); \
|
| int skip = source_->GetInt(); \
|
| @@ -1222,6 +1227,10 @@ void Deserializer::ReadChunk(Object** current,
|
| // Find a builtin and write a pointer to it in the current code object.
|
| CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
|
| CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
|
| + // Find an object in the attached references and write a pointer to it to
|
| + // the current object.
|
| + CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0)
|
| + CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0)
|
|
|
| #undef CASE_STATEMENT
|
| #undef CASE_BODY
|
| @@ -1875,12 +1884,13 @@ void Serializer::InitializeCodeAddressMap() {
|
| }
|
|
|
|
|
| -ScriptData* CodeSerializer::Serialize(Handle<SharedFunctionInfo> info) {
|
| +ScriptData* CodeSerializer::Serialize(Isolate* isolate,
|
| + Handle<SharedFunctionInfo> info,
|
| + Handle<String> source) {
|
| // Serialize code object.
|
| List<byte> payload;
|
| ListSnapshotSink list_sink(&payload);
|
| - CodeSerializer cs(info->GetIsolate(), &list_sink);
|
| - DisallowHeapAllocation no_gc;
|
| + CodeSerializer cs(isolate, &list_sink, *source);
|
| Object** location = Handle<Object>::cast(info).location();
|
| cs.VisitPointer(location);
|
| cs.Pad();
|
| @@ -1908,10 +1918,18 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| }
|
|
|
| // TODO(yangguo) wire up stubs from stub cache.
|
| - // TODO(yangguo) wire up script source.
|
| + // TODO(yangguo) wire up global object.
|
| // TODO(yangguo) We cannot deal with different hash seeds yet.
|
| ASSERT(!heap_object->IsHashTable());
|
|
|
| + if (address_mapper_.IsMapped(heap_object)) {
|
| + int space = SpaceOfObject(heap_object);
|
| + int address = address_mapper_.MappedTo(heap_object);
|
| + SerializeReferenceToPreviousObject(space, address, how_to_code,
|
| + where_to_point, skip);
|
| + return;
|
| + }
|
| +
|
| if (heap_object->IsCode()) {
|
| Code* code_object = Code::cast(heap_object);
|
| if (code_object->kind() == Code::BUILTIN) {
|
| @@ -1920,11 +1938,8 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| }
|
| }
|
|
|
| - if (address_mapper_.IsMapped(heap_object)) {
|
| - int space = SpaceOfObject(heap_object);
|
| - int address = address_mapper_.MappedTo(heap_object);
|
| - SerializeReferenceToPreviousObject(space, address, how_to_code,
|
| - where_to_point, skip);
|
| + if (heap_object == source_) {
|
| + SerializeSourceObject(how_to_code, where_to_point, skip);
|
| return;
|
| }
|
|
|
| @@ -1960,21 +1975,42 @@ void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
|
| }
|
|
|
|
|
| -Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
|
| +void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
|
| + WhereToPoint where_to_point,
|
| + int skip) {
|
| + if (skip != 0) {
|
| + sink_->Put(kSkip, "SkipFromSerializeSourceObject");
|
| + sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
|
| + }
|
| +
|
| + ASSERT(how_to_code == kPlain && where_to_point == kStartOfObject);
|
| + sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
|
| + sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
|
| +}
|
| +
|
| +
|
| +Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
|
| + ScriptData* data,
|
| + Handle<String> source) {
|
| SerializedCodeData scd(data);
|
| SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
|
| Deserializer deserializer(&payload);
|
| - deserializer.ExpectSerializedCode();
|
| STATIC_ASSERT(NEW_SPACE == 0);
|
| // TODO(yangguo) what happens if remaining new space is too small?
|
| for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
|
| deserializer.set_reservation(i, scd.GetReservation(i));
|
| }
|
| + DisallowHeapAllocation no_gc;
|
| +
|
| + // Prepare and register list of attached objects.
|
| + List<Object*> attached_objects(1);
|
| + attached_objects.Set(kSourceObjectIndex, *source);
|
| + deserializer.SetAttachedObjects(&attached_objects);
|
| +
|
| Object* root;
|
| deserializer.DeserializePartial(isolate, &root);
|
| deserializer.FlushICacheForNewCodeObjects();
|
| - ASSERT(root->IsSharedFunctionInfo());
|
| - return root;
|
| + return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate);
|
| }
|
|
|
|
|
|
|