| Index: src/serialize.cc
|
| diff --git a/src/serialize.cc b/src/serialize.cc
|
| index dc086a6ff3fe76b940022bae714de4557438ce18..89ba1be099afc6d9a295907b54d002c7711fa5f6 100644
|
| --- a/src/serialize.cc
|
| +++ b/src/serialize.cc
|
| @@ -889,83 +889,88 @@ void Deserializer::ReadChunk(Object** current,
|
| STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
|
|
|
| #define CASE_BODY(where, how, within, space_number_if_any) \
|
| - { \
|
| - bool emit_write_barrier = false; \
|
| - bool current_was_incremented = false; \
|
| - int space_number = space_number_if_any == kAnyOldSpace ? \
|
| - (data & kSpaceMask) : space_number_if_any; \
|
| - if (where == kNewObject && how == kPlain && within == kStartOfObject) {\
|
| - ReadObject(space_number, current); \
|
| - emit_write_barrier = (space_number == NEW_SPACE); \
|
| + { \
|
| + bool emit_write_barrier = false; \
|
| + bool current_was_incremented = false; \
|
| + int space_number = space_number_if_any == kAnyOldSpace \
|
| + ? (data & kSpaceMask) \
|
| + : space_number_if_any; \
|
| + if (where == kNewObject && how == kPlain && within == kStartOfObject) { \
|
| + ReadObject(space_number, current); \
|
| + emit_write_barrier = (space_number == NEW_SPACE); \
|
| + } else { \
|
| + Object* new_object = NULL; /* May not be a real Object pointer. */ \
|
| + if (where == kNewObject) { \
|
| + ReadObject(space_number, &new_object); \
|
| + } else if (where == kRootArray) { \
|
| + int root_id = source_->GetInt(); \
|
| + new_object = isolate->heap()->roots_array_start()[root_id]; \
|
| + emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| + } else if (where == kPartialSnapshotCache) { \
|
| + int cache_index = source_->GetInt(); \
|
| + new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \
|
| + emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| + } else if (where == kExternalReference) { \
|
| + int skip = source_->GetInt(); \
|
| + current = reinterpret_cast<Object**>( \
|
| + reinterpret_cast<Address>(current) + skip); \
|
| + int reference_id = source_->GetInt(); \
|
| + Address address = external_reference_decoder_->Decode(reference_id); \
|
| + new_object = reinterpret_cast<Object*>(address); \
|
| + } else if (where == kBackref) { \
|
| + emit_write_barrier = (space_number == NEW_SPACE); \
|
| + new_object = GetAddressFromEnd(data & kSpaceMask); \
|
| + } else if (where == kBuiltin) { \
|
| + 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; \
|
| + PrintF("BUILTIN how within %d, %d\n", how, within); \
|
| + } else { \
|
| + ASSERT(where == kBackrefWithSkip); \
|
| + int skip = source_->GetInt(); \
|
| + current = reinterpret_cast<Object**>( \
|
| + reinterpret_cast<Address>(current) + skip); \
|
| + emit_write_barrier = (space_number == NEW_SPACE); \
|
| + new_object = GetAddressFromEnd(data & kSpaceMask); \
|
| + } \
|
| + if (within == kInnerPointer) { \
|
| + if (space_number != CODE_SPACE || new_object->IsCode()) { \
|
| + Code* new_code_object = reinterpret_cast<Code*>(new_object); \
|
| + new_object = \
|
| + reinterpret_cast<Object*>(new_code_object->instruction_start()); \
|
| } else { \
|
| - Object* new_object = NULL; /* May not be a real Object pointer. */ \
|
| - if (where == kNewObject) { \
|
| - ReadObject(space_number, &new_object); \
|
| - } else if (where == kRootArray) { \
|
| - int root_id = source_->GetInt(); \
|
| - new_object = isolate->heap()->roots_array_start()[root_id]; \
|
| - emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| - } else if (where == kPartialSnapshotCache) { \
|
| - int cache_index = source_->GetInt(); \
|
| - new_object = isolate->serialize_partial_snapshot_cache() \
|
| - [cache_index]; \
|
| - emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| - } else if (where == kExternalReference) { \
|
| - int skip = source_->GetInt(); \
|
| - current = reinterpret_cast<Object**>(reinterpret_cast<Address>( \
|
| - current) + skip); \
|
| - int reference_id = source_->GetInt(); \
|
| - Address address = external_reference_decoder_-> \
|
| - Decode(reference_id); \
|
| - new_object = reinterpret_cast<Object*>(address); \
|
| - } else if (where == kBackref) { \
|
| - emit_write_barrier = (space_number == NEW_SPACE); \
|
| - new_object = GetAddressFromEnd(data & kSpaceMask); \
|
| - } else { \
|
| - ASSERT(where == kBackrefWithSkip); \
|
| - int skip = source_->GetInt(); \
|
| - current = reinterpret_cast<Object**>( \
|
| - reinterpret_cast<Address>(current) + skip); \
|
| - emit_write_barrier = (space_number == NEW_SPACE); \
|
| - new_object = GetAddressFromEnd(data & kSpaceMask); \
|
| - } \
|
| - if (within == kInnerPointer) { \
|
| - if (space_number != CODE_SPACE || new_object->IsCode()) { \
|
| - Code* new_code_object = reinterpret_cast<Code*>(new_object); \
|
| - new_object = reinterpret_cast<Object*>( \
|
| - new_code_object->instruction_start()); \
|
| - } else { \
|
| - ASSERT(space_number == CODE_SPACE); \
|
| - Cell* cell = Cell::cast(new_object); \
|
| - new_object = reinterpret_cast<Object*>( \
|
| - cell->ValueAddress()); \
|
| - } \
|
| - } \
|
| - if (how == kFromCode) { \
|
| - Address location_of_branch_data = \
|
| - reinterpret_cast<Address>(current); \
|
| - Assembler::deserialization_set_special_target_at( \
|
| - location_of_branch_data, \
|
| - Code::cast(HeapObject::FromAddress(current_object_address)), \
|
| - reinterpret_cast<Address>(new_object)); \
|
| - location_of_branch_data += Assembler::kSpecialTargetSize; \
|
| - current = reinterpret_cast<Object**>(location_of_branch_data); \
|
| - current_was_incremented = true; \
|
| - } else { \
|
| - *current = new_object; \
|
| - } \
|
| - } \
|
| - if (emit_write_barrier && write_barrier_needed) { \
|
| - Address current_address = reinterpret_cast<Address>(current); \
|
| - isolate->heap()->RecordWrite( \
|
| - current_object_address, \
|
| - static_cast<int>(current_address - current_object_address)); \
|
| + ASSERT(space_number == CODE_SPACE); \
|
| + Cell* cell = Cell::cast(new_object); \
|
| + new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \
|
| } \
|
| - if (!current_was_incremented) { \
|
| - current++; \
|
| - } \
|
| - break; \
|
| } \
|
| + if (how == kFromCode) { \
|
| + Address location_of_branch_data = reinterpret_cast<Address>(current); \
|
| + Assembler::deserialization_set_special_target_at( \
|
| + location_of_branch_data, \
|
| + Code::cast(HeapObject::FromAddress(current_object_address)), \
|
| + reinterpret_cast<Address>(new_object)); \
|
| + location_of_branch_data += Assembler::kSpecialTargetSize; \
|
| + current = reinterpret_cast<Object**>(location_of_branch_data); \
|
| + current_was_incremented = true; \
|
| + } else { \
|
| + *current = new_object; \
|
| + } \
|
| + } \
|
| + if (emit_write_barrier && write_barrier_needed) { \
|
| + Address current_address = reinterpret_cast<Address>(current); \
|
| + isolate->heap()->RecordWrite( \
|
| + current_object_address, \
|
| + static_cast<int>(current_address - current_object_address)); \
|
| + } \
|
| + if (!current_was_incremented) { \
|
| + current++; \
|
| + } \
|
| + break; \
|
| + }
|
|
|
| // This generates a case and a body for the new space (which has to do extra
|
| // write barrier handling) and handles the other spaces with 8 fall-through
|
| @@ -1161,6 +1166,12 @@ void Deserializer::ReadChunk(Object** current,
|
| kFromCode,
|
| kStartOfObject,
|
| 0)
|
| + // Find a builtin and write a pointer to it to the current object.
|
| + CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0)
|
| + CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0)
|
| + // 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)
|
|
|
| #undef CASE_STATEMENT
|
| #undef CASE_BODY
|
| @@ -1717,7 +1728,7 @@ int Serializer::ObjectSerializer::OutputRawData(
|
| int up_to_offset = static_cast<int>(up_to - object_start);
|
| int to_skip = up_to_offset - bytes_processed_so_far_;
|
| int bytes_to_output = to_skip;
|
| - bytes_processed_so_far_ += to_skip;
|
| + bytes_processed_so_far_ += to_skip;
|
| // This assert will fail if the reloc info gives us the target_address_address
|
| // locations in a non-ascending order. Luckily that doesn't happen.
|
| ASSERT(to_skip >= 0);
|
| @@ -1846,7 +1857,6 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| return;
|
| }
|
|
|
| - // TODO(yangguo) wire up builtins.
|
| // TODO(yangguo) wire up stubs from stub cache.
|
| // TODO(yangguo) wire up script source.
|
| // TODO(yangguo) wire up internalized strings
|
| @@ -1854,6 +1864,14 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| // TODO(yangguo) We cannot deal with different hash seeds yet.
|
| ASSERT(!heap_object->IsHashTable());
|
|
|
| + if (heap_object->IsCode()) {
|
| + Code* code_object = Code::cast(heap_object);
|
| + if (code_object->kind() == Code::BUILTIN) {
|
| + SerializeBuiltin(code_object, how_to_code, where_to_point, skip);
|
| + return;
|
| + }
|
| + }
|
| +
|
| if (address_mapper_.IsMapped(heap_object)) {
|
| int space = SpaceOfObject(heap_object);
|
| int address = address_mapper_.MappedTo(heap_object);
|
| @@ -1873,6 +1891,27 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| }
|
|
|
|
|
| +void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
|
| + WhereToPoint where_to_point, int skip) {
|
| + if (skip != 0) {
|
| + sink_->Put(kSkip, "SkipFromSerializeBuiltin");
|
| + sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
|
| + }
|
| +
|
| + ASSERT((how_to_code == kPlain && where_to_point == kStartOfObject) ||
|
| + (how_to_code == kFromCode && where_to_point == kInnerPointer));
|
| + int id = 0;
|
| + do { // Look for existing builtins in the list.
|
| + Code* b = isolate()->builtins()->builtin(static_cast<Builtins::Name>(id));
|
| + if (builtin == b) break;
|
| + } while (++id < Builtins::builtin_count);
|
| + ASSERT(id < Builtins::builtin_count); // We must have found a one.
|
| +
|
| + sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin");
|
| + sink_->PutInt(id, "builtin_index");
|
| +}
|
| +
|
| +
|
| Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
|
| SerializedCodeData scd(data);
|
| SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
|
|
|