From a6f446298766c2b72cc8e61d608265408f001daa Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Mon, 14 Jan 2019 14:34:42 +0100 Subject: [PATCH] Reland "[parser] Inline byte scope data into PreparseData object" This is a reland of e2d44ede95da3a380089c6eb8960b1d59faf750a Original change's description: > [parser] Inline byte scope data into PreparseData object > > Each PreparseData object had at least one pointer to a PodArray for its > serialized scope data. These objects usually have only tens of bytes of > payload. By inlining the byte data we save 3 words per PreparseData object. > This optimization saves 140KB of data on cnn.com. > > > - Store data_length and inner_length as int32 saving a words on 64bit > - Inline store byte data into PreparseData > - OnHeapConsumedPreparseData directly uses the PreparseData object > - get_inner, set_inner no longer allow Null sentinels > > Change-Id: I1f62154d05ea2f98a6574efa738b32a8a84319d5 > Reviewed-on: https://chromium-review.googlesource.com/c/1406673 > Reviewed-by: Leszek Swirski > Reviewed-by: Ulan Degenbaev > Commit-Queue: Camillo Bruni > Cr-Commit-Position: refs/heads/master@{#58751} Change-Id: I1f0a22c641d0d67f435b01c82daf8da7f144bff4 Reviewed-on: https://chromium-review.googlesource.com/c/1407066 Reviewed-by: Leszek Swirski Reviewed-by: Ulan Degenbaev Commit-Queue: Camillo Bruni Cr-Commit-Position: refs/heads/master@{#58785} --- src/arm64/constants-arm64.h | 2 - src/globals.h | 1 + src/heap/factory.cc | 12 ++-- src/heap/factory.h | 2 +- src/heap/object-stats.cc | 15 ----- src/objects-body-descriptors-inl.h | 11 ++-- src/objects-debug.cc | 10 +-- src/objects-inl.h | 3 +- src/objects-printer.cc | 8 +-- src/objects.cc | 3 +- src/objects/shared-function-info-inl.h | 84 +++++++++++++++++--------- src/objects/shared-function-info.h | 57 ++++++++++++----- src/parsing/preparse-data-impl.h | 46 +++++++------- src/parsing/preparse-data.cc | 57 ++++++----------- test/cctest/parsing/test-preparser.cc | 4 +- 15 files changed, 170 insertions(+), 145 deletions(-) diff --git a/src/arm64/constants-arm64.h b/src/arm64/constants-arm64.h index e5ae9b9ef8..c93aad9f61 100644 --- a/src/arm64/constants-arm64.h +++ b/src/arm64/constants-arm64.h @@ -111,8 +111,6 @@ const unsigned kRegCodeMask = 0x1f; const unsigned kShiftAmountWRegMask = 0x1f; const unsigned kShiftAmountXRegMask = 0x3f; // Standard machine types defined by AAPCS64. -const unsigned kByteSize = 8; -const unsigned kByteSizeInBytes = kByteSize >> 3; const unsigned kHalfWordSize = 16; const unsigned kHalfWordSizeLog2 = 4; const unsigned kHalfWordSizeInBytes = kHalfWordSize >> 3; diff --git a/src/globals.h b/src/globals.h index c5dcaa024f..0878119f85 100644 --- a/src/globals.h +++ b/src/globals.h @@ -119,6 +119,7 @@ constexpr uint32_t kMaxUInt32 = 0xFFFFFFFFu; constexpr int kMinUInt32 = 0; constexpr int kUInt8Size = sizeof(uint8_t); +constexpr int kByteSize = sizeof(byte); constexpr int kCharSize = sizeof(char); constexpr int kShortSize = sizeof(short); // NOLINT constexpr int kUInt16Size = sizeof(uint16_t); diff --git a/src/heap/factory.cc b/src/heap/factory.cc index e757918bc6..3bf979930f 100644 --- a/src/heap/factory.cc +++ b/src/heap/factory.cc @@ -2638,15 +2638,15 @@ Handle Factory::NewModuleInfo() { ModuleInfo::kLength, TENURED); } -Handle Factory::NewPreparseData(int length) { - int size = PreparseData::SizeFor(length); +Handle Factory::NewPreparseData(int data_length, + int children_length) { + int size = PreparseData::SizeFor(data_length, children_length); Handle result(PreparseData::cast(AllocateRawWithImmortalMap( size, TENURED, *preparse_data_map())), isolate()); - result->set_scope_data(PodArray::cast(*empty_byte_array())); - result->set_length(length); - MemsetTagged(result->child_data_start(), *null_value(), length); - + result->set_data_length(data_length); + result->set_children_length(children_length); + MemsetTagged(result->inner_data_start(), *null_value(), children_length); result->clear_padding(); return result; } diff --git a/src/heap/factory.h b/src/heap/factory.h index 1c3e804b69..abdca3807a 100644 --- a/src/heap/factory.h +++ b/src/heap/factory.h @@ -750,7 +750,7 @@ class V8_EXPORT_PRIVATE Factory { Handle NewModuleInfo(); - Handle NewPreparseData(int length); + Handle NewPreparseData(int data_length, int children_length); Handle NewUncompiledDataWithoutPreparseData(Handle inferred_name, diff --git a/src/heap/object-stats.cc b/src/heap/object-stats.cc index 2cfd19d70d..5839a611fb 100644 --- a/src/heap/object-stats.cc +++ b/src/heap/object-stats.cc @@ -401,7 +401,6 @@ class ObjectStatsCollectorImpl { void RecordVirtualExternalStringDetails(ExternalString script); void RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo info); void RecordVirtualJSFunctionDetails(JSFunction function); - void RecordVirtualPreparseDataDetails(PreparseData data); void RecordVirtualArrayBoilerplateDescription( ArrayBoilerplateDescription description); @@ -650,18 +649,6 @@ void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails( CHECK_EQ(calculated_size, vector->Size()); } -void ObjectStatsCollectorImpl::RecordVirtualPreparseDataDetails( - PreparseData data) { - if (virtual_objects_.find(data) != virtual_objects_.end()) return; - // Manually insert the PreparseData since we're combining the size with it's - // byte_data size. - virtual_objects_.insert(data); - virtual_objects_.insert(data->scope_data()); - size_t size = data->Size() + data->scope_data()->Size(); - DCHECK_LE(0, data->scope_data()->length()); - stats_->RecordObjectStats(PREPARSE_DATA_TYPE, size); -} - void ObjectStatsCollectorImpl::RecordVirtualFixedArrayDetails( FixedArray array) { if (IsCowArray(array)) { @@ -706,8 +693,6 @@ void ObjectStatsCollectorImpl::CollectStatistics( } else if (obj->IsArrayBoilerplateDescription()) { RecordVirtualArrayBoilerplateDescription( ArrayBoilerplateDescription::cast(obj)); - } else if (obj->IsPreparseData()) { - RecordVirtualPreparseDataDetails(PreparseData::cast(obj)); } else if (obj->IsFixedArrayExact()) { // Has to go last as it triggers too eagerly. RecordVirtualFixedArrayDetails(FixedArray::cast(obj)); diff --git a/src/objects-body-descriptors-inl.h b/src/objects-body-descriptors-inl.h index 9213244e7b..9339c942ae 100644 --- a/src/objects-body-descriptors-inl.h +++ b/src/objects-body-descriptors-inl.h @@ -505,18 +505,21 @@ class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase { class PreparseData::BodyDescriptor final : public BodyDescriptorBase { public: static bool IsValidSlot(Map map, HeapObject obj, int offset) { - return offset == kScopeDataOffset || offset >= kChildDataStartOffset; + return offset >= PreparseData::cast(obj)->inner_start_offset(); } template static inline void IterateBody(Map map, HeapObject obj, int object_size, ObjectVisitor* v) { - IteratePointer(obj, kScopeDataOffset, v); - IteratePointers(obj, kChildDataStartOffset, object_size, v); + PreparseData data = PreparseData::cast(obj); + int start_offset = data->inner_start_offset(); + int end_offset = start_offset + data->children_length() * kTaggedSize; + IteratePointers(obj, start_offset, end_offset, v); } static inline int SizeOf(Map map, HeapObject obj) { - return PreparseData::SizeFor(PreparseData::cast(obj)->length()); + PreparseData data = PreparseData::cast(obj); + return PreparseData::SizeFor(data->data_length(), data->children_length()); } }; diff --git a/src/objects-debug.cc b/src/objects-debug.cc index e94e2f9751..38422a7bc3 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -2033,12 +2033,12 @@ void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) { void PreparseData::PreparseDataVerify(Isolate* isolate) { CHECK(IsPreparseData()); - CHECK(scope_data()->IsByteArray()); - CHECK_GE(length(), 0); + CHECK_LE(0, data_length()); + CHECK_LE(0, children_length()); - for (int i = 0; i < length(); ++i) { - Object child = child_data(i); - CHECK(child->IsPreparseData() || child->IsNull()); + for (int i = 0; i < children_length(); ++i) { + Object child = get_child_raw(i); + CHECK(child->IsNull() || child->IsPreparseData()); VerifyPointer(isolate, child); } } diff --git a/src/objects-inl.h b/src/objects-inl.h index 22d735e076..72693fd071 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1084,7 +1084,8 @@ int HeapObject::SizeFromMap(Map map) const { return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length()); } if (instance_type == PREPARSE_DATA_TYPE) { - return PreparseData::SizeFor(PreparseData::unchecked_cast(*this)->length()); + PreparseData data = PreparseData::unchecked_cast(*this); + return PreparseData::SizeFor(data->data_length(), data->children_length()); } if (instance_type == CODE_TYPE) { return Code::unchecked_cast(*this)->CodeSize(); diff --git a/src/objects-printer.cc b/src/objects-printer.cc index c7357aa835..02d68b598f 100644 --- a/src/objects-printer.cc +++ b/src/objects-printer.cc @@ -2252,10 +2252,10 @@ void LayoutDescriptor::Print(std::ostream& os) { // NOLINT void PreparseData::PreparseDataPrint(std::ostream& os) { // NOLINT PrintHeader(os, "PreparseData"); - os << "\n - scope_data: " << Brief(scope_data()); - os << "\n - length: " << length(); - for (int i = 0; i < length(); ++i) { - os << "\n - [" << i << "]: " << Brief(child_data(i)); + os << "\n - data_length: " << data_length(); + os << "\n - children_length: " << children_length(); + for (int i = 0; i < children_length(); ++i) { + os << "\n - [" << i << "]: " << Brief(get_child(i)); } os << "\n"; } diff --git a/src/objects.cc b/src/objects.cc index 572622bc7f..6a297b93be 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3600,7 +3600,8 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT case PREPARSE_DATA_TYPE: { PreparseData data = PreparseData::cast(*this); - os << "length() << "]>"; + os << "data_length() + << " children=" << data->children_length() << "]>"; break; } diff --git a/src/objects/shared-function-info-inl.h b/src/objects/shared-function-info-inl.h index e823db4670..11ffa3767b 100644 --- a/src/objects/shared-function-info-inl.h +++ b/src/objects/shared-function-info-inl.h @@ -24,35 +24,64 @@ namespace internal { OBJECT_CONSTRUCTORS_IMPL(PreparseData, HeapObject) CAST_ACCESSOR(PreparseData) -ACCESSORS(PreparseData, scope_data, PodArray, kScopeDataOffset) -INT_ACCESSORS(PreparseData, length, kLengthOffset) +INT_ACCESSORS(PreparseData, data_length, kDataLengthOffset) +INT_ACCESSORS(PreparseData, children_length, kInnerLengthOffset) -Object PreparseData::child_data(int index) const { - DCHECK_GE(index, 0); - DCHECK_LT(index, this->length()); - int offset = kChildDataStartOffset + index * kTaggedSize; - return RELAXED_READ_FIELD(*this, offset); +int PreparseData::inner_start_offset() const { + return InnerOffset(data_length()); } -void PreparseData::set_child_data(int index, Object value, - WriteBarrierMode mode) { - DCHECK_GE(index, 0); - DCHECK_LT(index, this->length()); - int offset = kChildDataStartOffset + index * kTaggedSize; - RELAXED_WRITE_FIELD(*this, offset, value); - CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); -} - -ObjectSlot PreparseData::child_data_start() const { - return RawField(kChildDataStartOffset); +ObjectSlot PreparseData::inner_data_start() const { + return RawField(inner_start_offset()); } void PreparseData::clear_padding() { - if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { - DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); - memset(reinterpret_cast(address() + kOptionalPaddingOffset), 0, - FIELD_SIZE(kOptionalPaddingOffset)); - } + int data_end_offset = kDataStartOffset + data_length(); + int padding_size = inner_start_offset() - data_end_offset; + DCHECK_LE(0, padding_size); + if (padding_size == 0) return; + memset(reinterpret_cast(address() + data_end_offset), 0, padding_size); +} + +byte PreparseData::get(int index) const { + DCHECK_LE(0, index); + DCHECK_LT(index, data_length()); + int offset = kDataStartOffset + index * kByteSize; + return READ_BYTE_FIELD(*this, offset); +} + +void PreparseData::set(int index, byte value) { + DCHECK_LE(0, index); + DCHECK_LT(index, data_length()); + int offset = kDataStartOffset + index * kByteSize; + WRITE_BYTE_FIELD(*this, offset, value); +} + +void PreparseData::copy_in(int index, const byte* buffer, int length) { + DCHECK(index >= 0 && length >= 0 && length <= kMaxInt - index && + index + length <= this->data_length()); + Address dst_addr = FIELD_ADDR(this, kDataStartOffset + index * kByteSize); + memcpy(reinterpret_cast(dst_addr), buffer, length); +} + +PreparseData PreparseData::get_child(int index) const { + return PreparseData::cast(get_child_raw(index)); +} + +Object PreparseData::get_child_raw(int index) const { + DCHECK_LE(0, index); + DCHECK_LT(index, this->children_length()); + int offset = inner_start_offset() + index * kTaggedSize; + return RELAXED_READ_FIELD(*this, offset); +} + +void PreparseData::set_child(int index, PreparseData value, + WriteBarrierMode mode) { + DCHECK_LE(0, index); + DCHECK_LT(index, this->children_length()); + int offset = inner_start_offset() + index * kTaggedSize; + RELAXED_WRITE_FIELD(*this, offset, value); + CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); } OBJECT_CONSTRUCTORS_IMPL(UncompiledData, HeapObject) @@ -65,11 +94,10 @@ INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset) INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset) void UncompiledData::clear_padding() { - if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { - DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); - memset(reinterpret_cast(address() + kOptionalPaddingOffset), 0, - FIELD_SIZE(kOptionalPaddingOffset)); - } + if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return; + DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); + memset(reinterpret_cast(address() + kOptionalPaddingOffset), 0, + FIELD_SIZE(kOptionalPaddingOffset)); } CAST_ACCESSOR(UncompiledDataWithoutPreparseData) diff --git a/src/objects/shared-function-info.h b/src/objects/shared-function-info.h index 6b5bfb61d5..5091744a1e 100644 --- a/src/objects/shared-function-info.h +++ b/src/objects/shared-function-info.h @@ -27,16 +27,37 @@ class WasmExportedFunctionData; // Data collected by the pre-parser storing information about scopes and inner // functions. +// +// PreparseData Layout: +// +-------------------------------+ +// | data_length | children_length | +// +-------------------------------+ +// | Scope Byte Data ... | +// | ... | +// +-------------------------------+ +// | [Padding] | +// +-------------------------------+ +// | Inner PreparseData 1 | +// +-------------------------------+ +// | ... | +// +-------------------------------+ +// | Inner PreparseData N | +// +-------------------------------+ class PreparseData : public HeapObject { public: - DECL_ACCESSORS(scope_data, PodArray) - DECL_INT_ACCESSORS(length) + DECL_INT_ACCESSORS(data_length) + DECL_INT_ACCESSORS(children_length) - inline Object child_data(int index) const; - inline void set_child_data(int index, Object value, - WriteBarrierMode mode = UPDATE_WRITE_BARRIER); + inline int inner_start_offset() const; + inline ObjectSlot inner_data_start() const; - inline ObjectSlot child_data_start() const; + inline byte get(int index) const; + inline void set(int index, byte value); + inline void copy_in(int index, const byte* buffer, int length); + + inline PreparseData get_child(int index) const; + inline void set_child(int index, PreparseData value, + WriteBarrierMode mode = UPDATE_WRITE_BARRIER); // Clear uninitialized padding space. inline void clear_padding(); @@ -46,23 +67,30 @@ class PreparseData : public HeapObject { DECL_VERIFIER(PreparseData) // Layout description. -#define PREPARSE_DATA_FIELDS(V) \ - V(kScopeDataOffset, kTaggedSize) \ - V(kLengthOffset, kIntSize) \ - V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \ - /* Header size. */ \ - V(kChildDataStartOffset, 0) +#define PREPARSE_DATA_FIELDS(V) \ + V(kDataLengthOffset, kInt32Size) \ + V(kInnerLengthOffset, kInt32Size) \ + /* Header size. */ \ + V(kDataStartOffset, 0) \ + V(kHeaderSize, 0) DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, PREPARSE_DATA_FIELDS) #undef PREPARSE_DATA_FIELDS class BodyDescriptor; - static constexpr int SizeFor(int length) { - return kChildDataStartOffset + length * kTaggedSize; + static int InnerOffset(int data_length) { + return RoundUp(kDataStartOffset + data_length * kByteSize, kTaggedSize); + } + + static int SizeFor(int data_length, int children_length) { + return InnerOffset(data_length) + children_length * kTaggedSize; } OBJECT_CONSTRUCTORS(PreparseData, HeapObject); + + private: + inline Object get_child_raw(int index) const; }; // Abstract class representing extra data for an uncompiled function, which is @@ -84,7 +112,6 @@ class UncompiledData : public HeapObject { [](HeapObject object, ObjectSlot slot, HeapObject target) {}); // Layout description. - #define UNCOMPILED_DATA_FIELDS(V) \ V(kStartOfPointerFieldsOffset, 0) \ V(kInferredNameOffset, kTaggedSize) \ diff --git a/src/parsing/preparse-data-impl.h b/src/parsing/preparse-data-impl.h index 8ed0d27b0f..a51d2c42b1 100644 --- a/src/parsing/preparse-data-impl.h +++ b/src/parsing/preparse-data-impl.h @@ -47,7 +47,7 @@ class PreparseDataBuilder::ByteData : public ZoneObject, void OverwriteFirstUint32(uint32_t data); #endif - Handle> Serialize(Isolate* isolate); + void StoreInto(PreparseData data); size_t size() const { return backing_store_.size(); } @@ -60,6 +60,21 @@ class PreparseDataBuilder::ByteData : public ZoneObject, ZoneChunkList backing_store_; }; +// Wraps a ZoneVector to have with functions named the same as +// PodArray. +class ZoneVectorWrapper { + public: + ZoneVectorWrapper() = default; + explicit ZoneVectorWrapper(ZoneVector* data) : data_(data) {} + + int data_length() const { return static_cast(data_->size()); } + + uint8_t get(int index) const { return data_->at(index); } + + private: + ZoneVector* data_ = nullptr; +}; + template class BaseConsumedPreparseData : public ConsumedPreparseData { public: @@ -93,19 +108,19 @@ class BaseConsumedPreparseData : public ConsumedPreparseData { }; void SetPosition(int position) { - DCHECK_LE(position, data_.length()); + DCHECK_LE(position, data_.data_length()); index_ = position; } size_t RemainingBytes() const { DCHECK(has_data_); - DCHECK_LE(index_, data_.length()); - return data_.length() - index_; + DCHECK_LE(index_, data_.data_length()); + return data_.data_length() - index_; } bool HasRemainingBytes(size_t bytes) const { DCHECK(has_data_); - return index_ <= data_.length() && bytes <= RemainingBytes(); + return index_ <= data_.data_length() && bytes <= RemainingBytes(); } int32_t ReadUint32() { @@ -188,33 +203,18 @@ class BaseConsumedPreparseData : public ConsumedPreparseData { // Implementation of ConsumedPreparseData for on-heap data. class OnHeapConsumedPreparseData final - : public BaseConsumedPreparseData> { + : public BaseConsumedPreparseData { public: OnHeapConsumedPreparseData(Isolate* isolate, Handle data); - PodArray GetScopeData() final; - ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; + PreparseData GetScopeData() final; + ProducedPreparseData* GetChildData(Zone* zone, int index) final; private: Isolate* isolate_; Handle data_; }; -// Wraps a ZoneVector to have with functions named the same as -// PodArray. -class ZoneVectorWrapper { - public: - ZoneVectorWrapper() = default; - explicit ZoneVectorWrapper(ZoneVector* data) : data_(data) {} - - int length() const { return static_cast(data_->size()); } - - uint8_t get(int index) const { return data_->at(index); } - - private: - ZoneVector* data_ = nullptr; -}; - // A serialized PreparseData in zone memory (as apposed to being on-heap). class ZonePreparseData : public ZoneObject { public: diff --git a/src/parsing/preparse-data.cc b/src/parsing/preparse-data.cc index 27ad607c5f..4b9194a9ee 100644 --- a/src/parsing/preparse-data.cc +++ b/src/parsing/preparse-data.cc @@ -135,19 +135,12 @@ void PreparseDataBuilder::ByteData::WriteQuarter(uint8_t data) { backing_store_.back() |= (data << shift_amount); } -Handle> PreparseDataBuilder::ByteData::Serialize( - Isolate* isolate) { - Handle> array = PodArray::New( - isolate, static_cast(backing_store_.size()), TENURED); - +void PreparseDataBuilder::ByteData::StoreInto(PreparseData data) { DisallowHeapAllocation no_gc; - PodArray raw_array = *array; - int i = 0; for (uint8_t item : backing_store_) { - raw_array->set(i++, item); + data->set(i++, item); } - return array; } PreparseDataBuilder::PreparseDataBuilder(Zone* zone, @@ -252,17 +245,15 @@ Handle PreparseDataBuilder::Serialize(Isolate* isolate) { DCHECK(!ThisOrParentBailedOut()); int child_data_length = static_cast(data_for_inner_functions_.size()); - Handle data = - isolate->factory()->NewPreparseData(child_data_length); - - Handle> scope_data_array = byte_data_->Serialize(isolate); - data->set_scope_data(*scope_data_array); + Handle data = isolate->factory()->NewPreparseData( + static_cast(byte_data_->size()), child_data_length); + byte_data_->StoreInto(*data); int i = 0; for (const auto& item : data_for_inner_functions_) { DCHECK_NOT_NULL(item); Handle child_data = item->Serialize(isolate); - data->set_child_data(i++, *child_data); + data->set_child(i++, *child_data); } return data; @@ -588,25 +579,18 @@ void BaseConsumedPreparseData::VerifyDataStart() { } #endif -PodArray OnHeapConsumedPreparseData::GetScopeData() { - return data_->scope_data(); -} +PreparseData OnHeapConsumedPreparseData::GetScopeData() { return *data_; } -ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData( - Zone* zone, int child_index) { - CHECK_GT(data_->length(), child_index); - Object child_data = data_->child_data(child_index); - if (!child_data->IsPreparseData()) return nullptr; - Handle child_data_handle(PreparseData::cast(child_data), - isolate_); +ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone, + int index) { + DisallowHeapAllocation no_gc; + Handle child_data_handle(data_->get_child(index), isolate_); return ProducedPreparseData::For(child_data_handle, zone); } OnHeapConsumedPreparseData::OnHeapConsumedPreparseData( Isolate* isolate, Handle data) - : BaseConsumedPreparseData>(), - isolate_(isolate), - data_(data) { + : BaseConsumedPreparseData(), isolate_(isolate), data_(data) { DCHECK_NOT_NULL(isolate); DCHECK(data->IsPreparseData()); #ifdef DEBUG @@ -621,22 +605,17 @@ ZonePreparseData::ZonePreparseData(Zone* zone, children_(child_length, zone) {} Handle ZonePreparseData::Serialize(Isolate* isolate) { + int data_size = static_cast(byte_data()->size()); int child_data_length = child_length(); Handle result = - isolate->factory()->NewPreparseData(child_data_length); - - Handle> scope_data_array = PodArray::New( - isolate, static_cast(byte_data()->size()), TENURED); - scope_data_array->copy_in(0, byte_data()->data(), - static_cast(byte_data()->size())); - result->set_scope_data(*scope_data_array); + isolate->factory()->NewPreparseData(data_size, child_data_length); + result->copy_in(0, byte_data()->data(), data_size); for (int i = 0; i < child_data_length; i++) { ZonePreparseData* child = get_child(i); - if (child) { - Handle child_data = child->Serialize(isolate); - result->set_child_data(i, *child_data); - } + DCHECK_NOT_NULL(child); + Handle child_data = child->Serialize(isolate); + result->set_child(i, *child_data); } return result; } diff --git a/test/cctest/parsing/test-preparser.cc b/test/cctest/parsing/test-preparser.cc index 52be41073f..849b4da8fd 100644 --- a/test/cctest/parsing/test-preparser.cc +++ b/test/cctest/parsing/test-preparser.cc @@ -862,7 +862,9 @@ TEST(ProducingAndConsumingByteData) { { // Serialize as an OnHeapConsumedPreparseData, and read back data. - i::Handle> data_on_heap = bytes.Serialize(isolate); + i::Handle data_on_heap = + isolate->factory()->NewPreparseData(static_cast(bytes.size()), 0); + bytes.StoreInto(*data_on_heap); i::OnHeapConsumedPreparseData::ByteData bytes_for_reading; i::OnHeapConsumedPreparseData::ByteData::ReadingScope reading_scope( &bytes_for_reading, *data_on_heap);