Reland "[parser] Inline byte scope data into PreparseData object"

This is a reland of e2d44ede95

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 <leszeks@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Commit-Queue: Camillo Bruni <cbruni@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#58751}

Change-Id: I1f0a22c641d0d67f435b01c82daf8da7f144bff4
Reviewed-on: https://chromium-review.googlesource.com/c/1407066
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58785}
This commit is contained in:
Camillo Bruni 2019-01-14 14:34:42 +01:00 committed by Commit Bot
parent c8567109f5
commit a6f4462987
15 changed files with 170 additions and 145 deletions

View File

@ -111,8 +111,6 @@ const unsigned kRegCodeMask = 0x1f;
const unsigned kShiftAmountWRegMask = 0x1f; const unsigned kShiftAmountWRegMask = 0x1f;
const unsigned kShiftAmountXRegMask = 0x3f; const unsigned kShiftAmountXRegMask = 0x3f;
// Standard machine types defined by AAPCS64. // Standard machine types defined by AAPCS64.
const unsigned kByteSize = 8;
const unsigned kByteSizeInBytes = kByteSize >> 3;
const unsigned kHalfWordSize = 16; const unsigned kHalfWordSize = 16;
const unsigned kHalfWordSizeLog2 = 4; const unsigned kHalfWordSizeLog2 = 4;
const unsigned kHalfWordSizeInBytes = kHalfWordSize >> 3; const unsigned kHalfWordSizeInBytes = kHalfWordSize >> 3;

View File

@ -119,6 +119,7 @@ constexpr uint32_t kMaxUInt32 = 0xFFFFFFFFu;
constexpr int kMinUInt32 = 0; constexpr int kMinUInt32 = 0;
constexpr int kUInt8Size = sizeof(uint8_t); constexpr int kUInt8Size = sizeof(uint8_t);
constexpr int kByteSize = sizeof(byte);
constexpr int kCharSize = sizeof(char); constexpr int kCharSize = sizeof(char);
constexpr int kShortSize = sizeof(short); // NOLINT constexpr int kShortSize = sizeof(short); // NOLINT
constexpr int kUInt16Size = sizeof(uint16_t); constexpr int kUInt16Size = sizeof(uint16_t);

View File

@ -2638,15 +2638,15 @@ Handle<ModuleInfo> Factory::NewModuleInfo() {
ModuleInfo::kLength, TENURED); ModuleInfo::kLength, TENURED);
} }
Handle<PreparseData> Factory::NewPreparseData(int length) { Handle<PreparseData> Factory::NewPreparseData(int data_length,
int size = PreparseData::SizeFor(length); int children_length) {
int size = PreparseData::SizeFor(data_length, children_length);
Handle<PreparseData> result(PreparseData::cast(AllocateRawWithImmortalMap( Handle<PreparseData> result(PreparseData::cast(AllocateRawWithImmortalMap(
size, TENURED, *preparse_data_map())), size, TENURED, *preparse_data_map())),
isolate()); isolate());
result->set_scope_data(PodArray<uint8_t>::cast(*empty_byte_array())); result->set_data_length(data_length);
result->set_length(length); result->set_children_length(children_length);
MemsetTagged(result->child_data_start(), *null_value(), length); MemsetTagged(result->inner_data_start(), *null_value(), children_length);
result->clear_padding(); result->clear_padding();
return result; return result;
} }

View File

