Chromium Code Reviews| 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 |