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

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

Issue 10854084: Retrying r10475 (now with null check): (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 for (intptr_t i = 0; i < block_order_.length(); ++i) { 110 for (intptr_t i = 0; i < block_order_.length(); ++i) {
111 BlockEntryInstr* entry = block_order_[i]; 111 BlockEntryInstr* entry = block_order_[i];
112 entry->Accept(this); 112 entry->Accept(this);
113 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 113 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
114 it.Current()->Accept(this); 114 it.Current()->Accept(this);
115 } 115 }
116 } 116 }
117 } 117 }
118 118
119 119
120 // Returns true if the static type of this value is more specific than the 120 // Returns true if the compile type of this value is more specific than the
121 // given dst_type. 121 // given dst_type.
122 // TODO(regis): Should we support a set of static types? 122 // TODO(regis): Support a set of compile types for the given value.
123 bool Value::StaticTypeIsMoreSpecificThan(const AbstractType& dst_type) const { 123 bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const {
124 ASSERT(!dst_type.IsMalformed()); // Should be tested by caller. 124 ASSERT(!dst_type.IsMalformed()); // Should be tested by caller.
125 ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller. 125 ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller.
126 ASSERT(!dst_type.IsObjectType()); // Should be tested by caller. 126 ASSERT(!dst_type.IsObjectType()); // Should be tested by caller.
127 127
128 // If the value is the null constant, its type (NullType) is more specific 128 // If the value is the null constant, its type (NullType) is more specific
129 // than the destination type, even if the destination type is the void type, 129 // than the destination type, even if the destination type is the void type,
130 // since a void function is allowed to return null. 130 // since a void function is allowed to return null.
131 if (IsConstant() && AsConstant()->value().IsNull()) { 131 if (IsConstant() && AsConstant()->value().IsNull()) {
132 return true; 132 return true;
133 } 133 }
134 134
135 // Functions that do not explicitly return a value, implicitly return null, 135 // Functions that do not explicitly return a value, implicitly return null,
136 // except generative constructors, which return the object being constructed. 136 // except generative constructors, which return the object being constructed.
137 // It is therefore acceptable for void functions to return null. 137 // It is therefore acceptable for void functions to return null.
138 // In case of a null constant, we have already returned true above, else we 138 // In case of a null constant, we have already returned true above, else we
139 // return false here. 139 // return false here.
140 if (dst_type.IsVoidType()) { 140 if (dst_type.IsVoidType()) {
141 return false; 141 return false;
142 } 142 }
143 143
144 // Consider the static type of the value. 144 // Consider the compile type of the value.
145 const AbstractType& static_type = AbstractType::Handle(StaticType()); 145 const AbstractType& compile_type = AbstractType::Handle(CompileType());
146 ASSERT(!static_type.IsMalformed()); 146 ASSERT(!compile_type.IsMalformed());
147 147
148 // If the static type of the value is void, we are type checking the result of 148 // If the compile type of the value is void, we are type checking the result
149 // a void function, which was checked to be null at the return statement 149 // of a void function, which was checked to be null at the return statement
150 // inside the function. 150 // inside the function.
151 if (static_type.IsVoidType()) { 151 if (compile_type.IsVoidType()) {
152 return true; 152 return true;
153 } 153 }
154 154
155 // If the static type of the value is NullType, the type test is eliminated. 155 // If the compile type of the value is NullType, the type test is eliminated.
156 // There are only three instances that can be of Class Null: 156 // There are only three instances that can be of Class Null:
157 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). 157 // Object::null(), Object::sentinel(), and Object::transition_sentinel().
158 // The inline code and run time code performing the type check will never 158 // The inline code and run time code performing the type check will never
159 // encounter the 2 sentinel values. The type check of a sentinel value 159 // encounter the 2 sentinel values. The type check of a sentinel value
160 // will always be eliminated here, because these sentinel values can only 160 // will always be eliminated here, because these sentinel values can only
161 // be encountered as constants, never as actual value of a heap object 161 // be encountered as constants, never as actual value of a heap object
162 // being type checked. 162 // being type checked.
163 if (static_type.IsNullType()) { 163 if (compile_type.IsNullType()) {
164 return true; 164 return true;
165 } 165 }
166 166
167 // The run time type of the value is guaranteed to be a subtype of the 167 // The run time type of the value is guaranteed to be a subtype of the
168 // compile time static type of the value. However, establishing here that 168 // compile time type of the value. However, establishing here that
169 // the static type is a subtype of the destination type does not guarantee 169 // the compile time type is a subtype of the destination type does not
170 // that the run time type will also be a subtype of the destination type, 170 // guarantee that the run time type will also be a subtype of the destination
171 // because the subtype relation is not transitive. 171 // type, because the subtype relation is not transitive.
172 // However, the 'more specific than' relation is transitive and is used 172 // However, the 'more specific than' relation is transitive and is used
173 // here. In other words, if the static type of the value is more specific 173 // here. In other words, if the compile type of the value is more specific
174 // than the destination type, the run time type of the value, which is 174 // than the destination type, the run time type of the value, which is
175 // guaranteed to be a subtype of the static type, is also guaranteed to be 175 // guaranteed to be a subtype of the compile type, is also guaranteed to be
176 // a subtype of the destination type and the type check can therefore be 176 // a subtype of the destination type and the type check can therefore be
177 // eliminated. 177 // eliminated.
178 return static_type.IsMoreSpecificThan(dst_type, NULL); 178 return compile_type.IsMoreSpecificThan(dst_type, NULL);
179 } 179 }
180 180
181 181
182 RawAbstractType* PhiInstr::StaticType() const { 182 RawAbstractType* PhiInstr::CompileType() const {
183 // TODO(regis): Return the least upper bound of the input static types. 183 if (HasPropagatedType()) {
184 // It is much simpler to compute the least specific of the input static types, 184 return PropagatedType();
185 // and it may be good enough in practice. 185 }
186 // Even better: we could keep the set of the input static types intact. 186 // If type propagation has not yet occured, we are reaching this phi via a
187 AbstractType& least_specific_type = 187 // back edge phi input. Return null as compile type so that this input is
188 AbstractType::Handle(InputAt(0)->StaticType()); 188 // ignored in the first iteration of type propagation.
189 return AbstractType::null();
190 }
191
192
193 RawAbstractType* PhiInstr::LeastSpecificInputType() const {
194 AbstractType& least_specific_type = AbstractType::Handle();
189 AbstractType& input_type = AbstractType::Handle(); 195 AbstractType& input_type = AbstractType::Handle();
190 for (intptr_t i = 1; i < InputCount(); i++) { 196 for (intptr_t i = 0; i < InputCount(); i++) {
191 input_type = InputAt(i)->StaticType(); 197 input_type = InputAt(i)->CompileType();
192 if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) { 198 if (input_type.IsNull()) {
193 // Type least_specific_type is less specific than input_type. No change. 199 // This input is on a back edge and we are in the first iteration of type
194 } else if (least_specific_type.IsMoreSpecificThan(input_type, NULL)) { 200 // propagation. Ignore it.
201 continue;
202 }
203 ASSERT(!input_type.IsNull());
204 if (least_specific_type.IsNull() ||
205 least_specific_type.IsMoreSpecificThan(input_type, NULL)) {
195 // Type input_type is less specific than the current least_specific_type. 206 // Type input_type is less specific than the current least_specific_type.
196 least_specific_type = input_type.raw(); 207 least_specific_type = input_type.raw();
208 } else if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) {
209 // Type least_specific_type is less specific than input_type. No change.
197 } else { 210 } else {
198 // The types are unrelated. No need to continue. 211 // The types are unrelated. No need to continue.
199 least_specific_type = Type::ObjectType(); 212 least_specific_type = Type::ObjectType();
200 break; 213 break;
201 } 214 }
202 } 215 }
203 return least_specific_type.raw(); 216 return least_specific_type.raw();
204 } 217 }
205 218
206 219
207 RawAbstractType* ParameterInstr::StaticType() const { 220 RawAbstractType* ParameterInstr::CompileType() const {
208 // TODO(regis): Can type feedback provide information about the static type 221 // TODO(regis): Can type feedback provide information about the compile type
209 // of a passed-in parameter? 222 // of a passed-in parameter? In that case, it would be stored in the
210 // Note that in checked mode, we could return the static type of the formal 223 // propagated_type_ field.
211 // parameter. However, this would be wrong if ParameterInstr is used to type 224 if (HasPropagatedType()) {
212 // check the passed-in parameter, since the type check would then always be 225 return PropagatedType();
213 // wrongly eliminated. 226 }
227 // Note that returning the declared type of the formal parameter would be
228 // incorrect, because ParameterInstr is used as input to the type check
229 // verifying the run time type of the passed-in parameter and this check would
230 // always be wrongly eliminated.
214 return Type::DynamicType(); 231 return Type::DynamicType();
215 } 232 }
216 233
217 234
218 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { 235 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const {
219 for (intptr_t i = 0; i < predecessors_.length(); ++i) { 236 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
220 if (predecessors_[i] == pred) return i; 237 if (predecessors_[i] == pred) return i;
221 } 238 }
222 return -1; 239 return -1;
223 } 240 }
(...skipping 13 matching lines...) Expand all
237 } 254 }
238 } 255 }
239 256
240 257
241 void Instruction::RecordAssignedVars(BitVector* assigned_vars, 258 void Instruction::RecordAssignedVars(BitVector* assigned_vars,
242 intptr_t fixed_parameter_count) { 259 intptr_t fixed_parameter_count) {
243 // Nothing to do for the base class. 260 // Nothing to do for the base class.
244 } 261 }
245 262
246 263
264 RawAbstractType* BindInstr::CompileType() const {
265 if (HasPropagatedType()) {
266 return PropagatedType();
267 }
268 // The compile type may be requested when building the flow graph, i.e. before
269 // type propagation has occurred.
270 return computation()->CompileType();
271 }
272
273
247 void BindInstr::RecordAssignedVars(BitVector* assigned_vars, 274 void BindInstr::RecordAssignedVars(BitVector* assigned_vars,
248 intptr_t fixed_parameter_count) { 275 intptr_t fixed_parameter_count) {
249 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count); 276 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count);
250 } 277 }
251 278
252 279
253 // ==== Postorder graph traversal. 280 // ==== Postorder graph traversal.
254 void GraphEntryInstr::DiscoverBlocks( 281 void GraphEntryInstr::DiscoverBlocks(
255 BlockEntryInstr* current_block, 282 BlockEntryInstr* current_block,
256 GrowableArray<BlockEntryInstr*>* preorder, 283 GrowableArray<BlockEntryInstr*>* preorder,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 ASSERT(index == 0); 490 ASSERT(index == 0);
464 return successor(); 491 return successor();
465 } 492 }
466 493
467 494
468 void Instruction::Goto(JoinEntryInstr* entry) { 495 void Instruction::Goto(JoinEntryInstr* entry) {
469 set_next(new GotoInstr(entry)); 496 set_next(new GotoInstr(entry));
470 } 497 }
471 498
472 499
473 // ==== Support for propagating static type. 500 RawAbstractType* ConstantVal::CompileType() const {
474 RawAbstractType* ConstantVal::StaticType() const { 501 if (value().IsNull()) {
502 return Type::NullType();
503 }
475 if (value().IsInstance()) { 504 if (value().IsInstance()) {
476 return Instance::Cast(value()).GetType(); 505 return Instance::Cast(value()).GetType();
477 } else { 506 } else {
478 UNREACHABLE(); 507 ASSERT(value().IsAbstractTypeArguments());
479 return AbstractType::null(); 508 return AbstractType::null();
480 } 509 }
481 } 510 }
482 511
483 512
484 RawAbstractType* UseVal::StaticType() const { 513 RawAbstractType* UseVal::CompileType() const {
485 return definition()->StaticType(); 514 return definition()->CompileType();
486 } 515 }
487 516
488 517
489 RawAbstractType* AssertAssignableComp::StaticType() const { 518 RawAbstractType* AssertAssignableComp::CompileType() const {
490 const AbstractType& value_static_type = 519 const AbstractType& value_compile_type =
491 AbstractType::Handle(value()->StaticType()); 520 AbstractType::Handle(value()->CompileType());
492 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) { 521 if (!value_compile_type.IsNull() &&
493 return value_static_type.raw(); 522 value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) {
523 return value_compile_type.raw();
494 } 524 }
495 return dst_type().raw(); 525 return dst_type().raw();
496 } 526 }
497 527
498 528
499 RawAbstractType* AssertBooleanComp::StaticType() const { 529 RawAbstractType* AssertBooleanComp::CompileType() const {
500 return Type::BoolInterface(); 530 return Type::BoolInterface();
501 } 531 }
502 532
503 533
504 RawAbstractType* CurrentContextComp::StaticType() const { 534 RawAbstractType* CurrentContextComp::CompileType() const {
505 UNREACHABLE();
506 return AbstractType::null(); 535 return AbstractType::null();
507 } 536 }
508 537
509 538
510 RawAbstractType* StoreContextComp::StaticType() const { 539 RawAbstractType* StoreContextComp::CompileType() const {
511 UNREACHABLE();
512 return AbstractType::null(); 540 return AbstractType::null();
513 } 541 }
514 542
515 543
516 RawAbstractType* ClosureCallComp::StaticType() const { 544 RawAbstractType* ClosureCallComp::CompileType() const {
517 // Because of function subtyping rules, the static return type of a closure 545 // Because of function subtyping rules, the declared return type of a closure
518 // call cannot be relied upon for static type analysis. For example, a 546 // call cannot be relied upon for compile type analysis. For example, a
519 // function returning Dynamic can be assigned to a closure variable declared 547 // function returning Dynamic can be assigned to a closure variable declared
520 // to return int and may actually return a double at run-time. 548 // to return int and may actually return a double at run-time.
521 return Type::DynamicType(); 549 return Type::DynamicType();
522 } 550 }
523 551
524 552
525 RawAbstractType* InstanceCallComp::StaticType() const { 553 RawAbstractType* InstanceCallComp::CompileType() const {
526 // TODO(regis): Return a more specific type than Dynamic for recognized 554 // TODO(regis): Return a more specific type than Dynamic for recognized
527 // combinations of receiver static type and method name. 555 // combinations of receiver type and method name.
528 return Type::DynamicType(); 556 return Type::DynamicType();
529 } 557 }
530 558
531 559
532 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { 560 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
533 return Type::DynamicType(); 561 return Type::DynamicType();
534 } 562 }
535 563
536 564
537 RawAbstractType* StaticCallComp::StaticType() const { 565 RawAbstractType* StaticCallComp::CompileType() const {
538 return function().result_type(); 566 return function().result_type();
539 } 567 }
540 568
541 569
542 RawAbstractType* LoadLocalComp::StaticType() const { 570 RawAbstractType* LoadLocalComp::CompileType() const {
543 // TODO(regis): Verify that the type of the receiver is properly set.
544 if (FLAG_enable_type_checks) { 571 if (FLAG_enable_type_checks) {
545 return local().type().raw(); 572 return local().type().raw();
546 } 573 }
547 return Type::DynamicType(); 574 return Type::DynamicType();
548 } 575 }
549 576
550 577
551 RawAbstractType* StoreLocalComp::StaticType() const { 578 RawAbstractType* StoreLocalComp::CompileType() const {
552 return value()->StaticType(); 579 return value()->CompileType();
553 } 580 }
554 581
555 582
556 RawAbstractType* StrictCompareComp::StaticType() const { 583 RawAbstractType* StrictCompareComp::CompileType() const {
557 return Type::BoolInterface(); 584 return Type::BoolInterface();
558 } 585 }
559 586
560 587
561 RawAbstractType* EqualityCompareComp::StaticType() const { 588 RawAbstractType* EqualityCompareComp::CompileType() const {
562 return Type::BoolInterface(); 589 return Type::BoolInterface();
563 } 590 }
564 591
565 592
566 RawAbstractType* RelationalOpComp::StaticType() const { 593 RawAbstractType* RelationalOpComp::CompileType() const {
567 return Type::BoolInterface(); 594 return Type::BoolInterface();
568 } 595 }
569 596
570 597
571 RawAbstractType* NativeCallComp::StaticType() const { 598 RawAbstractType* NativeCallComp::CompileType() const {
572 // The result type of the native function is identical to the result type of 599 // The result type of the native function is identical to the result type of
573 // the enclosing native Dart function. However, we prefer to check the type 600 // the enclosing native Dart function. However, we prefer to check the type
574 // of the value returned from the native call. 601 // of the value returned from the native call.
575 return Type::DynamicType(); 602 return Type::DynamicType();
576 } 603 }
577 604
578 605
579 RawAbstractType* LoadIndexedComp::StaticType() const { 606 RawAbstractType* LoadIndexedComp::CompileType() const {
580 return Type::DynamicType(); 607 return Type::DynamicType();
581 } 608 }
582 609
583 610
584 RawAbstractType* StoreIndexedComp::StaticType() const { 611 RawAbstractType* StoreIndexedComp::CompileType() const {
585 UNREACHABLE();
586 return AbstractType::null(); 612 return AbstractType::null();
587 } 613 }
588 614
589 615
590 RawAbstractType* LoadInstanceFieldComp::StaticType() const { 616 RawAbstractType* LoadInstanceFieldComp::CompileType() const {
591 if (FLAG_enable_type_checks) { 617 if (FLAG_enable_type_checks) {
592 return field().type(); 618 return field().type();
593 } 619 }
594 return Type::DynamicType(); 620 return Type::DynamicType();
595 } 621 }
596 622
597 623
598 RawAbstractType* StoreInstanceFieldComp::StaticType() const { 624 RawAbstractType* StoreInstanceFieldComp::CompileType() const {
599 return value()->StaticType(); 625 return value()->CompileType();
600 } 626 }
601 627
602 628
603 RawAbstractType* LoadStaticFieldComp::StaticType() const { 629 RawAbstractType* LoadStaticFieldComp::CompileType() const {
604 if (FLAG_enable_type_checks) { 630 if (FLAG_enable_type_checks) {
605 return field().type(); 631 return field().type();
606 } 632 }
607 return Type::DynamicType(); 633 return Type::DynamicType();
608 } 634 }
609 635
610 636
611 RawAbstractType* StoreStaticFieldComp::StaticType() const { 637 RawAbstractType* StoreStaticFieldComp::CompileType() const {
612 return value()->StaticType(); 638 return value()->CompileType();
613 } 639 }
614 640
615 641
616 RawAbstractType* BooleanNegateComp::StaticType() const { 642 RawAbstractType* BooleanNegateComp::CompileType() const {
617 return Type::BoolInterface(); 643 return Type::BoolInterface();
618 } 644 }
619 645
620 646
621 RawAbstractType* InstanceOfComp::StaticType() const { 647 RawAbstractType* InstanceOfComp::CompileType() const {
622 return Type::BoolInterface(); 648 return Type::BoolInterface();
623 } 649 }
624 650
625 651
626 RawAbstractType* CreateArrayComp::StaticType() const { 652 RawAbstractType* CreateArrayComp::CompileType() const {
627 UNREACHABLE(); 653 // TODO(regis): Be more specific.
628 return AbstractType::null(); 654 return Type::DynamicType();
629 } 655 }
630 656
631 657
632 RawAbstractType* CreateClosureComp::StaticType() const { 658 RawAbstractType* CreateClosureComp::CompileType() const {
633 const Function& fun = function(); 659 const Function& fun = function();
634 const Class& signature_class = Class::Handle(fun.signature_class()); 660 const Class& signature_class = Class::Handle(fun.signature_class());
635 return signature_class.SignatureType(); 661 return signature_class.SignatureType();
636 } 662 }
637 663
638 664
639 RawAbstractType* AllocateObjectComp::StaticType() const { 665 RawAbstractType* AllocateObjectComp::CompileType() const {
640 // TODO(regis): Be more specific. 666 // TODO(regis): Be more specific.
641 return Type::DynamicType(); 667 return Type::DynamicType();
642 } 668 }
643 669
644 670
645 RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const { 671 RawAbstractType* AllocateObjectWithBoundsCheckComp::CompileType() const {
646 UNREACHABLE(); 672 // TODO(regis): Be more specific.
673 return Type::DynamicType();
674 }
675
676
677 RawAbstractType* LoadVMFieldComp::CompileType() const {
678 // Type may be null if the field is a VM field, e.g. context parent.
679 return type().raw();
680 }
681
682
683 RawAbstractType* StoreVMFieldComp::CompileType() const {
684 return value()->CompileType();
685 }
686
687
688 RawAbstractType* InstantiateTypeArgumentsComp::CompileType() const {
647 return AbstractType::null(); 689 return AbstractType::null();
648 } 690 }
649 691
650 692
651 RawAbstractType* LoadVMFieldComp::StaticType() const { 693 RawAbstractType* ExtractConstructorTypeArgumentsComp::CompileType() const {
652 ASSERT(!type().IsNull());
653 return type().raw();
654 }
655
656
657 RawAbstractType* StoreVMFieldComp::StaticType() const {
658 return value()->StaticType();
659 }
660
661
662 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const {
663 UNREACHABLE();
664 return AbstractType::null(); 694 return AbstractType::null();
665 } 695 }
666 696
667 697
668 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { 698 RawAbstractType* ExtractConstructorInstantiatorComp::CompileType() const {
669 UNREACHABLE();
670 return AbstractType::null(); 699 return AbstractType::null();
671 } 700 }
672 701
673 702
674 RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const { 703 RawAbstractType* AllocateContextComp::CompileType() const {
675 UNREACHABLE();
676 return AbstractType::null(); 704 return AbstractType::null();
677 } 705 }
678 706
679 707
680 RawAbstractType* AllocateContextComp::StaticType() const { 708 RawAbstractType* ChainContextComp::CompileType() const {
681 UNREACHABLE();
682 return AbstractType::null(); 709 return AbstractType::null();
683 } 710 }
684 711
685 712
686 RawAbstractType* ChainContextComp::StaticType() const { 713 RawAbstractType* CloneContextComp::CompileType() const {
687 UNREACHABLE();
688 return AbstractType::null(); 714 return AbstractType::null();
689 } 715 }
690 716
691 717
692 RawAbstractType* CloneContextComp::StaticType() const { 718 RawAbstractType* CatchEntryComp::CompileType() const {
693 UNREACHABLE();
694 return AbstractType::null(); 719 return AbstractType::null();
695 } 720 }
696 721
697 722
698 RawAbstractType* CatchEntryComp::StaticType() const { 723 RawAbstractType* CheckStackOverflowComp::CompileType() const {
699 UNREACHABLE(); 724 return Type::VoidType();
700 return AbstractType::null();
701 } 725 }
702 726
703 727
704 RawAbstractType* CheckStackOverflowComp::StaticType() const { 728 RawAbstractType* BinaryOpComp::CompileType() const {
705 UNREACHABLE();
706 return AbstractType::null();
707 }
708
709
710 RawAbstractType* BinaryOpComp::StaticType() const {
711 // TODO(srdjan): Compute based on input types (ICData). 729 // TODO(srdjan): Compute based on input types (ICData).
712 return Type::DynamicType(); 730 return Type::DynamicType();
713 } 731 }
714 732
715 733
716 RawAbstractType* DoubleBinaryOpComp::StaticType() const { 734 RawAbstractType* DoubleBinaryOpComp::CompileType() const {
717 return Type::DoubleInterface(); 735 return Type::DoubleInterface();
718 } 736 }
719 737
720 738
721 RawAbstractType* UnarySmiOpComp::StaticType() const { 739 RawAbstractType* UnarySmiOpComp::CompileType() const {
722 return Type::IntInterface(); 740 return Type::IntInterface();
723 } 741 }
724 742
725 743
726 RawAbstractType* NumberNegateComp::StaticType() const { 744 RawAbstractType* NumberNegateComp::CompileType() const {
727 return Type::NumberInterface(); 745 return Type::NumberInterface();
728 } 746 }
729 747
730 748
731 RawAbstractType* ToDoubleComp::StaticType() const { 749 RawAbstractType* ToDoubleComp::CompileType() const {
732 return Type::DoubleInterface(); 750 return Type::DoubleInterface();
733 } 751 }
734 752
735 753
736 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 754 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
737 // PrepareEntry). Only assembly code that can be shared across all architectures 755 // PrepareEntry). Only assembly code that can be shared across all architectures
738 // can be used. Machine specific register allocation and code generation 756 // can be used. Machine specific register allocation and code generation
739 // is located in intermediate_language_<arch>.cc 757 // is located in intermediate_language_<arch>.cc
740 758
741 759
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return NULL; 1042 return NULL;
1025 } 1043 }
1026 1044
1027 1045
1028 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { 1046 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) {
1029 UNIMPLEMENTED(); 1047 UNIMPLEMENTED();
1030 } 1048 }
1031 1049
1032 1050
1033 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1051 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1034 compiler->GenerateAssertAssignable(deopt_id(), 1052 if (!IsEliminated()) {
1035 token_pos(), 1053 compiler->GenerateAssertAssignable(deopt_id(),
1036 try_index(), 1054 token_pos(),
1037 dst_type(), 1055 try_index(),
1038 dst_name()); 1056 dst_type(),
1057 dst_name());
1058 }
1039 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 1059 ASSERT(locs()->in(0).reg() == locs()->out().reg());
1040 } 1060 }
1041 1061
1042 1062
1043 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { 1063 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
1044 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1064 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1045 locs->set_in(0, Location::RequiresRegister()); 1065 locs->set_in(0, Location::RequiresRegister());
1046 locs->set_temp(0, Location::RequiresRegister()); 1066 locs->set_temp(0, Location::RequiresRegister());
1047 locs->set_out(Location::SameAsFirstInput()); 1067 locs->set_out(Location::SameAsFirstInput());
1048 return locs; 1068 return locs;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 locations_[i] = Location::NoLocation(); 1220 locations_[i] = Location::NoLocation();
1201 } 1221 }
1202 } 1222 }
1203 } 1223 }
1204 } 1224 }
1205 1225
1206 1226
1207 #undef __ 1227 #undef __
1208 1228
1209 } // namespace dart 1229 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698