@ -750,7 +750,7 @@ class V8_EXPORT_PRIVATE Factory {
Handle<ModuleInfo> NewModuleInfo(); Handle<ModuleInfo> NewModuleInfo();
Handle<PreparseData> NewPreparseData(int length); Handle<PreparseData> NewPreparseData(int data_length, int children_length);
Handle<UncompiledDataWithoutPreparseData> Handle<UncompiledDataWithoutPreparseData>
NewUncompiledDataWithoutPreparseData(Handle<String> inferred_name, NewUncompiledDataWithoutPreparseData(Handle<String> inferred_name,

View File

@ -401,7 +401,6 @@ class ObjectStatsCollectorImpl {
void RecordVirtualExternalStringDetails(ExternalString script); void RecordVirtualExternalStringDetails(ExternalString script);
void RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo info); void RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo info);
void RecordVirtualJSFunctionDetails(JSFunction function); void RecordVirtualJSFunctionDetails(JSFunction function);
void RecordVirtualPreparseDataDetails(PreparseData data);
void RecordVirtualArrayBoilerplateDescription( void RecordVirtualArrayBoilerplateDescription(
ArrayBoilerplateDescription description); ArrayBoilerplateDescription description);
@ -650,18 +649,6 @@ void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
CHECK_EQ(calculated_size, vector->Size()); 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( void ObjectStatsCollectorImpl::RecordVirtualFixedArrayDetails(
FixedArray array) { FixedArray array) {
if (IsCowArray(array)) { if (IsCowArray(array)) {
@ -706,8 +693,6 @@ void ObjectStatsCollectorImpl::CollectStatistics(
} else if (obj->IsArrayBoilerplateDescription()) { } else if (obj->IsArrayBoilerplateDescription()) {
RecordVirtualArrayBoilerplateDescription( RecordVirtualArrayBoilerplateDescription(
ArrayBoilerplateDescription::cast(obj)); ArrayBoilerplateDescription::cast(obj));
} else if (obj->IsPreparseData()) {
RecordVirtualPreparseDataDetails(PreparseData::cast(obj));
} else if (obj->IsFixedArrayExact()) { } else if (obj->IsFixedArrayExact()) {
// Has to go last as it triggers too eagerly. // Has to go last as it triggers too eagerly.
RecordVirtualFixedArrayDetails(FixedArray::cast(obj)); RecordVirtualFixedArrayDetails(FixedArray::cast(obj));

View File

@ -505,18 +505,21 @@ class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
class PreparseData::BodyDescriptor final : public BodyDescriptorBase { class PreparseData::BodyDescriptor final : public BodyDescriptorBase {
public: public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) { static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return offset == kScopeDataOffset || offset >= kChildDataStartOffset; return offset >= PreparseData::cast(obj)->inner_start_offset();
} }
template <typename ObjectVisitor> template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size, static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) { ObjectVisitor* v) {
IteratePointer(obj, kScopeDataOffset, v); PreparseData data = PreparseData::cast(obj);
IteratePointers(obj, kChildDataStartOffset, object_size, v); 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) { 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());
} }
}; };

View File

@ -2033,12 +2033,12 @@ void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
void PreparseData::PreparseDataVerify(Isolate* isolate) { void PreparseData::PreparseDataVerify(Isolate* isolate) {
CHECK(IsPreparseData()); CHECK(IsPreparseData());
CHECK(scope_data()->IsByteArray()); CHECK_LE(0, data_length());
CHECK_GE(length(), 0); CHECK_LE(0, children_length());
for (int i = 0; i < length(); ++i) { for (int i = 0; i < children_length(); ++i) {
Object child = child_data(i); Object child = get_child_raw(i);
CHECK(child->IsPreparseData() || child->IsNull()); CHECK(child->IsNull() || child->IsPreparseData());
VerifyPointer(isolate, child); VerifyPointer(isolate, child);
} }
} }

View File

@ -1084,7 +1084,8 @@ int HeapObject::SizeFromMap(Map map) const {
return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length()); return BigInt::SizeFor(BigInt::unchecked_cast(*this)->length());
} }
if (instance_type == PREPARSE_DATA_TYPE) { 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) { if (instance_type == CODE_TYPE) {
return Code::unchecked_cast(*this)->CodeSize(); return Code::unchecked_cast(*this)->CodeSize();

View File

@ -2252,10 +2252,10 @@ void LayoutDescriptor::Print(std::ostream& os) { // NOLINT
void PreparseData::PreparseDataPrint(std::ostream& os) { // NOLINT void PreparseData::PreparseDataPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "PreparseData"); PrintHeader(os, "PreparseData");
os << "\n - scope_data: " << Brief(scope_data()); os << "\n - data_length: " << data_length();
os << "\n - length: " << length(); os << "\n - children_length: " << children_length();
for (int i = 0; i < length(); ++i) { for (int i = 0; i < children_length(); ++i) {
os << "\n - [" << i << "]: " << Brief(child_data(i)); os << "\n - [" << i << "]: " << Brief(get_child(i));
} }
os << "\n"; os << "\n";
} }

View File

@ -3600,7 +3600,8 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
case PREPARSE_DATA_TYPE: { case PREPARSE_DATA_TYPE: {
PreparseData data = PreparseData::cast(*this); PreparseData data = PreparseData::cast(*this);
os << "<PreparseData[" << data->length() << "]>"; os << "<PreparseData[data=" << data->data_length()
<< " children=" << data->children_length() << "]>";
break; break;
} }

View File

@ -24,35 +24,64 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(PreparseData, HeapObject) OBJECT_CONSTRUCTORS_IMPL(PreparseData, HeapObject)
CAST_ACCESSOR(PreparseData) CAST_ACCESSOR(PreparseData)
ACCESSORS(PreparseData, scope_data, PodArray<uint8_t>, kScopeDataOffset) INT_ACCESSORS(PreparseData, data_length, kDataLengthOffset)
INT_ACCESSORS(PreparseData, length, kLengthOffset) INT_ACCESSORS(PreparseData, children_length, kInnerLengthOffset)
Object PreparseData::child_data(int index) const { int PreparseData::inner_start_offset() const {
DCHECK_GE(index, 0); return InnerOffset(data_length());
DCHECK_LT(index, this->length());
int offset = kChildDataStartOffset + index * kTaggedSize;
return RELAXED_READ_FIELD(*this, offset);
} }
void PreparseData::set_child_data(int index, Object value, ObjectSlot PreparseData::inner_data_start() const {
WriteBarrierMode mode) { return RawField(inner_start_offset());
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);
} }
void PreparseData::clear_padding() { void PreparseData::clear_padding() {
if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { int data_end_offset = kDataStartOffset + data_length();
DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); int padding_size = inner_start_offset() - data_end_offset;
memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0, DCHECK_LE(0, padding_size);
FIELD_SIZE(kOptionalPaddingOffset)); if (padding_size == 0) return;
} memset(reinterpret_cast<void*>(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<void*>(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) OBJECT_CONSTRUCTORS_IMPL(UncompiledData, HeapObject)
@ -65,11 +94,10 @@ INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset) INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset)
void UncompiledData::clear_padding() { void UncompiledData::clear_padding() {
if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return;
DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0, memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
FIELD_SIZE(kOptionalPaddingOffset)); FIELD_SIZE(kOptionalPaddingOffset));
}
} }
CAST_ACCESSOR(UncompiledDataWithoutPreparseData) CAST_ACCESSOR(UncompiledDataWithoutPreparseData)

