Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_PARSING_PREPARSE_DATA_IMPL_H_
6 : #define V8_PARSING_PREPARSE_DATA_IMPL_H_
7 :
8 : #include "src/parsing/preparse-data.h"
9 :
10 : #include "src/assert-scope.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // Classes which are internal to prepared-scope-data.cc, but are exposed in
16 : // a header for tests.
17 :
18 : // Wraps a ZoneVector<uint8_t> to have with functions named the same as
19 : // PodArray<uint8_t>.
20 : class ZoneVectorWrapper {
21 : public:
22 : ZoneVectorWrapper() = default;
23 15 : explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {}
24 :
25 490 : int data_length() const { return static_cast<int>(data_->size()); }
26 :
27 4040 : uint8_t get(int index) const { return data_->at(index); }
28 :
29 : private:
30 : ZoneVector<uint8_t>* data_ = nullptr;
31 : };
32 :
33 : template <class Data>
34 36574 : class BaseConsumedPreparseData : public ConsumedPreparseData {
35 : public:
36 : class ByteData : public PreparseByteDataConstants {
37 : public:
38 36584 : ByteData() {}
39 :
40 : // Reading from the ByteData is only allowed when a ReadingScope is on the
41 : // stack. This ensures that we have a DisallowHeapAllocation in place
42 : // whenever ByteData holds a raw pointer into the heap.
43 : class ReadingScope {
44 : public:
45 : ReadingScope(ByteData* consumed_data, Data data)
46 : : consumed_data_(consumed_data) {
47 96748 : consumed_data->data_ = data;
48 : #ifdef DEBUG
49 : consumed_data->has_data_ = true;
50 : #endif
51 : }
52 : explicit ReadingScope(BaseConsumedPreparseData<Data>* parent)
53 96738 : : ReadingScope(parent->scope_data_.get(), parent->GetScopeData()) {}
54 : ~ReadingScope() {
55 : #ifdef DEBUG
56 : consumed_data_->has_data_ = false;
57 : #endif
58 : }
59 :
60 : private:
61 : ByteData* consumed_data_;
62 : DISALLOW_HEAP_ALLOCATION(no_gc)
63 : };
64 :
65 : void SetPosition(int position) {
66 : DCHECK_LE(position, data_.data_length());
67 : index_ = position;
68 : }
69 :
70 : size_t RemainingBytes() const {
71 : DCHECK(has_data_);
72 : DCHECK_LE(index_, data_.data_length());
73 60389 : return data_.data_length() - index_;
74 : }
75 :
76 : bool HasRemainingBytes(size_t bytes) const {
77 : DCHECK(has_data_);
78 379237 : return index_ <= data_.data_length() && bytes <= RemainingBytes();
79 : }
80 :
81 : int32_t ReadUint32() {
82 : DCHECK(has_data_);
83 : DCHECK(HasRemainingBytes(kUint32Size));
84 : // Check that there indeed is an integer following.
85 : DCHECK_EQ(data_.get(index_++), kUint32Size);
86 : int32_t result = data_.get(index_) + (data_.get(index_ + 1) << 8) +
87 : (data_.get(index_ + 2) << 16) +
88 : (data_.get(index_ + 3) << 24);
89 : index_ += 4;
90 : stored_quarters_ = 0;
91 : return result;
92 : }
93 :
94 905 : int32_t ReadVarint32() {
95 : DCHECK(HasRemainingBytes(kVarint32MinSize));
96 : DCHECK_EQ(data_.get(index_++), kVarint32MinSize);
97 : int32_t value = 0;
98 : bool has_another_byte;
99 : unsigned shift = 0;
100 328150 : do {
101 328150 : uint8_t byte = data_.get(index_++);
102 328150 : value |= static_cast<int32_t>(byte & 0x7F) << shift;
103 328150 : shift += 7;
104 328150 : has_another_byte = byte & 0x80;
105 : } while (has_another_byte);
106 : DCHECK_EQ(data_.get(index_++), kVarint32EndMarker);
107 241596 : stored_quarters_ = 0;
108 905 : return value;
109 : }
110 :
111 : uint8_t ReadUint8() {
112 : DCHECK(has_data_);
113 : DCHECK(HasRemainingBytes(kUint8Size));
114 : // Check that there indeed is a byte following.
115 : DCHECK_EQ(data_.get(index_++), kUint8Size);
116 99045 : stored_quarters_ = 0;
117 99075 : return data_.get(index_++);
118 : }
119 :
120 291035 : uint8_t ReadQuarter() {
121 : DCHECK(has_data_);
122 291035 : if (stored_quarters_ == 0) {
123 : DCHECK(HasRemainingBytes(kUint8Size));
124 : // Check that there indeed are quarters following.
125 : DCHECK_EQ(data_.get(index_++), kQuarterMarker);
126 300981 : stored_byte_ = data_.get(index_++);
127 150633 : stored_quarters_ = 4;
128 : }
129 : // Read the first 2 bits from stored_byte_.
130 291035 : uint8_t result = (stored_byte_ >> 6) & 3;
131 : DCHECK_LE(result, 3);
132 291035 : --stored_quarters_;
133 291035 : stored_byte_ <<= 2;
134 291035 : return result;
135 : }
136 :
137 : private:
138 : Data data_ = {};
139 : int index_ = 0;
140 : uint8_t stored_quarters_ = 0;
141 : uint8_t stored_byte_ = 0;
142 : #ifdef DEBUG
143 : bool has_data_ = false;
144 : #endif
145 : };
146 :
147 109722 : BaseConsumedPreparseData() : scope_data_(new ByteData()), child_index_(0) {}
148 :
149 : virtual Data GetScopeData() = 0;
150 :
151 : virtual ProducedPreparseData* GetChildData(Zone* zone, int child_index) = 0;
152 :
153 : ProducedPreparseData* GetDataForSkippableFunction(
154 : Zone* zone, int start_position, int* end_position, int* num_parameters,
155 : int* num_inner_functions, bool* uses_super_property,
156 : LanguageMode* language_mode) final;
157 :
158 : void RestoreScopeAllocationData(DeclarationScope* scope) final;
159 :
160 : #ifdef DEBUG
161 : bool VerifyDataStart();
162 : #endif
163 :
164 : private:
165 99025 : void RestoreDataForScope(Scope* scope);
166 : void RestoreDataForVariable(Variable* var);
167 99025 : void RestoreDataForInnerScopes(Scope* scope);
168 :
169 : std::unique_ptr<ByteData> scope_data_;
170 : // When consuming the data, these indexes point to the data we're going to
171 : // consume next.
172 : int child_index_;
173 :
174 : DISALLOW_COPY_AND_ASSIGN(BaseConsumedPreparseData);
175 : };
176 :
177 : // Implementation of ConsumedPreparseData for on-heap data.
178 73128 : class OnHeapConsumedPreparseData final
179 : : public BaseConsumedPreparseData<PreparseData> {
180 : public:
181 : OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data);
182 :
183 : PreparseData GetScopeData() final;
184 : ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
185 :
186 : private:
187 : Isolate* isolate_;
188 : Handle<PreparseData> data_;
189 : };
190 :
191 : // A serialized PreparseData in zone memory (as apposed to being on-heap).
192 : class ZonePreparseData : public ZoneObject {
193 : public:
194 : ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data, int child_length);
195 :
196 : Handle<PreparseData> Serialize(Isolate* isolate);
197 :
198 0 : int children_length() const { return static_cast<int>(children_.size()); }
199 :
200 0 : ZonePreparseData* get_child(int index) { return children_[index]; }
201 :
202 : void set_child(int index, ZonePreparseData* child) {
203 : DCHECK_NOT_NULL(child);
204 0 : children_[index] = child;
205 : }
206 :
207 : ZoneVector<uint8_t>* byte_data() { return &byte_data_; }
208 :
209 : private:
210 : ZoneVector<uint8_t> byte_data_;
211 : ZoneVector<ZonePreparseData*> children_;
212 :
213 : DISALLOW_COPY_AND_ASSIGN(ZonePreparseData);
214 : };
215 :
216 15 : ZonePreparseData* PreparseDataBuilder::ByteData::CopyToZone(
217 : Zone* zone, int children_length) {
218 : DCHECK(is_finalized_);
219 15 : return new (zone) ZonePreparseData(zone, &zone_byte_data_, children_length);
220 : }
221 :
222 : // Implementation of ConsumedPreparseData for PreparseData
223 : // serialized into zone memory.
224 20 : class ZoneConsumedPreparseData final
225 : : public BaseConsumedPreparseData<ZoneVectorWrapper> {
226 : public:
227 : ZoneConsumedPreparseData(Zone* zone, ZonePreparseData* data);
228 :
229 : ZoneVectorWrapper GetScopeData() final;
230 : ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
231 :
232 : private:
233 : ZonePreparseData* data_;
234 : ZoneVectorWrapper scope_data_wrapper_;
235 : };
236 :
237 : } // namespace internal
238 : } // namespace v8
239 :
240 : #endif // V8_PARSING_PREPARSE_DATA_IMPL_H_
|