[snapshot][ptr-compr] Simplify deserialization of references embedded in code

... and use RelocInfo iteration instead of skip-and-unaligned-write sequences.
This is a step towards avoiding unaligned stores via UnalignedSlot.

Various cleanup CLs will follow.

Bug: v8:8794
Change-Id: I62faedfa1c1ababe4b185fa8d7f2c6c1baa5cf79
Reviewed-on: https://chromium-review.googlesource.com/c/1456579
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59443}
This commit is contained in:
Igor Sheludko 2019-02-07 17:59:22 +01:00 committed by Commit Bot
parent 7a8cd55146
commit 7e914db539
5 changed files with 197 additions and 210 deletions

View File

@ -589,22 +589,22 @@ class Code::BodyDescriptor final : public BodyDescriptorBase {
return true;
}
static constexpr int kRelocModeMask =
RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
static constexpr int kModeMask =
RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
// GC does not visit data/code in the header and in the body directly.
IteratePointers(obj, kRelocationInfoOffset, kDataStart, v);
RelocIterator it(Code::cast(obj), kModeMask);
RelocIterator it(Code::cast(obj), kRelocModeMask);
v->VisitRelocInfo(&it);
}

View File

@ -9,6 +9,7 @@
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
#include "src/log.h"
#include "src/objects-body-descriptors-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/cell-inl.h"
#include "src/objects/hash-table.h"
@ -367,6 +368,16 @@ HeapObject Deserializer::GetBackReferencedObject(int space) {
return obj;
}
HeapObject Deserializer::ReadObject() {
MaybeObject object;
// We are reading to a location outside of JS heap, so pass NEW_SPACE to
// avoid triggering write barriers.
bool filled = ReadData(UnalignedSlot(&object), UnalignedSlot(&object + 1),
NEW_SPACE, kNullAddress);
CHECK(filled);
return object.GetHeapObjectAssumeStrong();
}
HeapObject Deserializer::ReadObject(int space_number) {
const int size = source_.GetInt() << kObjectAlignmentBits;
@ -393,21 +404,114 @@ HeapObject Deserializer::ReadObject(int space_number) {
return obj;
}
void Deserializer::ReadCodeObjectBody(int space_number,
Address code_object_address) {
// At this point the code object is already allocated, its map field is
// initialized and its raw data fields and code stream are also read.
// Now we read the rest of code header's fields.
UnalignedSlot current(code_object_address + HeapObject::kHeaderSize);
UnalignedSlot limit(code_object_address + Code::kDataStart);
bool filled = ReadData(current, limit, space_number, code_object_address);
CHECK(filled);
// Now iterate RelocInfos the same way it was done by the serialzier and
// deserialize respective data into RelocInfos.
Code code = Code::cast(HeapObject::FromAddress(code_object_address));
RelocIterator it(code, Code::BodyDescriptor::kRelocModeMask);
for (; !it.done(); it.next()) {
RelocInfo rinfo = *it.rinfo();
rinfo.Visit(this);
}
}
void Deserializer::VisitCodeTarget(Code host, RelocInfo* rinfo) {
HeapObject object = ReadObject();
rinfo->set_target_address(Code::cast(object)->raw_instruction_start());
}
void Deserializer::VisitEmbeddedPointer(Code host, RelocInfo* rinfo) {
HeapObject object = ReadObject();
// Embedded object reference must be a strong one.
rinfo->set_target_object(isolate_->heap(), object);
}
void Deserializer::VisitRuntimeEntry(Code host, RelocInfo* rinfo) {
// We no longer serialize code that contains runtime entries.
UNREACHABLE();
}
void Deserializer::VisitExternalReference(Code host, RelocInfo* rinfo) {
byte data = source_.Get();
CHECK(data == kExternalReference + kPlain + kStartOfObject ||
data == kExternalReference + kFromCode + kStartOfObject);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address = external_reference_table_->address(reference_id);
DCHECK_EQ(rinfo->IsCodedSpecially(),
data == kExternalReference + kFromCode + kStartOfObject);
if (data == kExternalReference + kFromCode + kStartOfObject) {
Address location_of_branch_data = rinfo->pc();
Assembler::deserialization_set_special_target_at(location_of_branch_data,
host, address);
} else {
WriteUnalignedValue(rinfo->target_address_address(), address);
}
}
void Deserializer::VisitInternalReference(Code host, RelocInfo* rinfo) {
byte data = source_.Get();
CHECK(data == kInternalReference || data == kInternalReferenceEncoded);
// Internal reference address is not encoded via skip, but by offset
// from code entry.
int pc_offset = source_.GetInt();
int target_offset = source_.GetInt();
DCHECK(0 <= pc_offset && pc_offset <= host->raw_instruction_size());
DCHECK(0 <= target_offset && target_offset <= host->raw_instruction_size());
Address pc = host->entry() + pc_offset;
// TODO(ishell): don't encode pc_offset as it can be taken from the rinfo.
DCHECK_EQ(pc, rinfo->pc());
Address target = host->entry() + target_offset;
Assembler::deserialization_set_target_internal_reference_at(
pc, target,
data == kInternalReference ? RelocInfo::INTERNAL_REFERENCE
: RelocInfo::INTERNAL_REFERENCE_ENCODED);
}
void Deserializer::VisitOffHeapTarget(Code host, RelocInfo* rinfo) {
DCHECK(FLAG_embedded_builtins);
byte data = source_.Get();
CHECK_EQ(data, kOffHeapTarget);
int builtin_index = source_.GetInt();
DCHECK(Builtins::IsBuiltinId(builtin_index));
CHECK_NOT_NULL(isolate_->embedded_blob());
EmbeddedData d = EmbeddedData::FromBlob();
Address address = d.InstructionStartOfBuiltin(builtin_index);
CHECK_NE(kNullAddress, address);
// TODO(ishell): implement RelocInfo::set_target_off_heap_target()
if (RelocInfo::OffHeapTargetIsCodedSpecially()) {
Address location_of_branch_data = rinfo->pc();
Assembler::deserialization_set_special_target_at(location_of_branch_data,
host, address);
} else {
WriteUnalignedValue(rinfo->target_address_address(), address);
}
}
UnalignedSlot Deserializer::ReadRepeatedObject(UnalignedSlot current,
int repeat_count) {
CHECK_LE(2, repeat_count);
MaybeObject object;
// We are reading to a location outside of JS heap, so pass NEW_SPACE to
// avoid triggering write barriers.
bool filled = ReadData(UnalignedSlot(&object), UnalignedSlot(&object + 1),
NEW_SPACE, kNullAddress);
CHECK(filled);
DCHECK(HAS_HEAP_OBJECT_TAG(object.ptr()));
HeapObject object = ReadObject();
DCHECK(!Heap::InYoungGeneration(object));
for (int i = 0; i < repeat_count; i++) {
// Repeated values are not subject to the write barrier so we don't need
// to trigger it.
UnalignedCopy(current, object);
UnalignedCopy(current, object.ptr());
current.Advance();
}
return current;
@ -549,55 +653,17 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
// Find an external reference and write a pointer to it in the current
// code object.
case kExternalReference + kFromCode + kStartOfObject:
current = ReadExternalReferenceCase(kFromCode, current,
current_object_address);
UNREACHABLE();
break;
case kInternalReferenceEncoded:
case kInternalReference: {
// Internal reference address is not encoded via skip, but by offset
// from code entry.
int pc_offset = source_.GetInt();
int target_offset = source_.GetInt();
Code code = Code::cast(HeapObject::FromAddress(current_object_address));
DCHECK(0 <= pc_offset && pc_offset <= code->raw_instruction_size());
DCHECK(0 <= target_offset &&
target_offset <= code->raw_instruction_size());
Address pc = code->entry() + pc_offset;
Address target = code->entry() + target_offset;
Assembler::deserialization_set_target_internal_reference_at(
pc, target,
data == kInternalReference ? RelocInfo::INTERNAL_REFERENCE
: RelocInfo::INTERNAL_REFERENCE_ENCODED);
UNREACHABLE();
break;
}
case kOffHeapTarget: {
DCHECK(FLAG_embedded_builtins);
int skip = source_.GetInt();
int builtin_index = source_.GetInt();
DCHECK(Builtins::IsBuiltinId(builtin_index));
current.Advance(skip);
CHECK_NOT_NULL(isolate->embedded_blob());
EmbeddedData d = EmbeddedData::FromBlob();
Address address = d.InstructionStartOfBuiltin(builtin_index);
CHECK_NE(kNullAddress, address);
if (RelocInfo::OffHeapTargetIsCodedSpecially()) {
Address location_of_branch_data = current.address();
int skip = Assembler::deserialization_special_target_size(
location_of_branch_data);
Assembler::deserialization_set_special_target_at(
location_of_branch_data,
Code::cast(HeapObject::FromAddress(current_object_address)),
address);
current.Advance(skip);
} else {
UnalignedCopy(current, address);
current.Advance();
}
UNREACHABLE();
break;
}
@ -612,7 +678,7 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
case kDeferred: {
// Deferred can only occur right after the heap object header.
DCHECK_EQ(current.address(), current_object_address + kPointerSize);
DCHECK_EQ(current.address(), current_object_address + kTaggedSize);
HeapObject obj = HeapObject::FromAddress(current_object_address);
// If the deferred object is a map, its instance type may be used
// during deserialization. Initialize it with a temporary value.
@ -638,10 +704,17 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
// Deserialize raw code directly into the body of the code object.
// Do not move current.
case kVariableRawCode: {
// VariableRawCode can only occur right after the heap object header.
DCHECK_EQ(current.address(), current_object_address + kTaggedSize);
int size_in_bytes = source_.GetInt();
source_.CopyRaw(
reinterpret_cast<byte*>(current_object_address + Code::kDataStart),
size_in_bytes);
ReadCodeObjectBody(source_space, current_object_address);
// Set current to the code object end.
current.Advance(Code::kDataStart - HeapObject::kHeaderSize +
size_in_bytes);
CHECK_EQ(current, limit);
break;
}
@ -663,8 +736,6 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
}
case kApiReference: {
int skip = source_.GetInt();
current.Advance(skip);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address;
if (isolate->api_external_references()) {
@ -790,23 +861,12 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
UnalignedSlot Deserializer::ReadExternalReferenceCase(
HowToCode how, UnalignedSlot current, Address current_object_address) {
int skip = source_.GetInt();
current.Advance(skip);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address = external_reference_table_->address(reference_id);
if (how == kFromCode) {
Address location_of_branch_data = current.address();
int skip =
Assembler::deserialization_special_target_size(location_of_branch_data);
Assembler::deserialization_set_special_target_at(
location_of_branch_data,
Code::cast(HeapObject::FromAddress(current_object_address)), address);
current.Advance(skip);
} else {
UnalignedCopy(current, address);
current.Advance();
}
DCHECK_EQ(how, kPlain);
UnalignedCopy(current, address);
current.Advance();
return current;
}
@ -824,71 +884,39 @@ UnalignedSlot Deserializer::ReadDataCase(Isolate* isolate,
? HeapObjectReferenceType::WEAK
: HeapObjectReferenceType::STRONG;
if (where == kNewObject && how == kPlain && within == kStartOfObject) {
if (where == kNewObject) {
heap_object = ReadObject(space_number);
emit_write_barrier = (space_number == NEW_SPACE);
} else if (where == kBackref) {
emit_write_barrier = (space_number == NEW_SPACE);
heap_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kBackrefWithSkip) {
int skip = source_.GetInt();
current.Advance(skip);
emit_write_barrier = (space_number == NEW_SPACE);
heap_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kRootArray) {
int id = source_.GetInt();
RootIndex root_index = static_cast<RootIndex>(id);
heap_object = HeapObject::cast(isolate->root(root_index));
emit_write_barrier = Heap::InYoungGeneration(heap_object);
hot_objects_.Add(heap_object);
} else if (where == kReadOnlyObjectCache) {
int cache_index = source_.GetInt();
heap_object =
HeapObject::cast(isolate->read_only_object_cache()->at(cache_index));
DCHECK(!Heap::InYoungGeneration(heap_object));
emit_write_barrier = false;
} else if (where == kPartialSnapshotCache) {
int cache_index = source_.GetInt();
heap_object =
HeapObject::cast(isolate->partial_snapshot_cache()->at(cache_index));
emit_write_barrier = Heap::InYoungGeneration(heap_object);
} else {
if (where == kNewObject) {
heap_object = ReadObject(space_number);
emit_write_barrier = (space_number == NEW_SPACE);
} else if (where == kBackref) {
emit_write_barrier = (space_number == NEW_SPACE);
heap_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kBackrefWithSkip) {
int skip = source_.GetInt();
current.Advance(skip);
emit_write_barrier = (space_number == NEW_SPACE);
heap_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kRootArray) {
int id = source_.GetInt();
RootIndex root_index = static_cast<RootIndex>(id);
heap_object = HeapObject::cast(isolate->root(root_index));
emit_write_barrier = Heap::InYoungGeneration(heap_object);
hot_objects_.Add(heap_object);
} else if (where == kReadOnlyObjectCache) {
int cache_index = source_.GetInt();
heap_object =
HeapObject::cast(isolate->read_only_object_cache()->at(cache_index));
DCHECK(!Heap::InYoungGeneration(heap_object));
emit_write_barrier = false;
} else if (where == kPartialSnapshotCache) {
int cache_index = source_.GetInt();
heap_object =
HeapObject::cast(isolate->partial_snapshot_cache()->at(cache_index));
emit_write_barrier = Heap::InYoungGeneration(heap_object);
} else {
DCHECK_EQ(where, kAttachedReference);
int index = source_.GetInt();
heap_object = *attached_objects_[index];
emit_write_barrier = Heap::InYoungGeneration(heap_object);
}
if (how == kFromCode) {
Address value;
if (within == kInnerPointer) {
if (heap_object->IsCode()) {
value = Code::cast(heap_object)->raw_instruction_start();
} else {
value = Cell::cast(heap_object)->ValueAddress();
}
} else {
value = heap_object->ptr();
}
DCHECK_EQ(reference_type, HeapObjectReferenceType::STRONG);
Address location_of_branch_data = current.address();
int skip = Assembler::deserialization_special_target_size(
location_of_branch_data);
Assembler::deserialization_set_special_target_at(
location_of_branch_data,
Code::cast(HeapObject::FromAddress(current_object_address)), value);
current.Advance(skip);
// Nothing else to be done in this case.
DCHECK(!write_barrier_needed);
return current;
} else {
DCHECK_EQ(how, kPlain);
DCHECK_EQ(within, kStartOfObject);
}
DCHECK_EQ(where, kAttachedReference);
int index = source_.GetInt();
heap_object = *attached_objects_[index];
emit_write_barrier = Heap::InYoungGeneration(heap_object);
}
HeapObjectReference heap_object_ref =
reference_type == HeapObjectReferenceType::STRONG

View File

@ -136,8 +136,19 @@ class Deserializer : public SerializerDeserializer {
inline UnalignedSlot ReadExternalReferenceCase(
HowToCode how, UnalignedSlot current, Address current_object_address);
HeapObject ReadObject();
HeapObject ReadObject(int space_number);
void ReadCodeObjectBody(int space_number, Address code_object_address);
public:
void VisitCodeTarget(Code host, RelocInfo* rinfo);
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo);
void VisitRuntimeEntry(Code host, RelocInfo* rinfo);
void VisitExternalReference(Code host, RelocInfo* rinfo);
void VisitInternalReference(Code host, RelocInfo* rinfo);
void VisitOffHeapTarget(Code host, RelocInfo* rinfo);
private:
UnalignedSlot ReadRepeatedObject(UnalignedSlot current, int repeat_count);
// Special handling for serialized code like hooking up internalized strings.

View File

@ -147,12 +147,8 @@ bool Serializer::SerializeHotObject(HeapObject obj, HowToCode how_to_code,
obj->ShortPrint();
PrintF("\n");
}
if (skip != 0) {
sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
sink_.PutInt(skip, "HotObjectSkipDistance");
} else {
sink_.Put(kHotObject + index, "HotObject");
}
// TODO(ishell): remove kHotObjectWithSkip
sink_.Put(kHotObject + index, "HotObject");
return true;
}
@ -182,13 +178,8 @@ bool Serializer::SerializeBackReference(HeapObject obj, HowToCode how_to_code,
PutAlignmentPrefix(obj);
AllocationSpace space = reference.space();
if (skip == 0) {
sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef");
} else {
sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space,
"BackRefWithSkip");
sink_.PutInt(skip, "BackRefSkipDistance");
}
// TODO(ishell): remove kBackrefWithSkip
sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef");
PutBackReference(obj, reference);
}
return true;
@ -219,12 +210,8 @@ void Serializer::PutRoot(RootIndex root, HeapObject object,
if (how_to_code == kPlain && where_to_point == kStartOfObject &&
root_index < kNumberOfRootArrayConstants &&
!Heap::InYoungGeneration(object)) {
if (skip == 0) {
sink_.Put(kRootArrayConstants + root_index, "RootConstant");
} else {
sink_.Put(kRootArrayConstantsWithSkip + root_index, "RootConstant");
sink_.PutInt(skip, "SkipInPutRoot");
}
// TODO(ishell): remove kRootArrayConstantsWithSkip
sink_.Put(kRootArrayConstants + root_index, "RootConstant");
} else {
FlushSkip(skip);
sink_.Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
@ -735,7 +722,8 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host,
void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code host,
RelocInfo* rinfo) {
int skip = SkipTo(rinfo->target_address_address());
// TODO(ishell): remove skip parameter from bytecode.
int skip = 0;
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
Object object = rinfo->target_object();
serializer_->SerializeObject(HeapObject::cast(object), how_to_code,
@ -745,7 +733,12 @@ void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code host,
void Serializer::ObjectSerializer::VisitExternalReference(Foreign host,
Address* p) {
int skip = SkipTo(reinterpret_cast<Address>(p));
// TODO(ishell): handle gap between map field and payload field
// once we shrink kTaggedSize.
STATIC_ASSERT(static_cast<int>(Foreign::kForeignAddressOffset) ==
static_cast<int>(HeapObject::kHeaderSize));
DCHECK_EQ(0, SkipTo(reinterpret_cast<Address>(p)));
Address target = *p;
auto encoded_reference = serializer_->EncodeExternalReference(target);
if (encoded_reference.is_from_api()) {
@ -753,14 +746,12 @@ void Serializer::ObjectSerializer::VisitExternalReference(Foreign host,
} else {
sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
}
sink_->PutInt(skip, "SkipB4ExternalRef");
sink_->PutInt(encoded_reference.index(), "reference index");
bytes_processed_so_far_ += kSystemPointerSize;
}
void Serializer::ObjectSerializer::VisitExternalReference(Code host,
RelocInfo* rinfo) {
int skip = SkipTo(rinfo->target_address_address());
Address target = rinfo->target_external_reference();
auto encoded_reference = serializer_->EncodeExternalReference(target);
if (encoded_reference.is_from_api()) {
@ -771,7 +762,6 @@ void Serializer::ObjectSerializer::VisitExternalReference(Code host,
sink_->Put(kExternalReference + how_to_code + kStartOfObject,
"ExternalRef");
}
sink_->PutInt(skip, "SkipB4ExternalRef");
DCHECK_NE(target, kNullAddress); // Code does not reference null.
sink_->PutInt(encoded_reference.index(), "reference index");
bytes_processed_so_far_ += rinfo->target_address_size();
@ -802,15 +792,8 @@ void Serializer::ObjectSerializer::VisitInternalReference(Code host,
void Serializer::ObjectSerializer::VisitRuntimeEntry(Code host,
RelocInfo* rinfo) {
int skip = SkipTo(rinfo->target_address_address());
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
Address target = rinfo->target_address();
auto encoded_reference = serializer_->EncodeExternalReference(target);
DCHECK(!encoded_reference.is_from_api());
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
sink_->PutInt(skip, "SkipB4ExternalRef");
sink_->PutInt(encoded_reference.index(), "reference index");
bytes_processed_so_far_ += rinfo->target_address_size();
// We no longer serialize code that contains runtime entries.
UNREACHABLE();
}
void Serializer::ObjectSerializer::VisitOffHeapTarget(Code host,
@ -824,48 +807,18 @@ void Serializer::ObjectSerializer::VisitOffHeapTarget(Code host,
Code target = InstructionStream::TryLookupCode(serializer_->isolate(), addr);
CHECK(Builtins::IsIsolateIndependentBuiltin(target));
int skip = SkipTo(rinfo->target_address_address());
sink_->Put(kOffHeapTarget, "OffHeapTarget");
sink_->PutInt(skip, "SkipB4OffHeapTarget");
sink_->PutInt(target->builtin_index(), "builtin index");
bytes_processed_so_far_ += rinfo->target_address_size();
}
namespace {
class CompareRelocInfo {
public:
bool operator()(RelocInfo x, RelocInfo y) {
// Everything that does not use target_address_address will compare equal.
Address x_num = 0;
Address y_num = 0;
if (x.HasTargetAddressAddress()) x_num = x.target_address_address();
if (y.HasTargetAddressAddress()) y_num = y.target_address_address();
return x_num > y_num;
}
};
} // namespace
void Serializer::ObjectSerializer::VisitRelocInfo(RelocIterator* it) {
std::priority_queue<RelocInfo, std::vector<RelocInfo>, CompareRelocInfo>
reloc_queue;
for (; !it->done(); it->next()) {
reloc_queue.push(*it->rinfo());
}
while (!reloc_queue.empty()) {
RelocInfo rinfo = reloc_queue.top();
reloc_queue.pop();
rinfo.Visit(this);
}
}
void Serializer::ObjectSerializer::VisitCodeTarget(Code host,
RelocInfo* rinfo) {
#ifdef V8_TARGET_ARCH_ARM
DCHECK(!RelocInfo::IsRelativeCodeTarget(rinfo->rmode()));
#endif
int skip = SkipTo(rinfo->target_address_address());
// TODO(ishell): remove skip parameter from bytecode.
int skip = 0;
Code object = Code::GetCodeFromTargetAddress(rinfo->target_address());
serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip);
bytes_processed_so_far_ += rinfo->target_address_size();

View File

@ -227,10 +227,7 @@ class Serializer : public SerializerDeserializer {
bool ObjectIsBytecodeHandler(HeapObject obj) const;
static inline void FlushSkip(SnapshotByteSink* sink, int skip) {
if (skip != 0) {
sink->Put(kSkip, "SkipFromSerializeObject");
sink->PutInt(skip, "SkipDistanceFromSerializeObject");
}
// TODO(ishell): remove kSkip and friends as they are no longer needed.
}
inline void FlushSkip(int skip) { FlushSkip(&sink_, skip); }
@ -335,8 +332,6 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
void VisitCodeTarget(Code host, RelocInfo* target) override;
void VisitRuntimeEntry(Code host, RelocInfo* reloc) override;
void VisitOffHeapTarget(Code host, RelocInfo* target) override;
// Relocation info needs to be visited sorted by target_address_address.
void VisitRelocInfo(RelocIterator* it) override;
private:
void SerializePrologue(AllocationSpace space, int size, Map map);