View File

@ -27,16 +27,37 @@ class WasmExportedFunctionData;
// Data collected by the pre-parser storing information about scopes and inner // Data collected by the pre-parser storing information about scopes and inner
// functions. // functions.
//
// PreparseData Layout:
// +-------------------------------+
// | data_length | children_length |
// +-------------------------------+
// | Scope Byte Data ... |
// | ... |
// +-------------------------------+
// | [Padding] |
// +-------------------------------+
// | Inner PreparseData 1 |
// +-------------------------------+
// | ... |
// +-------------------------------+
// | Inner PreparseData N |
// +-------------------------------+
class PreparseData : public HeapObject { class PreparseData : public HeapObject {
public: public:
DECL_ACCESSORS(scope_data, PodArray<uint8_t>) DECL_INT_ACCESSORS(data_length)
DECL_INT_ACCESSORS(length) DECL_INT_ACCESSORS(children_length)
inline Object child_data(int index) const; inline int inner_start_offset() const;
inline void set_child_data(int index, Object value, inline ObjectSlot inner_data_start() const;
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
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. // Clear uninitialized padding space.
inline void clear_padding(); inline void clear_padding();
@ -46,23 +67,30 @@ class PreparseData : public HeapObject {
DECL_VERIFIER(PreparseData) DECL_VERIFIER(PreparseData)
// Layout description. // Layout description.
#define PREPARSE_DATA_FIELDS(V) \ #define PREPARSE_DATA_FIELDS(V) \
V(kScopeDataOffset, kTaggedSize) \ V(kDataLengthOffset, kInt32Size) \
V(kLengthOffset, kIntSize) \ V(kInnerLengthOffset, kInt32Size) \
V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \ /* Header size. */ \
/* Header size. */ \ V(kDataStartOffset, 0) \
V(kChildDataStartOffset, 0) V(kHeaderSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, PREPARSE_DATA_FIELDS) DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, PREPARSE_DATA_FIELDS)
#undef PREPARSE_DATA_FIELDS #undef PREPARSE_DATA_FIELDS
class BodyDescriptor; class BodyDescriptor;
static constexpr int SizeFor(int length) { static int InnerOffset(int data_length) {
return kChildDataStartOffset + length * kTaggedSize; 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); OBJECT_CONSTRUCTORS(PreparseData, HeapObject);
private:
inline Object get_child_raw(int index) const;
}; };
// Abstract class representing extra data for an uncompiled function, which is // 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) {}); [](HeapObject object, ObjectSlot slot, HeapObject target) {});
// Layout description. // Layout description.
#define UNCOMPILED_DATA_FIELDS(V) \ #define UNCOMPILED_DATA_FIELDS(V) \
V(kStartOfPointerFieldsOffset, 0) \ V(kStartOfPointerFieldsOffset, 0) \
V(kInferredNameOffset, kTaggedSize) \ V(kInferredNameOffset, kTaggedSize) \

View File

@ -47,7 +47,7 @@ class PreparseDataBuilder::ByteData : public ZoneObject,
void OverwriteFirstUint32(uint32_t data); void OverwriteFirstUint32(uint32_t data);
#endif #endif
Handle<PodArray<uint8_t>> Serialize(Isolate* isolate); void StoreInto(PreparseData data);
size_t size() const { return backing_store_.size(); } size_t size() const { return backing_store_.size(); }
@ -60,6 +60,21 @@ class PreparseDataBuilder::ByteData : public ZoneObject,
ZoneChunkList<uint8_t> backing_store_; ZoneChunkList<uint8_t> backing_store_;
}; };
// Wraps a ZoneVector<uint8_t> to have with functions named the same as
// PodArray<uint8_t>.
class ZoneVectorWrapper {
public:
ZoneVectorWrapper() = default;
explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {}
int data_length() const { return static_cast<int>(data_->size()); }
uint8_t get(int index) const { return data_->at(index); }
private:
ZoneVector<uint8_t>* data_ = nullptr;
};
template <class Data> template <class Data>
class BaseConsumedPreparseData : public ConsumedPreparseData { class BaseConsumedPreparseData : public ConsumedPreparseData {
public: public:
@ -93,19 +108,19 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
}; };
void SetPosition(int position) { void SetPosition(int position) {
DCHECK_LE(position, data_.length()); DCHECK_LE(position, data_.data_length());
index_ = position; index_ = position;
} }
size_t RemainingBytes() const { size_t RemainingBytes() const {
DCHECK(has_data_); DCHECK(has_data_);
DCHECK_LE(index_, data_.length()); DCHECK_LE(index_, data_.data_length());
return data_.length() - index_; return data_.data_length() - index_;
} }
bool HasRemainingBytes(size_t bytes) const { bool HasRemainingBytes(size_t bytes) const {
DCHECK(has_data_); DCHECK(has_data_);
return index_ <= data_.length() && bytes <= RemainingBytes(); return index_ <= data_.data_length() && bytes <= RemainingBytes();
} }
int32_t ReadUint32() { int32_t ReadUint32() {
@ -188,33 +203,18 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
// Implementation of ConsumedPreparseData for on-heap data. // Implementation of ConsumedPreparseData for on-heap data.
class OnHeapConsumedPreparseData final class OnHeapConsumedPreparseData final
: public BaseConsumedPreparseData<PodArray<uint8_t>> { : public BaseConsumedPreparseData<PreparseData> {
public: public:
OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data); OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data);
PodArray<uint8_t> GetScopeData() final; PreparseData GetScopeData() final;
ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; ProducedPreparseData* GetChildData(Zone* zone, int index) final;
private: private:
Isolate* isolate_; Isolate* isolate_;
Handle<PreparseData> data_; Handle<PreparseData> data_;
}; };
// Wraps a ZoneVector<uint8_t> to have with functions named the same as
// PodArray<uint8_t>.
class ZoneVectorWrapper {
public:
ZoneVectorWrapper() = default;
explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {}
int length() const { return static_cast<int>(data_->size()); }
uint8_t get(int index) const { return data_->at(index); }
private:
ZoneVector<uint8_t>* data_ = nullptr;
};
// A serialized PreparseData in zone memory (as apposed to being on-heap). // A serialized PreparseData in zone memory (as apposed to being on-heap).
class ZonePreparseData : public ZoneObject { class ZonePreparseData : public ZoneObject {
public: public:

View File

@ -135,19 +135,12 @@ void PreparseDataBuilder::ByteData::WriteQuarter(uint8_t data) {
backing_store_.back() |= (data << shift_amount); backing_store_.back() |= (data << shift_amount);
} }
Handle<PodArray<uint8_t>> PreparseDataBuilder::ByteData::Serialize( void PreparseDataBuilder::ByteData::StoreInto(PreparseData data) {
Isolate* isolate) {
Handle<PodArray<uint8_t>> array = PodArray<uint8_t>::New(
isolate, static_cast<int>(backing_store_.size()), TENURED);
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
PodArray<uint8_t> raw_array = *array;
int i = 0; int i = 0;
for (uint8_t item : backing_store_) { for (uint8_t item : backing_store_) {
raw_array->set(i++, item); data->set(i++, item);
} }
return array;
} }
PreparseDataBuilder::PreparseDataBuilder(Zone* zone, PreparseDataBuilder::PreparseDataBuilder(Zone* zone,
@ -252,17 +245,15 @@ Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) {
DCHECK(!ThisOrParentBailedOut()); DCHECK(!ThisOrParentBailedOut());
int child_data_length = static_cast<int>(data_for_inner_functions_.size()); int child_data_length = static_cast<int>(data_for_inner_functions_.size());
Handle<PreparseData> data = Handle<PreparseData> data = isolate->factory()->NewPreparseData(
isolate->factory()->NewPreparseData(child_data_length); static_cast<int>(byte_data_->size()), child_data_length);
byte_data_->StoreInto(*data);
Handle<PodArray<uint8_t>> scope_data_array = byte_data_->Serialize(isolate);
data->set_scope_data(*scope_data_array);
int i = 0; int i = 0;
for (const auto& item : data_for_inner_functions_) { for (const auto& item : data_for_inner_functions_) {
DCHECK_NOT_NULL(item); DCHECK_NOT_NULL(item);
Handle<PreparseData> child_data = item->Serialize(isolate); Handle<PreparseData> child_data = item->Serialize(isolate);
data->set_child_data(i++, *child_data); data->set_child(i++, *child_data);
} }
return data; return data;
@ -588,25 +579,18 @@ void BaseConsumedPreparseData<Data>::VerifyDataStart() {
} }
#endif #endif
PodArray<uint8_t> OnHeapConsumedPreparseData::GetScopeData() { PreparseData OnHeapConsumedPreparseData::GetScopeData() { return *data_; }
return data_->scope_data();
}
ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData( ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone,
Zone* zone, int child_index) { int index) {
CHECK_GT(data_->length(), child_index); DisallowHeapAllocation no_gc;
Object child_data = data_->child_data(child_index); Handle<PreparseData> child_data_handle(data_->get_child(index), isolate_);
if (!child_data->IsPreparseData()) return nullptr;
Handle<PreparseData> child_data_handle(PreparseData::cast(child_data),
isolate_);
return ProducedPreparseData::For(child_data_handle, zone); return ProducedPreparseData::For(child_data_handle, zone);
} }
OnHeapConsumedPreparseData::OnHeapConsumedPreparseData( OnHeapConsumedPreparseData::OnHeapConsumedPreparseData(
Isolate* isolate, Handle<PreparseData> data) Isolate* isolate, Handle<PreparseData> data)
: BaseConsumedPreparseData<PodArray<uint8_t>>(), : BaseConsumedPreparseData<PreparseData>(), isolate_(isolate), data_(data) {
isolate_(isolate),
data_(data) {
DCHECK_NOT_NULL(isolate); DCHECK_NOT_NULL(isolate);
DCHECK(data->IsPreparseData()); DCHECK(data->IsPreparseData());
#ifdef DEBUG #ifdef DEBUG
@ -621,22 +605,17 @@ ZonePreparseData::ZonePreparseData(Zone* zone,
children_(child_length, zone) {} children_(child_length, zone) {}
Handle<PreparseData> ZonePreparseData::Serialize(Isolate* isolate) { Handle<PreparseData> ZonePreparseData::Serialize(Isolate* isolate) {
int data_size = static_cast<int>(byte_data()->size());
int child_data_length = child_length(); int child_data_length = child_length();
Handle<PreparseData> result = Handle<PreparseData> result =
isolate->factory()->NewPreparseData(child_data_length); isolate->factory()->NewPreparseData(data_size, child_data_length);
result->copy_in(0, byte_data()->data(), data_size);
Handle<PodArray<uint8_t>> scope_data_array = PodArray<uint8_t>::New(
isolate, static_cast<int>(byte_data()->size()), TENURED);
scope_data_array->copy_in(0, byte_data()->data(),
static_cast<int>(byte_data()->size()));
result->set_scope_data(*scope_data_array);
for (int i = 0; i < child_data_length; i++) { for (int i = 0; i < child_data_length; i++) {
ZonePreparseData* child = get_child(i); ZonePreparseData* child = get_child(i);
if (child) { DCHECK_NOT_NULL(child);
Handle<PreparseData> child_data = child->Serialize(isolate); Handle<PreparseData> child_data = child->Serialize(isolate);
result->set_child_data(i, *child_data); result->set_child(i, *child_data);
}
} }
return result; return result;
} }

View File

@ -862,7 +862,9 @@ TEST(ProducingAndConsumingByteData) {
{ {
// Serialize as an OnHeapConsumedPreparseData, and read back data. // Serialize as an OnHeapConsumedPreparseData, and read back data.
i::Handle<i::PodArray<uint8_t>> data_on_heap = bytes.Serialize(isolate); i::Handle<i::PreparseData> data_on_heap =
isolate->factory()->NewPreparseData(static_cast<int>(bytes.size()), 0);
bytes.StoreInto(*data_on_heap);
i::OnHeapConsumedPreparseData::ByteData bytes_for_reading; i::OnHeapConsumedPreparseData::ByteData bytes_for_reading;
i::OnHeapConsumedPreparseData::ByteData::ReadingScope reading_scope( i::OnHeapConsumedPreparseData::ByteData::ReadingScope reading_scope(
&bytes_for_reading, *data_on_heap); &bytes_for_reading, *data_on_heap);