[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:
parent
8a526a4153
commit
37e632b119
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user