[snapshot][cleanup] Remove HowToCode flag from bytecodes

... as it's no longer needed.

Bug: v8:8794, v8:8562
Change-Id: Ia5149bab33af219e5cdc6909af4688e53f1409fa
Reviewed-on: https://chromium-review.googlesource.com/c/1460458
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59463}
This commit is contained in:
Igor Sheludko 2019-02-08 03:43:42 +01:00 committed by Commit Bot
parent 8a526a4153
commit 37e632b119
14 changed files with 124 additions and 185 deletions

View File

@ -96,8 +96,7 @@ ScriptData* CodeSerializer::SerializeSharedFunctionInfo(
return data.GetScriptData();
}
bool CodeSerializer::SerializeReadOnlyObject(HeapObject obj,
HowToCode how_to_code) {
bool CodeSerializer::SerializeReadOnlyObject(HeapObject obj) {
PagedSpace* read_only_space = isolate()->heap()->read_only_space();
if (!read_only_space->Contains(obj)) return false;
@ -115,18 +114,18 @@ bool CodeSerializer::SerializeReadOnlyObject(HeapObject obj,
SerializerReference back_reference =
SerializerReference::BackReference(RO_SPACE, chunk_index, chunk_offset);
reference_map()->Add(reinterpret_cast<void*>(obj->ptr()), back_reference);
CHECK(SerializeBackReference(obj, how_to_code));
CHECK(SerializeBackReference(obj));
return true;
}
void CodeSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
if (SerializeHotObject(obj, how_to_code)) return;
void CodeSerializer::SerializeObject(HeapObject obj) {
if (SerializeHotObject(obj)) return;
if (SerializeRoot(obj, how_to_code)) return;
if (SerializeRoot(obj)) return;
if (SerializeBackReference(obj, how_to_code)) return;
if (SerializeBackReference(obj)) return;
if (SerializeReadOnlyObject(obj, how_to_code)) return;
if (SerializeReadOnlyObject(obj)) return;
if (obj->IsCode()) {
Code code_object = Code::cast(obj);
@ -139,14 +138,14 @@ void CodeSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
case Code::STUB:
case Code::BUILTIN:
default:
return SerializeCodeObject(code_object, how_to_code);
return SerializeCodeObject(code_object);
}
UNREACHABLE();
}
ReadOnlyRoots roots(isolate());
if (ElideObject(obj)) {
return SerializeObject(roots.undefined_value(), how_to_code);
return SerializeObject(roots.undefined_value());
}
if (obj->IsScript()) {
@ -164,7 +163,7 @@ void CodeSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
// object graph.
FixedArray host_options = script_obj->host_defined_options();
script_obj->set_host_defined_options(roots.empty_fixed_array());
SerializeGeneric(obj, how_to_code);
SerializeGeneric(obj);
script_obj->set_host_defined_options(host_options);
script_obj->set_context_data(context_data);
return;
@ -189,7 +188,7 @@ void CodeSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
}
DCHECK(!sfi->HasDebugInfo());
SerializeGeneric(obj, how_to_code);
SerializeGeneric(obj);
// Restore debug info
if (!debug_info.is_null()) {
@ -215,13 +214,12 @@ void CodeSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
// We expect no instantiated function objects or contexts.
CHECK(!obj->IsJSFunction() && !obj->IsContext());
SerializeGeneric(obj, how_to_code);
SerializeGeneric(obj);
}
void CodeSerializer::SerializeGeneric(HeapObject heap_object,
HowToCode how_to_code) {
void CodeSerializer::SerializeGeneric(HeapObject heap_object) {
// Object has not yet been serialized. Serialize it here.
ObjectSerializer serializer(this, heap_object, &sink_, how_to_code);
ObjectSerializer serializer(this, heap_object, &sink_);
serializer.Serialize();
}

View File

@ -58,17 +58,15 @@ class CodeSerializer : public Serializer {
CodeSerializer(Isolate* isolate, uint32_t source_hash);
~CodeSerializer() override { OutputStatistics("CodeSerializer"); }
virtual void SerializeCodeObject(Code code_object, HowToCode how_to_code) {
UNREACHABLE();
}
virtual void SerializeCodeObject(Code code_object) { UNREACHABLE(); }
virtual bool ElideObject(Object obj) { return false; }
void SerializeGeneric(HeapObject heap_object, HowToCode how_to_code);
void SerializeGeneric(HeapObject heap_object);
private:
void SerializeObject(HeapObject o, HowToCode how_to_code) override;
void SerializeObject(HeapObject o) override;
bool SerializeReadOnlyObject(HeapObject obj, HowToCode how_to_code);
bool SerializeReadOnlyObject(HeapObject obj);
DISALLOW_HEAP_ALLOCATION(no_gc_);
uint32_t source_hash_;

View File

@ -442,14 +442,11 @@ void Deserializer::VisitRuntimeEntry(Code host, RelocInfo* rinfo) {
void Deserializer::VisitExternalReference(Code host, RelocInfo* rinfo) {
byte data = source_.Get();
CHECK(data == kExternalReference + kPlain ||
data == kExternalReference + kFromCode);
CHECK_EQ(data, kExternalReference);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address = external_reference_table_->address(reference_id);
Address address = ReadExternalReferenceCase();
DCHECK_EQ(rinfo->IsCodedSpecially(), data == kExternalReference + kFromCode);
if (data == kExternalReference + kFromCode) {
if (rinfo->IsCodedSpecially()) {
Address location_of_branch_data = rinfo->pc();
Assembler::deserialization_set_special_target_at(location_of_branch_data,
host, address);
@ -536,13 +533,12 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
while (current < limit) {
byte data = source_.Get();
switch (data) {
#define CASE_STATEMENT(where, how, space_number) \
case where + how + space_number: \
#define CASE_STATEMENT(where, space_number) \
case where + space_number: \
STATIC_ASSERT((where & ~kWhereMask) == 0); \
STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
#define CASE_BODY(where, how, space_number_if_any) \
#define CASE_BODY(where, space_number_if_any) \
current = ReadDataCase<where, space_number_if_any>( \
isolate, current, current_object_address, data, write_barrier_needed); \
break;
@ -550,19 +546,19 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
// 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 fall-through cases
// and one body.
#define ALL_SPACES(where, how) \
CASE_STATEMENT(where, how, NEW_SPACE) \
CASE_BODY(where, how, NEW_SPACE) \
CASE_STATEMENT(where, how, OLD_SPACE) \
#define ALL_SPACES(where) \
CASE_STATEMENT(where, NEW_SPACE) \
CASE_BODY(where, NEW_SPACE) \
CASE_STATEMENT(where, OLD_SPACE) \
V8_FALLTHROUGH; \
CASE_STATEMENT(where, how, CODE_SPACE) \
CASE_STATEMENT(where, CODE_SPACE) \
V8_FALLTHROUGH; \
CASE_STATEMENT(where, how, MAP_SPACE) \
CASE_STATEMENT(where, MAP_SPACE) \
V8_FALLTHROUGH; \
CASE_STATEMENT(where, how, LO_SPACE) \
CASE_STATEMENT(where, LO_SPACE) \
V8_FALLTHROUGH; \
CASE_STATEMENT(where, how, RO_SPACE) \
CASE_BODY(where, how, kAnyOldSpace)
CASE_STATEMENT(where, RO_SPACE) \
CASE_BODY(where, kAnyOldSpace)
#define FOUR_CASES(byte_code) \
case byte_code: \
@ -576,43 +572,28 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
FOUR_CASES(byte_code + 8) \
FOUR_CASES(byte_code + 12)
#define SINGLE_CASE(where, how, space) \
CASE_STATEMENT(where, how, space) \
CASE_BODY(where, how, space)
#define SINGLE_CASE(where, space) \
CASE_STATEMENT(where, space) \
CASE_BODY(where, space)
// Deserialize a new object and write a pointer to it to the current
// object.
ALL_SPACES(kNewObject, kPlain)
// Deserialize a new code object and write a pointer to its first
// instruction to the current code object.
ALL_SPACES(kNewObject, kFromCode)
ALL_SPACES(kNewObject)
// Find a recently deserialized object using its offset from the current
// allocation point and write a pointer to it to the current object.
ALL_SPACES(kBackref, kPlain)
// Find a recently deserialized code object using its offset from the
// current allocation point and write a pointer to its first instruction
// to the current code object or the instruction pointer in a function
// object.
ALL_SPACES(kBackref, kFromCode)
ALL_SPACES(kBackref)
// Find an object in the roots array and write a pointer to it to the
// current object.
SINGLE_CASE(kRootArray, kPlain, 0)
#if V8_CODE_EMBEDS_OBJECT_POINTER
// Find an object in the roots array and write a pointer to it to in code.
SINGLE_CASE(kRootArray, kFromCode, 0)
#endif
SINGLE_CASE(kRootArray, RO_SPACE)
// Find an object in the partial snapshots cache and write a pointer to it
// to the current object.
SINGLE_CASE(kPartialSnapshotCache, kPlain, 0)
SINGLE_CASE(kPartialSnapshotCache, kFromCode, 0)
SINGLE_CASE(kPartialSnapshotCache, RO_SPACE)
// Find an object in the partial snapshots cache and write a pointer to it
// to the current object.
SINGLE_CASE(kReadOnlyObjectCache, kPlain, 0)
SINGLE_CASE(kReadOnlyObjectCache, kFromCode, 0)
SINGLE_CASE(kReadOnlyObjectCache, RO_SPACE)
// Find an object in the attached references and write a pointer to it to
// the current object.
SINGLE_CASE(kAttachedReference, kPlain, 0)
SINGLE_CASE(kAttachedReference, kFromCode, 0)
SINGLE_CASE(kAttachedReference, RO_SPACE)
#undef CASE_STATEMENT
#undef CASE_BODY
@ -620,21 +601,17 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
// Find an external reference and write a pointer to it to the current
// object.
case kExternalReference + kPlain:
current =
ReadExternalReferenceCase(kPlain, current, current_object_address);
break;
case kExternalReference + kFromCode:
UNREACHABLE();
break;
case kInternalReferenceEncoded:
case kInternalReference: {
UNREACHABLE();
case kExternalReference: {
Address address = ReadExternalReferenceCase();
UnalignedCopy(current, address);
current.Advance();
break;
}
case kInternalReferenceEncoded:
case kInternalReference:
case kOffHeapTarget: {
// These bytecodes are expected only during RelocInfo iteration.
UNREACHABLE();
break;
}
@ -817,15 +794,9 @@ bool Deserializer::ReadData(UnalignedSlot current, UnalignedSlot limit,
return true;
}
UnalignedSlot Deserializer::ReadExternalReferenceCase(
HowToCode how, UnalignedSlot current, Address current_object_address) {
Address Deserializer::ReadExternalReferenceCase() {
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address = external_reference_table_->address(reference_id);
DCHECK_EQ(how, kPlain);
UnalignedCopy(current, address);
current.Advance();
return current;
return external_reference_table_->address(reference_id);
}
template <SerializerDeserializer::Where where, int space_number_if_any>

View File

@ -132,9 +132,7 @@ class Deserializer : public SerializerDeserializer {
bool write_barrier_needed);
// A helper function for ReadData for reading external references.
// Returns the new value of {current}.
inline UnalignedSlot ReadExternalReferenceCase(
HowToCode how, UnalignedSlot current, Address current_object_address);
inline Address ReadExternalReferenceCase();
HeapObject ReadObject();
HeapObject ReadObject(int space_number);

View File

@ -68,23 +68,21 @@ void PartialSerializer::Serialize(Context* o, bool include_global_proxy) {
Pad();
}
void PartialSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
void PartialSerializer::SerializeObject(HeapObject obj) {
DCHECK(!ObjectIsBytecodeHandler(obj)); // Only referenced in dispatch table.
if (SerializeHotObject(obj, how_to_code)) return;
if (SerializeHotObject(obj)) return;
if (SerializeRoot(obj, how_to_code)) return;
if (SerializeRoot(obj)) return;
if (SerializeBackReference(obj, how_to_code)) return;
if (SerializeBackReference(obj)) return;
if (startup_serializer_->SerializeUsingReadOnlyObjectCache(&sink_, obj,
how_to_code)) {
if (startup_serializer_->SerializeUsingReadOnlyObjectCache(&sink_, obj)) {
return;
}
if (ShouldBeInThePartialSnapshotCache(obj)) {
startup_serializer_->SerializeUsingPartialSnapshotCache(&sink_, obj,
how_to_code);
startup_serializer_->SerializeUsingPartialSnapshotCache(&sink_, obj);
return;
}
@ -103,7 +101,7 @@ void PartialSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
// Clear literal boilerplates and feedback.
if (obj->IsFeedbackVector()) FeedbackVector::cast(obj)->ClearSlots(isolate());
if (SerializeJSObjectWithEmbedderFields(obj, how_to_code)) {
if (SerializeJSObjectWithEmbedderFields(obj)) {
return;
}
@ -118,7 +116,7 @@ void PartialSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
CheckRehashability(obj);
// Object has not yet been serialized. Serialize it here.
ObjectSerializer serializer(this, obj, &sink_, how_to_code);
ObjectSerializer serializer(this, obj, &sink_);
serializer.Serialize();
}
@ -139,8 +137,7 @@ namespace {
bool DataIsEmpty(const StartupData& data) { return data.raw_size == 0; }
} // anonymous namespace
bool PartialSerializer::SerializeJSObjectWithEmbedderFields(
Object obj, HowToCode how_to_code) {
bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
if (!obj->IsJSObject()) return false;
JSObject js_obj = JSObject::cast(obj);
int embedder_fields_count = js_obj->GetEmbedderFieldCount();
@ -191,7 +188,7 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(
// 3) Serialize the object. References from embedder fields to heap objects or
// smis are serialized regularly.
ObjectSerializer(this, js_obj, &sink_, how_to_code).Serialize();
ObjectSerializer(this, js_obj, &sink_).Serialize();
// 4) Obtain back reference for the serialized object.
SerializerReference reference =

View File

@ -27,11 +27,11 @@ class PartialSerializer : public Serializer {
bool can_be_rehashed() const { return can_be_rehashed_; }
private:
void SerializeObject(HeapObject o, HowToCode how_to_code) override;
void SerializeObject(HeapObject o) override;
bool ShouldBeInThePartialSnapshotCache(HeapObject o);
bool SerializeJSObjectWithEmbedderFields(Object obj, HowToCode how_to_code);
bool SerializeJSObjectWithEmbedderFields(Object obj);
void CheckRehashability(HeapObject obj);

View File

@ -24,21 +24,20 @@ ReadOnlySerializer::~ReadOnlySerializer() {
OutputStatistics("ReadOnlySerializer");
}
void ReadOnlySerializer::SerializeObject(HeapObject obj,
HowToCode how_to_code) {
void ReadOnlySerializer::SerializeObject(HeapObject obj) {
CHECK(isolate()->heap()->read_only_space()->Contains(obj));
CHECK_IMPLIES(obj->IsString(), obj->IsInternalizedString());
if (SerializeHotObject(obj, how_to_code)) return;
if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj, how_to_code)) {
if (SerializeHotObject(obj)) return;
if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj)) {
return;
}
if (SerializeBackReference(obj, how_to_code)) return;
if (SerializeBackReference(obj)) return;
CheckRehashability(obj);
// Object has not yet been serialized. Serialize it here.
ObjectSerializer object_serializer(this, obj, &sink_, how_to_code);
ObjectSerializer object_serializer(this, obj, &sink_);
object_serializer.Serialize();
}
@ -79,7 +78,7 @@ bool ReadOnlySerializer::MustBeDeferred(HeapObject object) {
}
bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
SnapshotByteSink* sink, HeapObject obj, HowToCode how_to_code) {
SnapshotByteSink* sink, HeapObject obj) {
if (!isolate()->heap()->read_only_space()->Contains(obj)) return false;
// Get the cache index and serialize it into the read-only snapshot if
@ -87,7 +86,7 @@ bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
int cache_index = SerializeInObjectCache(obj);
// Writing out the cache entry into the calling serializer's sink.
sink->Put(kReadOnlyObjectCache + how_to_code, "ReadOnlyObjectCache");
sink->Put(kReadOnlyObjectCache, "ReadOnlyObjectCache");
sink->PutInt(cache_index, "read_only_object_cache_index");
return true;

View File

@ -28,11 +28,11 @@ class ReadOnlySerializer : public RootsSerializer {
// read-only object cache if not already present and emit a
// ReadOnlyObjectCache bytecode into |sink|. Returns whether this was
// successful.
bool SerializeUsingReadOnlyObjectCache(SnapshotByteSink* sink, HeapObject obj,
HowToCode how_to_code);
bool SerializeUsingReadOnlyObjectCache(SnapshotByteSink* sink,
HeapObject obj);
private:
void SerializeObject(HeapObject o, HowToCode how_to_code) override;
void SerializeObject(HeapObject o) override;
bool MustBeDeferred(HeapObject object) override;
DISALLOW_COPY_AND_ASSIGN(ReadOnlySerializer);

View File

@ -28,7 +28,7 @@ int RootsSerializer::SerializeInObjectCache(HeapObject heap_object) {
if (!object_cache_index_map_.LookupOrInsert(heap_object, &index)) {
// This object is not part of the object cache yet. Add it to the cache so
// we can refer to it via cache index from the delegating snapshot.
SerializeObject(heap_object, kPlain);
SerializeObject(heap_object);
}
return index;
}

View File

@ -148,7 +148,7 @@ class SerializerDeserializer : public RootVisitor {
V(0x7c)
// ---------- byte code range 0x00..0x3f ----------
// Byte codes in this range represent Where and HowToCode.
// Byte codes in this range represent Where.
// Where the pointed-to object can be found:
// The static assert below will trigger when the number of preallocated spaces
// changed. If that happens, update the bytecode ranges in the comments below.
@ -179,16 +179,6 @@ class SerializerDeserializer : public RootVisitor {
static const int kSpaceMask = 7;
STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
// How to code the pointer to the object.
enum HowToCode {
// Straight pointer.
kPlain = 0,
// A pointer inlined in code. What this means depends on the architecture.
kFromCode = 0x20
};
static const int kHowToCodeMask = 0x20;
// ---------- Misc ----------
// Do nothing, used for padding.
static const int kNop = 0x2f;

View File

@ -91,7 +91,7 @@ void Serializer::SerializeDeferredObjects() {
while (!deferred_objects_.empty()) {
HeapObject obj = deferred_objects_.back();
deferred_objects_.pop_back();
ObjectSerializer obj_serializer(this, obj, &sink_, kPlain);
ObjectSerializer obj_serializer(this, obj, &sink_);
obj_serializer.SerializeDeferred();
}
sink_.Put(kSynchronize, "Finished with deferred objects");
@ -110,7 +110,7 @@ void Serializer::SerializeRootObject(Object object) {
if (object->IsSmi()) {
PutSmi(Smi::cast(object));
} else {
SerializeObject(HeapObject::cast(object), kPlain);
SerializeObject(HeapObject::cast(object));
}
}
@ -123,19 +123,18 @@ void Serializer::PrintStack() {
}
#endif // DEBUG
bool Serializer::SerializeRoot(HeapObject obj, HowToCode how_to_code) {
bool Serializer::SerializeRoot(HeapObject obj) {
RootIndex root_index;
// Derived serializers are responsible for determining if the root has
// actually been serialized before calling this.
if (root_index_map()->Lookup(obj, &root_index)) {
PutRoot(root_index, obj, how_to_code);
PutRoot(root_index, obj);
return true;
}
return false;
}
bool Serializer::SerializeHotObject(HeapObject obj, HowToCode how_to_code) {
if (how_to_code != kPlain) return false;
bool Serializer::SerializeHotObject(HeapObject obj) {
// Encode a reference to a hot object by its index in the working set.
int index = hot_objects_.Find(obj);
if (index == HotObjectsList::kNotFound) return false;
@ -150,7 +149,7 @@ bool Serializer::SerializeHotObject(HeapObject obj, HowToCode how_to_code) {
return true;
}
bool Serializer::SerializeBackReference(HeapObject obj, HowToCode how_to_code) {
bool Serializer::SerializeBackReference(HeapObject obj) {
SerializerReference reference =
reference_map_.LookupReference(reinterpret_cast<void*>(obj.ptr()));
if (!reference.is_valid()) return false;
@ -163,7 +162,7 @@ bool Serializer::SerializeBackReference(HeapObject obj, HowToCode how_to_code) {
PrintF(" Encoding attached reference %d\n",
reference.attached_reference_index());
}
PutAttachedReference(reference, how_to_code);
PutAttachedReference(reference);
} else {
DCHECK(reference.is_back_reference());
if (FLAG_trace_serializer) {
@ -174,7 +173,7 @@ bool Serializer::SerializeBackReference(HeapObject obj, HowToCode how_to_code) {
PutAlignmentPrefix(obj);
AllocationSpace space = reference.space();
sink_.Put(kBackref + how_to_code + space, "BackRef");
sink_.Put(kBackref + space, "BackRef");
PutBackReference(obj, reference);
}
return true;
@ -185,8 +184,7 @@ bool Serializer::ObjectIsBytecodeHandler(HeapObject obj) const {
return (Code::cast(obj)->kind() == Code::BYTECODE_HANDLER);
}
void Serializer::PutRoot(RootIndex root, HeapObject object,
SerializerDeserializer::HowToCode how_to_code) {
void Serializer::PutRoot(RootIndex root, HeapObject object) {
int root_index = static_cast<int>(root);
if (FLAG_trace_serializer) {
PrintF(" Encoding root %d:", root_index);
@ -200,11 +198,11 @@ void Serializer::PutRoot(RootIndex root, HeapObject object,
kNumberOfRootArrayConstants - 1);
// TODO(ulan): Check that it works with young large objects.
if (how_to_code == kPlain && root_index < kNumberOfRootArrayConstants &&
if (root_index < kNumberOfRootArrayConstants &&
!Heap::InYoungGeneration(object)) {
sink_.Put(kRootArrayConstants + root_index, "RootConstant");
} else {
sink_.Put(kRootArray + how_to_code, "RootSerialization");
sink_.Put(kRootArray, "RootSerialization");
sink_.PutInt(root_index, "root_index");
hot_objects_.Add(object);
}
@ -239,10 +237,9 @@ void Serializer::PutBackReference(HeapObject object,
hot_objects_.Add(object);
}
void Serializer::PutAttachedReference(SerializerReference reference,
HowToCode how_to_code) {
void Serializer::PutAttachedReference(SerializerReference reference) {
DCHECK(reference.is_attached_reference());
sink_.Put(kAttachedReference + how_to_code, "AttachedRef");
sink_.Put(kAttachedReference, "AttachedRef");
sink_.PutInt(reference.attached_reference_index(), "AttachedRefIndex");
}
@ -311,21 +308,20 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
SerializerReference back_reference;
if (space == LO_SPACE) {
sink_->Put(kNewObject + reference_representation_ + space,
"NewLargeObject");
sink_->Put(kNewObject + space, "NewLargeObject");
sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
CHECK(!object_->IsCode());
back_reference = serializer_->allocator()->AllocateLargeObject(size);
} else if (space == MAP_SPACE) {
DCHECK_EQ(Map::kSize, size);
back_reference = serializer_->allocator()->AllocateMap();
sink_->Put(kNewObject + reference_representation_ + space, "NewMap");
sink_->Put(kNewObject + space, "NewMap");
// This is redundant, but we include it anyways.
sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
} else {
int fill = serializer_->PutAlignmentPrefix(object_);
back_reference = serializer_->allocator()->Allocate(space, size + fill);
sink_->Put(kNewObject + reference_representation_ + space, "NewObject");
sink_->Put(kNewObject + space, "NewObject");
sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
}
@ -340,7 +336,7 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
back_reference);
// Serialize the map (first word of the object).
serializer_->SerializeObject(map, kPlain);
serializer_->SerializeObject(map);
}
int32_t Serializer::ObjectSerializer::SerializeBackingStore(
@ -699,16 +695,15 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host,
if (reference_type == HeapObjectReferenceType::WEAK) {
sink_->Put(kWeakPrefix, "WeakReference");
}
serializer_->SerializeObject(current_contents, kPlain);
serializer_->SerializeObject(current_contents);
}
}
}
void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code host,
RelocInfo* rinfo) {
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
Object object = rinfo->target_object();
serializer_->SerializeObject(HeapObject::cast(object), how_to_code);
serializer_->SerializeObject(HeapObject::cast(object));
bytes_processed_so_far_ += rinfo->target_address_size();
}
@ -719,7 +714,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(Foreign host,
if (encoded_reference.is_from_api()) {
sink_->Put(kApiReference, "ApiRef");
} else {
sink_->Put(kExternalReference + kPlain, "ExternalRef");
sink_->Put(kExternalReference, "ExternalRef");
}
sink_->PutInt(encoded_reference.index(), "reference index");
bytes_processed_so_far_ += kSystemPointerSize;
@ -733,8 +728,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(Code host,
DCHECK(!rinfo->IsCodedSpecially());
sink_->Put(kApiReference, "ApiRef");
} else {
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
sink_->Put(kExternalReference + how_to_code, "ExternalRef");
sink_->Put(kExternalReference, "ExternalRef");
}
DCHECK_NE(target, kNullAddress); // Code does not reference null.
sink_->PutInt(encoded_reference.index(), "reference index");
@ -792,7 +786,7 @@ void Serializer::ObjectSerializer::VisitCodeTarget(Code host,
DCHECK(!RelocInfo::IsRelativeCodeTarget(rinfo->rmode()));
#endif
Code object = Code::GetCodeFromTargetAddress(rinfo->target_address());
serializer_->SerializeObject(object, kFromCode);
serializer_->SerializeObject(object);
bytes_processed_so_far_ += rinfo->target_address_size();
}

View File

@ -191,7 +191,7 @@ class Serializer : public SerializerDeserializer {
};
void SerializeDeferredObjects();
virtual void SerializeObject(HeapObject o, HowToCode how_to_code) = 0;
virtual void SerializeObject(HeapObject o) = 0;
virtual bool MustBeDeferred(HeapObject object);
@ -199,24 +199,23 @@ class Serializer : public SerializerDeserializer {
FullObjectSlot start, FullObjectSlot end) override;
void SerializeRootObject(Object object);
void PutRoot(RootIndex root_index, HeapObject object, HowToCode how);
void PutRoot(RootIndex root_index, HeapObject object);
void PutSmi(Smi smi);
void PutBackReference(HeapObject object, SerializerReference reference);
void PutAttachedReference(SerializerReference reference,
HowToCode how_to_code);
void PutAttachedReference(SerializerReference reference);
// Emit alignment prefix if necessary, return required padding space in bytes.
int PutAlignmentPrefix(HeapObject object);
void PutNextChunk(int space);
void PutRepeat(int repeat_count);
// Returns true if the object was successfully serialized as a root.
bool SerializeRoot(HeapObject obj, HowToCode how_to_code);
bool SerializeRoot(HeapObject obj);
// Returns true if the object was successfully serialized as hot object.
bool SerializeHotObject(HeapObject obj, HowToCode how_to_code);
bool SerializeHotObject(HeapObject obj);
// Returns true if the object was successfully serialized as back reference.
bool SerializeBackReference(HeapObject obj, HowToCode how_to_code);
bool SerializeBackReference(HeapObject obj);
// Returns true if the given heap object is a bytecode handler code object.
bool ObjectIsBytecodeHandler(HeapObject obj) const;
@ -290,11 +289,10 @@ class RelocInfoIterator;
class Serializer::ObjectSerializer : public ObjectVisitor {
public:
ObjectSerializer(Serializer* serializer, HeapObject obj,
SnapshotByteSink* sink, HowToCode how_to_code)
SnapshotByteSink* sink)
: serializer_(serializer),
object_(obj),
sink_(sink),
reference_representation_(how_to_code),
bytes_processed_so_far_(0) {
#ifdef DEBUG
serializer_->PushStack(obj);
@ -338,7 +336,6 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
Serializer* serializer_;
HeapObject object_;
SnapshotByteSink* sink_;
int reference_representation_;
int bytes_processed_so_far_;
};

View File

@ -69,15 +69,14 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
} // namespace
#endif // DEBUG
void StartupSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
void StartupSerializer::SerializeObject(HeapObject obj) {
DCHECK(!obj->IsJSFunction());
DCHECK(!IsUnexpectedCodeObject(isolate(), obj));
if (SerializeHotObject(obj, how_to_code)) return;
if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj, how_to_code))
return;
if (SerializeUsingReadOnlyObjectCache(&sink_, obj, how_to_code)) return;
if (SerializeBackReference(obj, how_to_code)) return;
if (SerializeHotObject(obj)) return;
if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj)) return;
if (SerializeUsingReadOnlyObjectCache(&sink_, obj)) return;
if (SerializeBackReference(obj)) return;
bool use_simulator = false;
#ifdef USE_SIMULATOR
@ -112,7 +111,7 @@ void StartupSerializer::SerializeObject(HeapObject obj, HowToCode how_to_code) {
// Object has not yet been serialized. Serialize it here.
DCHECK(!isolate()->heap()->read_only_space()->Contains(obj));
ObjectSerializer object_serializer(this, obj, &sink_, how_to_code);
ObjectSerializer object_serializer(this, obj, &sink_);
object_serializer.Serialize();
}
@ -155,15 +154,14 @@ SerializedHandleChecker::SerializedHandleChecker(Isolate* isolate,
}
bool StartupSerializer::SerializeUsingReadOnlyObjectCache(
SnapshotByteSink* sink, HeapObject obj, HowToCode how_to_code) {
return read_only_serializer_->SerializeUsingReadOnlyObjectCache(sink, obj,
how_to_code);
SnapshotByteSink* sink, HeapObject obj) {
return read_only_serializer_->SerializeUsingReadOnlyObjectCache(sink, obj);
}
void StartupSerializer::SerializeUsingPartialSnapshotCache(
SnapshotByteSink* sink, HeapObject obj, HowToCode how_to_code) {
SnapshotByteSink* sink, HeapObject obj) {
int cache_index = SerializeInObjectCache(obj);
sink->Put(kPartialSnapshotCache + how_to_code, "PartialSnapshotCache");
sink->Put(kPartialSnapshotCache, "PartialSnapshotCache");
sink->PutInt(cache_index, "partial_snapshot_cache_index");
}

View File

@ -33,17 +33,16 @@ class StartupSerializer : public RootsSerializer {
// read-only object cache if not already present and emits a
// ReadOnlyObjectCache bytecode into |sink|. Returns whether this was
// successful.
bool SerializeUsingReadOnlyObjectCache(SnapshotByteSink* sink, HeapObject obj,
HowToCode how_to_code);
bool SerializeUsingReadOnlyObjectCache(SnapshotByteSink* sink,
HeapObject obj);
// Adds |obj| to the partial snapshot object cache if not already present and
// emits a PartialSnapshotCache bytecode into |sink|.
void SerializeUsingPartialSnapshotCache(SnapshotByteSink* sink,
HeapObject obj,
HowToCode how_to_code);
HeapObject obj);
private:
void SerializeObject(HeapObject o, HowToCode how_to_code) override;
void SerializeObject(HeapObject o) override;
ReadOnlySerializer* read_only_serializer_;
std::vector<AccessorInfo> accessor_infos_;