From 90475d1b9bdf101b9d309f16f51afeed5184b3c6 Mon Sep 17 00:00:00 2001 From: liqy Date: Wed, 20 Dec 2017 00:25:26 +0800 Subject: [PATCH] deps: v8: support visit external string --- deps/v8/src/heap/mark-compact.cc | 1 + deps/v8/src/objects-body-descriptors-inl.h | 10 +++++++ deps/v8/src/objects.h | 4 +++ deps/v8/src/snapshot/deserializer.cc | 21 +++++++++----- deps/v8/src/snapshot/serializer-common.cc | 6 ++++ deps/v8/src/snapshot/serializer-common.h | 1 + deps/v8/src/snapshot/serializer.cc | 33 ++++++++++++++++++++++ deps/v8/src/snapshot/serializer.h | 5 ++++ 8 files changed, 74 insertions(+), 7 deletions(-) diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc index 194415e949..c74e0ea02c 100644 --- a/deps/v8/src/heap/mark-compact.cc +++ b/deps/v8/src/heap/mark-compact.cc @@ -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 {} diff --git a/deps/v8/src/objects-body-descriptors-inl.h b/deps/v8/src/objects-body-descriptors-inl.h index fba2ff70cc..6f7ba1f3f9 100644 --- a/deps/v8/src/objects-body-descriptors-inl.h +++ b/deps/v8/src/objects-body-descriptors-inl.h @@ -321,6 +321,11 @@ class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase { template 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(HeapObject::RawField( + obj, kResourceOffset))); + } } static inline int SizeOf(Map* map, HeapObject* object) { return kSize; } @@ -333,6 +338,11 @@ class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase { template 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(HeapObject::RawField( + obj, kResourceOffset))); + } } static inline int SizeOf(Map* map, HeapObject* object) { return kSize; } diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index dc14385656..f7147d4a98 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -922,6 +922,7 @@ class AllocationSite; class Cell; class ConsString; class ElementsAccessor; +class ExternalString; class FindAndReplacePattern; class FixedArrayBase; class PropertyArray; @@ -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) {} }; diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc index 113d24bb70..bf6d92b75b 100644 --- a/deps/v8/src/snapshot/deserializer.cc +++ b/deps/v8/src/snapshot/deserializer.cc @@ -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. diff --git a/deps/v8/src/snapshot/serializer-common.cc b/deps/v8/src/snapshot/serializer-common.cc index 4840da9cf5..0a7ace341b 100644 --- a/deps/v8/src/snapshot/serializer-common.cc +++ b/deps/v8/src/snapshot/serializer-common.cc @@ -73,6 +73,12 @@ ExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode( return result; } +bool ExternalReferenceEncoder::IsValidExternalReference(Address address) { + Maybe maybe_index = map_->Get(address); + if (maybe_index.IsNothing()) return false; + return true; +} + const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, Address address) const { Maybe maybe_index = map_->Get(address); diff --git a/deps/v8/src/snapshot/serializer-common.h b/deps/v8/src/snapshot/serializer-common.h index bfb881810b..69dade9684 100644 --- a/deps/v8/src/snapshot/serializer-common.h +++ b/deps/v8/src/snapshot/serializer-common.h @@ -40,6 +40,7 @@ class ExternalReferenceEncoder { ~ExternalReferenceEncoder(); Value Encode(Address key); + bool IsValidExternalReference(Address key); const char* NameOfAddress(Isolate* isolate, Address address) const; diff --git a/deps/v8/src/snapshot/serializer.cc b/deps/v8/src/snapshot/serializer.cc index 3d0176a139..5947bec23a 100644 --- a/deps/v8/src/snapshot/serializer.cc +++ b/deps/v8/src/snapshot/serializer.cc @@ -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(string->resource()); + if (serializer_->IsValidExternalReference(reinterpret_cast
(resource))) { + SerializeContent(); + return; + } + } else if (object_->IsExternalTwoByteString()) { + ExternalTwoByteString* string = ExternalTwoByteString::cast(object_); + ExternalTwoByteString::Resource* resource = + const_cast(string->resource()); + if (serializer_->IsValidExternalReference(reinterpret_cast
(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. @@ -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
(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(), diff --git a/deps/v8/src/snapshot/serializer.h b/deps/v8/src/snapshot/serializer.h index a1924b4f7a..aea1a844d3 100644 --- a/deps/v8/src/snapshot/serializer.h +++ b/deps/v8/src/snapshot/serializer.h @@ -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. @@ -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;