OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/kernel_binary_flowgraph.h" | 5 #include "vm/kernel_binary_flowgraph.h" |
6 | 6 |
7 #if !defined(DART_PRECOMPILED_RUNTIME) | 7 #if !defined(DART_PRECOMPILED_RUNTIME) |
8 | 8 |
9 namespace dart { | 9 namespace dart { |
10 namespace kernel { | 10 namespace kernel { |
11 | 11 |
12 #define Z (flow_graph_builder_->zone_) | 12 #define Z (zone_) |
13 #define H (flow_graph_builder_->translation_helper_) | 13 #define H (translation_helper_) |
14 | |
15 StreamingConstantEvaluator::StreamingConstantEvaluator( | |
16 StreamingFlowGraphBuilder* builder, | |
17 Zone* zone, | |
18 TranslationHelper* h, | |
Kevin Millikin (Google)
2017/03/31 12:23:41
h ==> helper
| |
19 DartTypeTranslator* type_translator) | |
20 : builder_(builder), | |
21 isolate_(Isolate::Current()), | |
22 zone_(zone), | |
23 translation_helper_(*h), | |
24 // type_translator_(*type_translator), | |
Kevin Millikin (Google)
2017/03/31 12:23:41
Why this commented out code?
| |
25 script_(Script::Handle( | |
26 zone, | |
27 builder == NULL ? Script::null() | |
28 : builder_->parsed_function()->function().script())), | |
29 result_(Instance::Handle(zone)) {} | |
30 | |
31 | |
32 Instance& StreamingConstantEvaluator::EvaluateExpression() { | |
33 intptr_t offset = builder_->ReaderOffset(); | |
34 if (!GetCachedConstant(offset, &result_)) { | |
35 uint8_t payload = 0; | |
36 Tag tag = builder_->ReadTag(&payload); | |
37 switch (tag) { | |
38 case kDoubleLiteral: | |
39 EvaluateDoubleLiteral(); | |
40 break; | |
41 default: | |
42 UNREACHABLE(); | |
43 } | |
44 | |
45 CacheConstantValue(offset, result_); | |
46 } | |
47 // We return a new `ZoneHandle` here on purpose: The intermediate language | |
48 // instructions do not make a copy of the handle, so we do it. | |
49 return dart::Instance::ZoneHandle(Z, result_.raw()); | |
Kevin Millikin (Google)
2017/03/31 12:23:41
I guess you just copied this, but it doesn't need
| |
50 } | |
51 | |
52 void StreamingConstantEvaluator::EvaluateDoubleLiteral() { | |
53 int str_index = builder_->ReadUInt(); | |
54 result_ = dart::Double::New(builder_->DartString(str_index), Heap::kOld); | |
Kevin Millikin (Google)
2017/03/31 12:23:41
I don't think we need dart:: here either.
| |
55 result_ = H.Canonicalize(result_); | |
56 } | |
57 | |
58 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset, | |
59 Instance* value) { | |
60 if (builder_ == NULL) return false; | |
61 | |
62 const Function& function = builder_->parsed_function()->function(); | |
63 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { | |
64 // Don't cache constants in initializer expressions. They get | |
65 // evaluated only once. | |
66 return false; | |
67 } | |
68 | |
69 bool is_present = false; | |
70 ASSERT(!script_.InVMHeap()); | |
71 if (script_.compile_time_constants() == Array::null()) { | |
72 return false; | |
73 } | |
74 KernelConstantsMap constants(script_.compile_time_constants()); | |
75 *value ^= constants.GetOrNull(kernel_offset, &is_present); | |
76 // Mutator compiler thread may add constants while background compiler | |
77 // is running, and thus change the value of 'compile_time_constants'; | |
78 // do not assert that 'compile_time_constants' has not changed. | |
79 constants.Release(); | |
80 if (FLAG_compiler_stats && is_present) { | |
81 H.thread()->compiler_stats()->num_const_cache_hits++; | |
82 } | |
83 return is_present; | |
84 } | |
85 | |
86 | |
87 void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset, | |
88 const Instance& value) { | |
89 ASSERT(Thread::Current()->IsMutatorThread()); | |
90 | |
91 if (builder_ == NULL) return; | |
92 | |
93 const Function& function = builder_->parsed_function()->function(); | |
94 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { | |
95 // Don't cache constants in initializer expressions. They get | |
96 // evaluated only once. | |
97 return; | |
98 } | |
99 const intptr_t kInitialConstMapSize = 16; | |
100 ASSERT(!script_.InVMHeap()); | |
101 if (script_.compile_time_constants() == Array::null()) { | |
102 const Array& array = Array::Handle( | |
103 HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew)); | |
104 script_.set_compile_time_constants(array); | |
105 } | |
106 KernelConstantsMap constants(script_.compile_time_constants()); | |
107 constants.InsertNewOrGetValue(kernel_offset, value); | |
108 script_.set_compile_time_constants(constants.Release()); | |
109 } | |
110 | |
14 | 111 |
15 Fragment StreamingFlowGraphBuilder::BuildAt(intptr_t kernel_offset) { | 112 Fragment StreamingFlowGraphBuilder::BuildAt(intptr_t kernel_offset) { |
16 reader_->set_offset(kernel_offset); | 113 SetOffset(kernel_offset); |
17 | 114 |
18 uint8_t payload = 0; | 115 uint8_t payload = 0; |
19 Tag tag = reader_->ReadTag(&payload); | 116 Tag tag = ReadTag(&payload); |
20 switch (tag) { | 117 switch (tag) { |
21 case kInvalidExpression: | 118 case kInvalidExpression: |
22 return BuildInvalidExpression(); | 119 return BuildInvalidExpression(); |
23 // case kVariableGet: | 120 // case kVariableGet: |
24 // return VariableGet::ReadFrom(reader_); | 121 // return VariableGet::ReadFrom(reader_); |
25 // case kSpecializedVariableGet: | 122 // case kSpecializedVariableGet: |
26 // return VariableGet::ReadFrom(reader_, payload); | 123 // return VariableGet::ReadFrom(reader_, payload); |
27 // case kVariableSet: | 124 // case kVariableSet: |
28 // return VariableSet::ReadFrom(reader_); | 125 // return VariableSet::ReadFrom(reader_); |
29 // case kSpecializedVariableSet: | 126 // case kSpecializedVariableSet: |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 // case kBigIntLiteral: | 188 // case kBigIntLiteral: |
92 // return BigintLiteral::ReadFrom(reader_); | 189 // return BigintLiteral::ReadFrom(reader_); |
93 case kStringLiteral: | 190 case kStringLiteral: |
94 return BuildStringLiteral(); | 191 return BuildStringLiteral(); |
95 case kSpecialIntLiteral: | 192 case kSpecialIntLiteral: |
96 return BuildIntLiteral(payload); | 193 return BuildIntLiteral(payload); |
97 case kNegativeIntLiteral: | 194 case kNegativeIntLiteral: |
98 return BuildIntLiteral(true); | 195 return BuildIntLiteral(true); |
99 case kPositiveIntLiteral: | 196 case kPositiveIntLiteral: |
100 return BuildIntLiteral(false); | 197 return BuildIntLiteral(false); |
101 // case kDoubleLiteral: | 198 case kDoubleLiteral: |
102 // return DoubleLiteral::ReadFrom(reader_); | 199 return BuildDoubleLiteral(); |
103 case kTrueLiteral: | 200 case kTrueLiteral: |
104 return BuildBoolLiteral(true); | 201 return BuildBoolLiteral(true); |
105 case kFalseLiteral: | 202 case kFalseLiteral: |
106 return BuildBoolLiteral(false); | 203 return BuildBoolLiteral(false); |
107 case kNullLiteral: | 204 case kNullLiteral: |
108 return BuildNullLiteral(); | 205 return BuildNullLiteral(); |
109 default: | 206 default: |
110 UNREACHABLE(); | 207 UNREACHABLE(); |
111 } | 208 } |
112 | 209 |
113 return Fragment(); | 210 return Fragment(); |
114 } | 211 } |
115 | 212 |
116 intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) { | 213 intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) { |
117 if (string_table_offsets_ != NULL && string_table_entries_read_ > index) { | 214 if (string_table_offsets_ != NULL && string_table_entries_read_ > index) { |
118 return string_table_offsets_[index]; | 215 return string_table_offsets_[index]; |
119 } | 216 } |
120 if (string_table_offsets_ == NULL) { | 217 if (string_table_offsets_ == NULL) { |
121 reader_->set_offset(4); // Skip kMagicProgramFile - now at string table. | 218 reader_->set_offset(4); // Skip kMagicProgramFile - now at string table. |
122 string_table_size_ = ReadListLength(); | 219 string_table_size_ = ReadListLength(); |
123 string_table_offsets_ = new intptr_t[string_table_size_]; | 220 string_table_offsets_ = new intptr_t[string_table_size_]; |
124 string_table_offsets_[0] = reader_->offset(); | 221 string_table_offsets_[0] = ReaderOffset(); |
125 string_table_entries_read_ = 1; | 222 string_table_entries_read_ = 1; |
126 } | 223 } |
127 | 224 |
128 ASSERT(string_table_size_ > index); | 225 ASSERT(string_table_size_ > index); |
129 --string_table_entries_read_; | 226 --string_table_entries_read_; |
130 reader_->set_offset(string_table_offsets_[string_table_entries_read_]); | 227 reader_->set_offset(string_table_offsets_[string_table_entries_read_]); |
131 for (; string_table_entries_read_ < index; ++string_table_entries_read_) { | 228 for (; string_table_entries_read_ < index; ++string_table_entries_read_) { |
132 string_table_offsets_[string_table_entries_read_] = reader_->offset(); | 229 string_table_offsets_[string_table_entries_read_] = ReaderOffset(); |
133 uint32_t bytes = ReadUInt(); | 230 uint32_t bytes = ReadUInt(); |
134 reader_->set_offset(reader_->offset() + bytes); | 231 SkipBytes(bytes); |
135 } | 232 } |
136 string_table_offsets_[string_table_entries_read_] = reader_->offset(); | 233 string_table_offsets_[string_table_entries_read_] = ReaderOffset(); |
137 ++string_table_entries_read_; | 234 ++string_table_entries_read_; |
138 | 235 |
139 return string_table_offsets_[index]; | 236 return string_table_offsets_[index]; |
140 } | 237 } |
141 | 238 |
239 intptr_t StreamingFlowGraphBuilder::ReaderOffset() { | |
240 return reader_->offset(); | |
241 } | |
242 | |
243 void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) { | |
244 reader_->set_offset(offset); | |
245 } | |
246 | |
247 void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) { | |
248 reader_->set_offset(ReaderOffset() + bytes); | |
249 } | |
250 | |
142 uint32_t StreamingFlowGraphBuilder::ReadUInt() { | 251 uint32_t StreamingFlowGraphBuilder::ReadUInt() { |
143 return reader_->ReadUInt(); | 252 return reader_->ReadUInt(); |
144 } | 253 } |
145 | 254 |
146 intptr_t StreamingFlowGraphBuilder::ReadListLength() { | 255 intptr_t StreamingFlowGraphBuilder::ReadListLength() { |
147 return reader_->ReadListLength(); | 256 return reader_->ReadListLength(); |
148 } | 257 } |
149 | 258 |
150 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { | 259 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { |
151 return reader_->ReadPosition(record); | 260 return reader_->ReadPosition(record); |
152 } | 261 } |
153 | 262 |
263 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) { | |
264 return reader_->ReadTag(payload); | |
265 } | |
266 | |
154 CatchBlock* StreamingFlowGraphBuilder::catch_block() { | 267 CatchBlock* StreamingFlowGraphBuilder::catch_block() { |
155 return flow_graph_builder_->catch_block_; | 268 return flow_graph_builder_->catch_block_; |
156 } | 269 } |
157 | 270 |
158 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() { | 271 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() { |
159 return flow_graph_builder_->scopes_; | 272 return flow_graph_builder_->scopes_; |
160 } | 273 } |
161 | 274 |
275 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() { | |
276 return flow_graph_builder_->parsed_function_; | |
277 } | |
278 | |
279 dart::String& StreamingFlowGraphBuilder::DartSymbol(intptr_t str_index) { | |
280 intptr_t savedOffset = ReaderOffset(); | |
281 | |
282 SetOffset(GetStringTableOffset(str_index)); | |
283 uint32_t bytes = ReadUInt(); | |
284 const uint8_t* data = &reader_->buffer()[ReaderOffset()]; | |
285 | |
286 SetOffset(savedOffset); | |
287 return H.DartSymbol(data, bytes); | |
288 } | |
289 | |
290 dart::String& StreamingFlowGraphBuilder::DartString(intptr_t str_index) { | |
291 intptr_t savedOffset = ReaderOffset(); | |
292 | |
293 SetOffset(GetStringTableOffset(str_index)); | |
294 uint32_t bytes = ReadUInt(); | |
295 const uint8_t* data = &reader_->buffer()[ReaderOffset()]; | |
296 | |
297 SetOffset(savedOffset); | |
298 return H.DartString(data, bytes); | |
299 } | |
300 | |
162 Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) { | 301 Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) { |
163 return flow_graph_builder_->DebugStepCheck(position); | 302 return flow_graph_builder_->DebugStepCheck(position); |
164 } | 303 } |
165 | 304 |
166 Fragment StreamingFlowGraphBuilder::LoadLocal(LocalVariable* variable) { | 305 Fragment StreamingFlowGraphBuilder::LoadLocal(LocalVariable* variable) { |
167 return flow_graph_builder_->LoadLocal(variable); | 306 return flow_graph_builder_->LoadLocal(variable); |
168 } | 307 } |
169 | 308 |
170 Fragment StreamingFlowGraphBuilder::PushArgument() { | 309 Fragment StreamingFlowGraphBuilder::PushArgument() { |
171 return flow_graph_builder_->PushArgument(); | 310 return flow_graph_builder_->PushArgument(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 instructions += LoadLocal(catch_block()->exception_var()); | 344 instructions += LoadLocal(catch_block()->exception_var()); |
206 instructions += PushArgument(); | 345 instructions += PushArgument(); |
207 instructions += LoadLocal(catch_block()->stack_trace_var()); | 346 instructions += LoadLocal(catch_block()->stack_trace_var()); |
208 instructions += PushArgument(); | 347 instructions += PushArgument(); |
209 instructions += RethrowException(position, catch_block()->catch_try_index()); | 348 instructions += RethrowException(position, catch_block()->catch_try_index()); |
210 | 349 |
211 return instructions; | 350 return instructions; |
212 } | 351 } |
213 | 352 |
214 Fragment StreamingFlowGraphBuilder::BuildStringLiteral() { | 353 Fragment StreamingFlowGraphBuilder::BuildStringLiteral() { |
215 int str_index = ReadUInt(); | 354 intptr_t str_index = ReadUInt(); |
216 intptr_t savedOffset = reader_->offset(); | 355 return Constant(DartSymbol(str_index)); |
217 | |
218 reader_->set_offset(GetStringTableOffset(str_index)); | |
219 uint32_t bytes = ReadUInt(); | |
220 const uint8_t* data = &reader_->buffer()[reader_->offset()]; | |
221 | |
222 reader_->set_offset(savedOffset); | |
223 return Constant(H.DartSymbol(data, bytes)); | |
224 } | 356 } |
225 | 357 |
226 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) { | 358 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) { |
227 int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; | 359 int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; |
228 return IntConstant(value); | 360 return IntConstant(value); |
229 } | 361 } |
230 | 362 |
231 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative) { | 363 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative) { |
232 int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt()) : ReadUInt(); | 364 int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt()) : ReadUInt(); |
233 return IntConstant(value); | 365 return IntConstant(value); |
234 } | 366 } |
235 | 367 |
368 Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral() { | |
369 SkipBytes(-1); // EvaluateExpression needs the tag. | |
370 return Constant(constant_evaluator_.EvaluateExpression()); | |
371 } | |
372 | |
236 Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value) { | 373 Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value) { |
237 return Constant(Bool::Get(value)); | 374 return Constant(Bool::Get(value)); |
238 } | 375 } |
239 | 376 |
240 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { | 377 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { |
241 return Constant(Instance::ZoneHandle(Z, Instance::null())); | 378 return Constant(Instance::ZoneHandle(Z, Instance::null())); |
242 } | 379 } |
243 | 380 |
244 } // namespace kernel | 381 } // namespace kernel |
245 } // namespace dart | 382 } // namespace dart |
246 | 383 |
247 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 384 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |