Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2794473002: Stream StaticGet (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "vm/object_store.h" 7 #include "vm/object_store.h"
8 8
9 #if !defined(DART_PRECOMPILED_RUNTIME) 9 #if !defined(DART_PRECOMPILED_RUNTIME)
10 10
(...skipping 20 matching lines...) Expand all
31 : builder_->parsed_function()->function().script())), 31 : builder_->parsed_function()->function().script())),
32 result_(Instance::Handle(zone)) {} 32 result_(Instance::Handle(zone)) {}
33 33
34 34
35 Instance& StreamingConstantEvaluator::EvaluateExpression() { 35 Instance& StreamingConstantEvaluator::EvaluateExpression() {
36 intptr_t offset = builder_->ReaderOffset(); 36 intptr_t offset = builder_->ReaderOffset();
37 if (!GetCachedConstant(offset, &result_)) { 37 if (!GetCachedConstant(offset, &result_)) {
38 uint8_t payload = 0; 38 uint8_t payload = 0;
39 Tag tag = builder_->ReadTag(&payload); 39 Tag tag = builder_->ReadTag(&payload);
40 switch (tag) { 40 switch (tag) {
41 case kStaticGet:
42 EvaluateStaticGet();
43 break;
41 case kSymbolLiteral: 44 case kSymbolLiteral:
42 EvaluateSymbolLiteral(); 45 EvaluateSymbolLiteral();
43 break; 46 break;
44 case kDoubleLiteral: 47 case kDoubleLiteral:
45 EvaluateDoubleLiteral(); 48 EvaluateDoubleLiteral();
46 break; 49 break;
47 default: 50 default:
48 UNREACHABLE(); 51 UNREACHABLE();
49 } 52 }
50 53
51 CacheConstantValue(offset, result_); 54 CacheConstantValue(offset, result_);
52 } 55 }
53 // We return a new `ZoneHandle` here on purpose: The intermediate language 56 // We return a new `ZoneHandle` here on purpose: The intermediate language
54 // instructions do not make a copy of the handle, so we do it. 57 // instructions do not make a copy of the handle, so we do it.
55 return dart::Instance::ZoneHandle(Z, result_.raw()); 58 return dart::Instance::ZoneHandle(Z, result_.raw());
56 } 59 }
57 60
61 void StreamingConstantEvaluator::EvaluateStaticGet() {
62 builder_->ReadPosition();
63 int canonical_name_index = builder_->ReadUInt();
64 CanonicalName* target = builder_->GetCanonicalName(canonical_name_index);
65
66 if (target->IsField()) {
67 const dart::Field& field =
68 dart::Field::Handle(Z, H.LookupFieldByKernelField(target));
69 if (field.StaticValue() == Object::sentinel().raw() ||
70 field.StaticValue() == Object::transition_sentinel().raw()) {
71 field.EvaluateInitializer();
72 result_ = field.StaticValue();
73 result_ = H.Canonicalize(result_);
74 field.SetStaticValue(result_, true);
75 } else {
76 result_ = field.StaticValue();
77 }
78 } else if (target->IsProcedure()) {
79 const Function& function =
80 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
81
82 if (target->IsMethod()) {
83 Function& closure_function =
84 Function::ZoneHandle(Z, function.ImplicitClosureFunction());
85 closure_function.set_kernel_function(function.kernel_function());
86 result_ = closure_function.ImplicitStaticClosure();
87 result_ = H.Canonicalize(result_);
88 } else if (target->IsGetter()) {
89 UNIMPLEMENTED();
90 } else {
91 UNIMPLEMENTED();
92 }
93 }
94 }
95
58 void StreamingConstantEvaluator::EvaluateSymbolLiteral() { 96 void StreamingConstantEvaluator::EvaluateSymbolLiteral() {
59 int str_index = builder_->ReadUInt(); 97 int str_index = builder_->ReadUInt();
60 const dart::String& symbol_value = builder_->DartSymbol(str_index); 98 const dart::String& symbol_value = builder_->DartSymbol(str_index);
61 99
62 const dart::Class& symbol_class = 100 const dart::Class& symbol_class =
63 dart::Class::ZoneHandle(Z, I->object_store()->symbol_class()); 101 dart::Class::ZoneHandle(Z, I->object_store()->symbol_class());
64 ASSERT(!symbol_class.IsNull()); 102 ASSERT(!symbol_class.IsNull());
65 const dart::Function& symbol_constructor = Function::ZoneHandle( 103 const dart::Function& symbol_constructor = Function::ZoneHandle(
66 Z, symbol_class.LookupConstructor(Symbols::SymbolCtor())); 104 Z, symbol_class.LookupConstructor(Symbols::SymbolCtor()));
67 ASSERT(!symbol_constructor.IsNull()); 105 ASSERT(!symbol_constructor.IsNull());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 // case kSpecializedVariableSet: 223 // case kSpecializedVariableSet:
186 // return VariableSet::ReadFrom(reader_, payload); 224 // return VariableSet::ReadFrom(reader_, payload);
187 // case kPropertyGet: 225 // case kPropertyGet:
188 // return PropertyGet::ReadFrom(reader_); 226 // return PropertyGet::ReadFrom(reader_);
189 // case kPropertySet: 227 // case kPropertySet:
190 // return PropertySet::ReadFrom(reader_); 228 // return PropertySet::ReadFrom(reader_);
191 // case kDirectPropertyGet: 229 // case kDirectPropertyGet:
192 // return DirectPropertyGet::ReadFrom(reader_); 230 // return DirectPropertyGet::ReadFrom(reader_);
193 // case kDirectPropertySet: 231 // case kDirectPropertySet:
194 // return DirectPropertySet::ReadFrom(reader_); 232 // return DirectPropertySet::ReadFrom(reader_);
195 // case kStaticGet: 233 case kStaticGet:
196 // return StaticGet::ReadFrom(reader_); 234 return BuildStaticGet();
197 // case kStaticSet: 235 // case kStaticSet:
198 // return StaticSet::ReadFrom(reader_); 236 // return StaticSet::ReadFrom(reader_);
199 // case kMethodInvocation: 237 // case kMethodInvocation:
200 // return MethodInvocation::ReadFrom(reader_); 238 // return MethodInvocation::ReadFrom(reader_);
201 // case kDirectMethodInvocation: 239 // case kDirectMethodInvocation:
202 // return DirectMethodInvocation::ReadFrom(reader_); 240 // return DirectMethodInvocation::ReadFrom(reader_);
203 // case kStaticInvocation: 241 // case kStaticInvocation:
204 // return StaticInvocation::ReadFrom(reader_, false); 242 // return StaticInvocation::ReadFrom(reader_, false);
205 // case kConstStaticInvocation: 243 // case kConstStaticInvocation:
206 // return StaticInvocation::ReadFrom(reader_, true); 244 // return StaticInvocation::ReadFrom(reader_, true);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 UNREACHABLE(); 304 UNREACHABLE();
267 } 305 }
268 306
269 return Fragment(); 307 return Fragment();
270 } 308 }
271 309
272 intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) { 310 intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) {
273 if (string_table_offsets_ != NULL && string_table_entries_read_ > index) { 311 if (string_table_offsets_ != NULL && string_table_entries_read_ > index) {
274 return string_table_offsets_[index]; 312 return string_table_offsets_[index];
275 } 313 }
314
315 intptr_t saved_offset = ReaderOffset();
276 if (string_table_offsets_ == NULL) { 316 if (string_table_offsets_ == NULL) {
277 reader_->set_offset(4); // Skip kMagicProgramFile - now at string table. 317 reader_->set_offset(4); // Skip kMagicProgramFile - now at string table.
278 string_table_size_ = ReadListLength(); 318 string_table_size_ = ReadListLength();
279 string_table_offsets_ = new intptr_t[string_table_size_]; 319 string_table_offsets_ = new intptr_t[string_table_size_];
280 string_table_offsets_[0] = ReaderOffset(); 320 string_table_offsets_[0] = ReaderOffset();
281 string_table_entries_read_ = 1; 321 string_table_entries_read_ = 1;
282 } 322 }
283 323
284 ASSERT(string_table_size_ > index); 324 ASSERT(string_table_size_ > index);
285 --string_table_entries_read_; 325 --string_table_entries_read_;
286 reader_->set_offset(string_table_offsets_[string_table_entries_read_]); 326 reader_->set_offset(string_table_offsets_[string_table_entries_read_]);
287 for (; string_table_entries_read_ < index; ++string_table_entries_read_) { 327 for (; string_table_entries_read_ < index; ++string_table_entries_read_) {
288 string_table_offsets_[string_table_entries_read_] = ReaderOffset(); 328 string_table_offsets_[string_table_entries_read_] = ReaderOffset();
289 uint32_t bytes = ReadUInt(); 329 uint32_t bytes = ReadUInt();
290 SkipBytes(bytes); 330 SkipBytes(bytes);
291 } 331 }
292 string_table_offsets_[string_table_entries_read_] = ReaderOffset(); 332 string_table_offsets_[string_table_entries_read_] = ReaderOffset();
293 ++string_table_entries_read_; 333 ++string_table_entries_read_;
294 334
335 SetOffset(saved_offset);
295 return string_table_offsets_[index]; 336 return string_table_offsets_[index];
296 } 337 }
297 338
339 CanonicalName* StreamingFlowGraphBuilder::GetCanonicalName(intptr_t index) {
340 if (index == 0) return NULL;
341 --index;
342
343 if (canonical_names_ != NULL && canonical_names_entries_read_ > index) {
344 return canonical_names_[index];
345 }
346
347 intptr_t saved_offset = ReaderOffset();
348 if (canonical_names_ == NULL) {
349 // Find offset from where to read canonical names table.
350
351 // First skip the string table:
352 // Get first string to make sure we have the table size, get last string and
353 // read it to get past the string table.
354 // Note that this will also cache all string positions.
355 GetStringTableOffset(0);
356 SetOffset(GetStringTableOffset(string_table_size_ - 1));
357 uint32_t bytes = ReadUInt();
358 SkipBytes(bytes);
359
360 // Another string table (source URIs)
361 intptr_t list_length = ReadListLength();
362 for (intptr_t i = 0; i < list_length; ++i) {
363 uint32_t bytes = ReadUInt();
364 SkipBytes(bytes);
365 }
366
367 // Source code table
368 for (intptr_t i = 0; i < list_length; ++i) {
369 // Source code
370 intptr_t bytes = ReadUInt();
371 SkipBytes(bytes);
372
373 // Line starts table
374 intptr_t line_count = ReadUInt();
375 for (intptr_t j = 0; j < line_count; ++j) {
376 ReadUInt();
377 }
378 }
379
380 // Now at canonical names table.
381 canonical_names_size_ = ReadUInt();
382 canonical_names_ = new CanonicalName*[canonical_names_size_];
383 canonical_names_next_offset_ = ReaderOffset();
384 }
385
386 SetOffset(canonical_names_next_offset_);
387 for (; canonical_names_entries_read_ <= index;
388 ++canonical_names_entries_read_) {
389 intptr_t biased_parent_index = ReadUInt();
390 CanonicalName* parent;
391 if (biased_parent_index != 0) {
392 parent = canonical_names_[biased_parent_index - 1];
393 } else {
394 if (canonical_names_entries_read_ == 0) {
395 parent = CanonicalName::NewRoot();
396 } else {
397 parent = canonical_names_[0]->parent();
398 }
399 }
400 ASSERT(parent != NULL);
401 intptr_t name_index = ReadUInt();
402 String* name = KernelString(name_index);
403 CanonicalName* canonical_name = parent->AddChild(name);
404 canonical_names_[canonical_names_entries_read_] = canonical_name;
405 }
406
407 canonical_names_next_offset_ = ReaderOffset();
408
409 SetOffset(saved_offset);
410 return canonical_names_[index];
411 }
412
298 intptr_t StreamingFlowGraphBuilder::ReaderOffset() { 413 intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
299 return reader_->offset(); 414 return reader_->offset();
300 } 415 }
301 416
302 void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) { 417 void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) {
303 reader_->set_offset(offset); 418 reader_->set_offset(offset);
304 } 419 }
305 420
306 void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) { 421 void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) {
307 reader_->set_offset(ReaderOffset() + bytes); 422 reader_->set_offset(ReaderOffset() + bytes);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 intptr_t saved_offset = ReaderOffset(); 465 intptr_t saved_offset = ReaderOffset();
351 466
352 SetOffset(GetStringTableOffset(str_index)); 467 SetOffset(GetStringTableOffset(str_index));
353 uint32_t bytes = ReadUInt(); 468 uint32_t bytes = ReadUInt();
354 const uint8_t* data = &reader_->buffer()[ReaderOffset()]; 469 const uint8_t* data = &reader_->buffer()[ReaderOffset()];
355 470
356 SetOffset(saved_offset); 471 SetOffset(saved_offset);
357 return H.DartString(data, bytes); 472 return H.DartString(data, bytes);
358 } 473 }
359 474
475 String* StreamingFlowGraphBuilder::KernelString(intptr_t str_index) {
476 intptr_t savedOffset = ReaderOffset();
477
478 SetOffset(GetStringTableOffset(str_index));
479 uint32_t bytes = ReadUInt();
480 const uint8_t* data = &reader_->buffer()[ReaderOffset()];
481
482 SetOffset(savedOffset);
483 return new String(data, bytes);
484 }
485
360 Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) { 486 Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) {
361 return flow_graph_builder_->DebugStepCheck(position); 487 return flow_graph_builder_->DebugStepCheck(position);
362 } 488 }
363 489
364 Fragment StreamingFlowGraphBuilder::LoadLocal(LocalVariable* variable) { 490 Fragment StreamingFlowGraphBuilder::LoadLocal(LocalVariable* variable) {
365 return flow_graph_builder_->LoadLocal(variable); 491 return flow_graph_builder_->LoadLocal(variable);
366 } 492 }
367 493
368 Fragment StreamingFlowGraphBuilder::PushArgument() { 494 Fragment StreamingFlowGraphBuilder::PushArgument() {
369 return flow_graph_builder_->PushArgument(); 495 return flow_graph_builder_->PushArgument();
370 } 496 }
371 497
372 Fragment StreamingFlowGraphBuilder::RethrowException(TokenPosition position, 498 Fragment StreamingFlowGraphBuilder::RethrowException(TokenPosition position,
373 int catch_try_index) { 499 int catch_try_index) {
374 return flow_graph_builder_->RethrowException(position, catch_try_index); 500 return flow_graph_builder_->RethrowException(position, catch_try_index);
375 } 501 }
376 502
377 Fragment StreamingFlowGraphBuilder::ThrowNoSuchMethodError() { 503 Fragment StreamingFlowGraphBuilder::ThrowNoSuchMethodError() {
378 return flow_graph_builder_->ThrowNoSuchMethodError(); 504 return flow_graph_builder_->ThrowNoSuchMethodError();
379 } 505 }
380 506
381 Fragment StreamingFlowGraphBuilder::Constant(const Object& value) { 507 Fragment StreamingFlowGraphBuilder::Constant(const Object& value) {
382 return flow_graph_builder_->Constant(value); 508 return flow_graph_builder_->Constant(value);
383 } 509 }
384 510
385 Fragment StreamingFlowGraphBuilder::IntConstant(int64_t value) { 511 Fragment StreamingFlowGraphBuilder::IntConstant(int64_t value) {
386 return flow_graph_builder_->IntConstant(value); 512 return flow_graph_builder_->IntConstant(value);
387 } 513 }
388 514
515 Fragment StreamingFlowGraphBuilder::LoadStaticField() {
516 return flow_graph_builder_->LoadStaticField();
517 }
518
519 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
520 const Function& target,
521 intptr_t argument_count) {
522 return flow_graph_builder_->StaticCall(position, target, argument_count);
523 }
524
389 Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() { 525 Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() {
390 // The frontend will take care of emitting normal errors (like 526 // The frontend will take care of emitting normal errors (like
391 // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special 527 // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special
392 // situations (e.g. an invalid annotation). 528 // situations (e.g. an invalid annotation).
393 return ThrowNoSuchMethodError(); 529 return ThrowNoSuchMethodError();
394 } 530 }
395 531
532 Fragment StreamingFlowGraphBuilder::BuildStaticGet() {
533 intptr_t saved_offset = ReaderOffset() - 1; // Include the tag.
534 TokenPosition position = ReadPosition();
535 int canonical_name_index = ReadUInt();
536 CanonicalName* target = GetCanonicalName(canonical_name_index);
537
538 if (target->IsField()) {
539 const dart::Field& field =
540 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
541 if (field.is_const()) {
542 SetOffset(saved_offset); // EvaluateExpression needs the tag.
543 return Constant(constant_evaluator_.EvaluateExpression());
544 } else {
545 const dart::Class& owner = dart::Class::Handle(Z, field.Owner());
546 const dart::String& getter_name = H.DartGetterName(target);
547 const Function& getter =
548 Function::ZoneHandle(Z, owner.LookupStaticFunction(getter_name));
549 if (getter.IsNull() || !field.has_initializer()) {
550 Fragment instructions = Constant(field);
551 return instructions + LoadStaticField();
552 } else {
553 return StaticCall(position, getter, 0);
554 }
555 }
556 } else {
557 const Function& function =
558 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
559
560 if (target->IsGetter()) {
561 return StaticCall(position, function, 0);
562 } else if (target->IsMethod()) {
563 SetOffset(saved_offset); // EvaluateExpression needs the tag.
564 return Constant(constant_evaluator_.EvaluateExpression());
565 } else {
566 UNIMPLEMENTED();
567 }
568 }
569
570 return Fragment();
571 }
572
396 Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral() { 573 Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral() {
397 SkipBytes(-1); // EvaluateExpression needs the tag. 574 SkipBytes(-1); // EvaluateExpression needs the tag.
398 return Constant(constant_evaluator_.EvaluateExpression()); 575 return Constant(constant_evaluator_.EvaluateExpression());
399 } 576 }
400 577
401 Fragment StreamingFlowGraphBuilder::BuildThisExpression() { 578 Fragment StreamingFlowGraphBuilder::BuildThisExpression() {
402 return LoadLocal(scopes()->this_variable); 579 return LoadLocal(scopes()->this_variable);
403 } 580 }
404 581
405 Fragment StreamingFlowGraphBuilder::BuildRethrow() { 582 Fragment StreamingFlowGraphBuilder::BuildRethrow() {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 621 }
445 622
446 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { 623 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() {
447 return Constant(Instance::ZoneHandle(Z, Instance::null())); 624 return Constant(Instance::ZoneHandle(Z, Instance::null()));
448 } 625 }
449 626
450 } // namespace kernel 627 } // namespace kernel
451 } // namespace dart 628 } // namespace dart
452 629
453 #endif // !defined(DART_PRECOMPILED_RUNTIME) 630 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698