Skip to content

Commit

Permalink
deps: v8: support visit external string
Browse files Browse the repository at this point in the history
  • Loading branch information
liqyan committed Dec 19, 2017
1 parent 3a4ee88 commit 90475d1
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 7 deletions.
1 change: 1 addition & 0 deletions deps/v8/src/heap/mark-compact.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,7 @@ class RecordMigratedSlotVisitor : public ObjectVisitor {
// Entries that are skipped for recording.
inline void VisitExternalReference(Code* host, RelocInfo* rinfo) final {}
inline void VisitExternalReference(Foreign* host, Address* p) final {}
inline void VisitExternalReference(ExternalString* host, Address* p) {}
inline void VisitRuntimeEntry(Code* host, RelocInfo* rinfo) final {}
inline void VisitInternalReference(Code* host, RelocInfo* rinfo) final {}

Expand Down
10 changes: 10 additions & 0 deletions deps/v8/src/objects-body-descriptors-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
if (obj->map() != obj->GetHeap()->native_source_string_map()) {
v->VisitExternalReference(ExternalString::cast(obj),
reinterpret_cast<Address*>(HeapObject::RawField(
obj, kResourceOffset)));
}
}

static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
Expand All @@ -333,6 +338,11 @@ class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
if (obj->map() != obj->GetHeap()->native_source_string_map()) {
v->VisitExternalReference(ExternalString::cast(obj),
reinterpret_cast<Address*>(HeapObject::RawField(
obj, kResourceOffset)));
}
}

static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ class AllocationSite;
class Cell;
class ConsString;
class ElementsAccessor;
class ExternalString;
class FindAndReplacePattern;
class FixedArrayBase;
class PropertyArray;
Expand Down Expand Up @@ -7182,6 +7183,9 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits an external reference.
virtual void VisitExternalReference(Foreign* host, Address* p) {}

// Visits an external reference embedded into a external string object.
virtual void VisitExternalReference(ExternalString* host, Address* p) {}

