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 442 : int data_length() const { return static_cast<int>(data_->size()); }
26 :
27 7504 : 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 37126 : class BaseConsumedPreparseData : public ConsumedPreparseData {
35 : public:
36 : class ByteData : public PreparseByteDataConstants {
37 : public:
38 37136 : 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 99220 : consumed_data->data_ = data;
48 : #ifdef DEBUG
49 : consumed_data->has_data_ = true;
50 : #endif
51 : }
52 : explicit ReadingScope(BaseConsumedPreparseData<Data>* parent)
53 99210 : : 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 62342 : return data_.data_length() - index_;
74 : }
75 :
76 : bool HasRemainingBytes(size_t bytes) const {
77 : DCHECK(has_data_);
78 385658 : return index_ <= data_.data_length() && bytes <= RemainingBytes();
79 : }
80 :
81 249408 : 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 250240 : int32_t result = data_.get(index_) + (data_.get(index_ + 1) << 8) +
87 832 : (data_.get(index_ + 2) << 16) +
88 996800 : (data_.get(index_ + 3) << 24);
89 249408 : index_ += 4;
90 249408 : stored_quarters_ = 0;
91 249408 : return result;
92 : }
93 :
94 : uint8_t ReadUint8() {
95 : DCHECK(has_data_);
96 : DCHECK(HasRemainingBytes(kUint8Size));
97 : // Check that there indeed is a byte following.
98 : DCHECK_EQ(data_.get(index_++), kUint8Size);
99 99336 : stored_quarters_ = 0;
100 99356 : return data_.get(index_++);
101 : }
102 :
103 335739 : uint8_t ReadQuarter() {
104 : DCHECK(has_data_);
105 335739 : if (stored_quarters_ == 0) {
106 : DCHECK(HasRemainingBytes(kUint8Size));
107 : // Check that there indeed are quarters following.
108 : DCHECK_EQ(data_.get(index_++), kQuarterMarker);
109 329835 : stored_byte_ = data_.get(index_++);
110 165048 : stored_quarters_ = 4;
111 : }
112 : // Read the first 2 bits from stored_byte_.
113 335739 : uint8_t result = (stored_byte_ >> 6) & 3;
114 : DCHECK_LE(result, 3);
115 335739 : --stored_quarters_;
116 335739 : stored_byte_ <<= 2;
117 335739 : return result;
118 : }
119 :
120 : private:
121 : Data data_ = {};
122 : int index_ = 0;
123 : uint8_t stored_quarters_ = 0;
124 : uint8_t stored_byte_ = 0;
125 : #ifdef DEBUG
126 : bool has_data_ = false;
127 : #endif
128 : };
129 :
130 111378 : BaseConsumedPreparseData() : scope_data_(new ByteData()), child_index_(0) {}
131 :
132 : virtual Data GetScopeData() = 0;
133 :
134 : virtual ProducedPreparseData* GetChildData(Zone* zone, int child_index) = 0;
135 :
136 : ProducedPreparseData* GetDataForSkippableFunction(
137 : Zone* zone, int start_position, int* end_position, int* num_parameters,
138 : int* num_inner_functions, bool* uses_super_property,
139 : LanguageMode* language_mode) final;
140 :
141 : void RestoreScopeAllocationData(DeclarationScope* scope) final;
142 :
143 : #ifdef DEBUG
144 : void VerifyDataStart();
145 : #endif
146 :
147 : private:
148 99306 : void RestoreDataForScope(Scope* scope);
149 : void RestoreDataForVariable(Variable* var);
150 99306 : void RestoreDataForInnerScopes(Scope* scope);
151 :
152 : std::unique_ptr<ByteData> scope_data_;
153 : // When consuming the data, these indexes point to the data we're going to
154 : // consume next.
155 : int child_index_;
156 :
157 : DISALLOW_COPY_AND_ASSIGN(BaseConsumedPreparseData);
158 : };
159 :
160 : // Implementation of ConsumedPreparseData for on-heap data.
161 74232 : class OnHeapConsumedPreparseData final
162 : : public BaseConsumedPreparseData<PreparseData> {
163 : public:
164 : OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data);
165 :
166 : PreparseData GetScopeData() final;
167 : ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
168 :
169 : private:
170 : Isolate* isolate_;
171 : Handle<PreparseData> data_;
172 : };
173 :
174 : // A serialized PreparseData in zone memory (as apposed to being on-heap).
175 : class ZonePreparseData : public ZoneObject {
176 : public:
177 : ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data, int child_length);
178 :
179 : Handle<PreparseData> Serialize(Isolate* isolate);
180 :
181 0 : int children_length() const { return static_cast<int>(children_.size()); }
182 :
183 0 : ZonePreparseData* get_child(int index) { return children_[index]; }
184 :
185 : void set_child(int index, ZonePreparseData* child) {
186 : DCHECK_NOT_NULL(child);
187 0 : children_[index] = child;
188 : }
189 :
190 : ZoneVector<uint8_t>* byte_data() { return &byte_data_; }
191 :
192 : private:
193 : ZoneVector<uint8_t> byte_data_;
194 : ZoneVector<ZonePreparseData*> children_;
195 :
196 : DISALLOW_COPY_AND_ASSIGN(ZonePreparseData);
197 : };
198 :
199 : // Implementation of ConsumedPreparseData for PreparseData
200 : // serialized into zone memory.
201 20 : class ZoneConsumedPreparseData final
202 : : public BaseConsumedPreparseData<ZoneVectorWrapper> {
203 : public:
204 : ZoneConsumedPreparseData(Zone* zone, ZonePreparseData* data);
205 :
206 : ZoneVectorWrapper GetScopeData() final;
207 : ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
208 :
209 : private:
210 : ZonePreparseData* data_;
211 : ZoneVectorWrapper scope_data_wrapper_;
212 : };
213 :
214 : } // namespace internal
215 : } // namespace v8
216 :
217 : #endif // V8_PARSING_PREPARSE_DATA_IMPL_H_
|