// Visits an (encoded) internal reference.
virtual void VisitInternalReference(Code* host, RelocInfo* rinfo) {}
};
Expand Down
21 changes: 14 additions & 7 deletions deps/v8/src/snapshot/deserializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,20 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
accessor_infos_.push_back(AccessorInfo::cast(obj));
}
} else if (obj->IsExternalOneByteString()) {
DCHECK(obj->map() == isolate_->heap()->native_source_string_map());
ExternalOneByteString* string = ExternalOneByteString::cast(obj);
DCHECK(string->is_short());
string->set_resource(
NativesExternalStringResource::DecodeForDeserialization(
string->resource()));
isolate_->heap()->RegisterExternalString(string);
if (obj->map() == isolate_->heap()->native_source_string_map()) {
ExternalOneByteString* string = ExternalOneByteString::cast(obj);
DCHECK(string->is_short());
string->set_resource(
NativesExternalStringResource::DecodeForDeserialization(
string->resource()));
isolate_->heap()->RegisterExternalString(string);
} else {
ExternalOneByteString* string = ExternalOneByteString::cast(obj);
isolate_->heap()->RegisterExternalString(string);
}
} else if (obj->IsExternalTwoByteString()) {
ExternalTwoByteString* string = ExternalTwoByteString::cast(obj);
isolate_->heap()->RegisterExternalString(string);
} else if (obj->IsJSArrayBuffer()) {
JSArrayBuffer* buffer = JSArrayBuffer::cast(obj);
// Only fixup for the off-heap case.
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/src/snapshot/serializer-common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ ExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode(
return result;
}

bool ExternalReferenceEncoder::IsValidExternalReference(Address address) {
Maybe<uint32_t> maybe_index = map_->Get(address);
if (maybe_index.IsNothing()) return false;
return true;
}

const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
Address address) const {
Maybe<uint32_t> maybe_index = map_->Get(address);
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/snapshot/serializer-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ExternalReferenceEncoder {
~ExternalReferenceEncoder();

Value Encode(Address key);
bool IsValidExternalReference(Address key);

const char* NameOfAddress(Isolate* isolate, Address address) const;

Expand Down
33 changes: 33 additions & 0 deletions deps/v8/src/snapshot/serializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,23 @@ void Serializer::ObjectSerializer::SerializeFixedTypedArray() {
void Serializer::ObjectSerializer::SerializeExternalString() {
Heap* heap = serializer_->isolate()->heap();
if (object_->map() != heap->native_source_string_map()) {
if (object_->IsExternalOneByteString()) {
ExternalOneByteString* string = ExternalOneByteString::cast(object_);
ExternalOneByteString::Resource* resource =
const_cast<ExternalOneByteString::Resource*>(string->resource());
if (serializer_->IsValidExternalReference(reinterpret_cast<Address>(resource))) {
SerializeContent();

This comment has been minimized.

Copy link
@hashseed

hashseed Dec 22, 2017

Contributor

I think this can be done a lot simpler, without having to change the object visitor. We could use the same trick as we do for native source strings.

If we have an external string that has a known resource (IsValidExternalReference returns true), we replace the resource field with the external reference id (see line 503). Upon deserialization, if we see an external string that does not have the native source string map, then we have to restore the resource field by looking up the external reference.

That would be a much less intrusive change. I'll prepare an upstream V8 patch to implement this idea.

return;
}
} else if (object_->IsExternalTwoByteString()) {
ExternalTwoByteString* string = ExternalTwoByteString::cast(object_);
ExternalTwoByteString::Resource* resource =
const_cast<ExternalTwoByteString::Resource*>(string->resource());
if (serializer_->IsValidExternalReference(reinterpret_cast<Address>(resource))) {
SerializeContent();
return;
}
}
// Usually we cannot recreate resources for external strings. To work
// around this, external strings are serialized to look like ordinary
// sequential strings.
Expand Down Expand Up @@ -738,6 +755,22 @@ void Serializer::ObjectSerializer::VisitExternalReference(Foreign* host,
bytes_processed_so_far_ += kPointerSize;
}

void Serializer::ObjectSerializer::VisitExternalReference(ExternalString* host,
Address* p) {
int skip = OutputRawData(reinterpret_cast<Address>(p),
kCanReturnSkipInsteadOfSkipping);
Address target = *p;
auto encoded_reference = serializer_->EncodeExternalReference(target);
if (encoded_reference.is_from_api()) {
sink_->Put(kApiReference, "ApiRef");
} else {
sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
}
sink_->PutInt(skip, "SkipB4ExternalRef");
sink_->PutInt(encoded_reference.index(), "reference index");
bytes_processed_so_far_ += kPointerSize;
}

void Serializer::ObjectSerializer::VisitExternalReference(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->target_address_address(),
Expand Down
5 changes: 5 additions & 0 deletions deps/v8/src/snapshot/serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ class Serializer : public SerializerDeserializer {
return external_reference_encoder_.Encode(addr);
}

bool IsValidExternalReference(Address addr) {
return external_reference_encoder_.IsValidExternalReference(addr);
}

bool HasNotExceededFirstPageOfEachSpace();

// GetInt reads 4 bytes at once, requiring padding at the end.
Expand Down Expand Up @@ -315,6 +319,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
void VisitPointers(HeapObject* host, Object** start, Object** end) override;
void VisitEmbeddedPointer(Code* host, RelocInfo* target) override;
void VisitExternalReference(Foreign* host, Address* p) override;
void VisitExternalReference(ExternalString* host, Address* p) override;
void VisitExternalReference(Code* host, RelocInfo* rinfo) override;
void VisitInternalReference(Code* host, RelocInfo* rinfo) override;
void VisitCodeTarget(Code* host, RelocInfo* target) override;
Expand Down

0 comments on commit 90475d1

Please sign in to comment.