OLD | NEW |
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
11 #include "vm/handles_impl.h" | 11 #include "vm/handles_impl.h" |
12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
13 #include "vm/object.h" | 13 #include "vm/object.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 class BindInstr; | |
18 class BitVector; | 17 class BitVector; |
19 class BlockEntryInstr; | 18 class BlockEntryInstr; |
20 class BufferFormatter; | 19 class BufferFormatter; |
21 class ComparisonComp; | 20 class ComparisonInstr; |
22 class ConstantComp; | |
23 class Computation; | |
24 class ControlInstruction; | 21 class ControlInstruction; |
25 class Definition; | 22 class Definition; |
26 class Environment; | 23 class Environment; |
27 class FlowGraphCompiler; | 24 class FlowGraphCompiler; |
28 class FlowGraphVisitor; | 25 class FlowGraphVisitor; |
29 class Instruction; | 26 class Instruction; |
30 class LocalVariable; | 27 class LocalVariable; |
31 | 28 |
32 | 29 |
33 // TODO(srdjan): Add _ByteArrayBase, get:length. | 30 // TODO(srdjan): Add _ByteArrayBase, get:length. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 // Instructions. | 175 // Instructions. |
179 | 176 |
180 // M is a single argument macro. It is applied to each concrete instruction | 177 // M is a single argument macro. It is applied to each concrete instruction |
181 // type name. The concrete instruction classes are the name with Instr | 178 // type name. The concrete instruction classes are the name with Instr |
182 // concatenated. | 179 // concatenated. |
183 #define FOR_EACH_INSTRUCTION(M) \ | 180 #define FOR_EACH_INSTRUCTION(M) \ |
184 M(GraphEntry) \ | 181 M(GraphEntry) \ |
185 M(JoinEntry) \ | 182 M(JoinEntry) \ |
186 M(TargetEntry) \ | 183 M(TargetEntry) \ |
187 M(Phi) \ | 184 M(Phi) \ |
188 M(Bind) \ | |
189 M(Parameter) \ | 185 M(Parameter) \ |
190 M(ParallelMove) \ | 186 M(ParallelMove) \ |
191 M(PushArgument) \ | 187 M(PushArgument) \ |
192 M(Return) \ | 188 M(Return) \ |
193 M(Throw) \ | 189 M(Throw) \ |
194 M(ReThrow) \ | 190 M(ReThrow) \ |
195 M(Goto) \ | 191 M(Goto) \ |
196 M(Branch) \ | 192 M(Branch) \ |
| 193 M(AssertAssignable) \ |
| 194 M(AssertBoolean) \ |
| 195 M(ArgumentDefinitionTest) \ |
| 196 M(CurrentContext) \ |
| 197 M(StoreContext) \ |
| 198 M(ClosureCall) \ |
| 199 M(InstanceCall) \ |
| 200 M(PolymorphicInstanceCall) \ |
| 201 M(StaticCall) \ |
| 202 M(LoadLocal) \ |
| 203 M(StoreLocal) \ |
| 204 M(StrictCompare) \ |
| 205 M(EqualityCompare) \ |
| 206 M(RelationalOp) \ |
| 207 M(NativeCall) \ |
| 208 M(LoadIndexed) \ |
| 209 M(StoreIndexed) \ |
| 210 M(LoadInstanceField) \ |
| 211 M(StoreInstanceField) \ |
| 212 M(LoadStaticField) \ |
| 213 M(StoreStaticField) \ |
| 214 M(BooleanNegate) \ |
| 215 M(InstanceOf) \ |
| 216 M(CreateArray) \ |
| 217 M(CreateClosure) \ |
| 218 M(AllocateObject) \ |
| 219 M(AllocateObjectWithBoundsCheck) \ |
| 220 M(LoadVMField) \ |
| 221 M(StoreVMField) \ |
| 222 M(InstantiateTypeArguments) \ |
| 223 M(ExtractConstructorTypeArguments) \ |
| 224 M(ExtractConstructorInstantiator) \ |
| 225 M(AllocateContext) \ |
| 226 M(ChainContext) \ |
| 227 M(CloneContext) \ |
| 228 M(CatchEntry) \ |
| 229 M(BinarySmiOp) \ |
| 230 M(BinaryMintOp) \ |
| 231 M(UnarySmiOp) \ |
| 232 M(NumberNegate) \ |
| 233 M(CheckStackOverflow) \ |
| 234 M(DoubleToDouble) \ |
| 235 M(SmiToDouble) \ |
| 236 M(CheckClass) \ |
| 237 M(CheckSmi) \ |
| 238 M(Constant) \ |
| 239 M(CheckEitherNonSmi) \ |
| 240 M(UnboxedDoubleBinaryOp) \ |
| 241 M(UnboxDouble) \ |
| 242 M(BoxDouble) \ |
| 243 M(CheckArrayBound) \ |
197 | 244 |
198 | 245 |
199 #define FORWARD_DECLARATION(type) class type##Instr; | 246 #define FORWARD_DECLARATION(type) class type##Instr; |
200 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 247 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
201 #undef FORWARD_DECLARATION | 248 #undef FORWARD_DECLARATION |
202 | 249 |
203 | 250 |
204 // Functions required in all concrete instruction classes. | 251 // Functions required in all concrete instruction classes. |
205 #define DECLARE_INSTRUCTION(type) \ | 252 #define DECLARE_INSTRUCTION(type) \ |
| 253 virtual Tag tag() const { return k##type; } \ |
206 virtual void Accept(FlowGraphVisitor* visitor); \ | 254 virtual void Accept(FlowGraphVisitor* visitor); \ |
207 virtual type##Instr* As##type() { return this; } \ | 255 virtual type##Instr* As##type() { return this; } \ |
208 virtual const char* DebugName() const { return #type; } \ | 256 virtual const char* DebugName() const { return #type; } \ |
209 virtual void PrintTo(BufferFormatter* f) const; \ | 257 virtual LocationSummary* MakeLocationSummary() const; \ |
210 virtual void PrintToVisualizer(BufferFormatter* f) const; | 258 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ |
211 | 259 |
212 | 260 |
213 class Instruction : public ZoneAllocated { | 261 class Instruction : public ZoneAllocated { |
214 public: | 262 public: |
| 263 #define DECLARE_TAG(type) k##type, |
| 264 enum Tag { |
| 265 FOR_EACH_INSTRUCTION(DECLARE_TAG) |
| 266 }; |
| 267 #undef DECLARE_TAG |
| 268 |
215 Instruction() | 269 Instruction() |
216 : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { } | 270 : deopt_id_(Isolate::Current()->GetNextDeoptId()), |
| 271 lifetime_position_(-1), |
| 272 previous_(NULL), |
| 273 next_(NULL), |
| 274 env_(NULL) { } |
| 275 |
| 276 virtual Tag tag() const = 0; |
| 277 |
| 278 intptr_t deopt_id() const { return deopt_id_; } |
217 | 279 |
218 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } | 280 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } |
219 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } | 281 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } |
220 | 282 |
221 bool IsDefinition() { return (AsDefinition() != NULL); } | 283 bool IsDefinition() { return (AsDefinition() != NULL); } |
222 virtual Definition* AsDefinition() { return NULL; } | 284 virtual Definition* AsDefinition() { return NULL; } |
223 | 285 |
224 bool IsControl() { return (AsControl() != NULL); } | 286 bool IsControl() { return (AsControl() != NULL); } |
225 virtual ControlInstruction* AsControl() { return NULL; } | 287 virtual ControlInstruction* AsControl() { return NULL; } |
226 | 288 |
227 virtual intptr_t InputCount() const = 0; | 289 virtual intptr_t InputCount() const = 0; |
228 virtual Value* InputAt(intptr_t i) const = 0; | 290 virtual Value* InputAt(intptr_t i) const = 0; |
229 virtual void SetInputAt(intptr_t i, Value* value) = 0; | 291 virtual void SetInputAt(intptr_t i, Value* value) = 0; |
230 | 292 |
231 // Call instructions override this function and return the | 293 // Call instructions override this function and return the number of |
232 // number of pushed arguments. | 294 // pushed arguments. |
233 virtual intptr_t ArgumentCount() const = 0; | 295 virtual intptr_t ArgumentCount() const = 0; |
234 | 296 |
235 // Returns true, if this instruction can deoptimize. | 297 // Returns true, if this instruction can deoptimize. |
236 virtual bool CanDeoptimize() const = 0; | 298 virtual bool CanDeoptimize() const = 0; |
237 | 299 |
238 // Visiting support. | 300 // Visiting support. |
239 virtual void Accept(FlowGraphVisitor* visitor) = 0; | 301 virtual void Accept(FlowGraphVisitor* visitor) = 0; |
240 | 302 |
241 Instruction* previous() const { return previous_; } | 303 Instruction* previous() const { return previous_; } |
242 void set_previous(Instruction* instr) { | 304 void set_previous(Instruction* instr) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 intptr_t fixed_parameter_count) { | 354 intptr_t fixed_parameter_count) { |
293 // Never called for instructions except block entries and branches. | 355 // Never called for instructions except block entries and branches. |
294 UNREACHABLE(); | 356 UNREACHABLE(); |
295 } | 357 } |
296 | 358 |
297 // Mutate assigned_vars to add the local variable index for all | 359 // Mutate assigned_vars to add the local variable index for all |
298 // frame-allocated locals assigned to by the instruction. | 360 // frame-allocated locals assigned to by the instruction. |
299 virtual void RecordAssignedVars(BitVector* assigned_vars, | 361 virtual void RecordAssignedVars(BitVector* assigned_vars, |
300 intptr_t fixed_parameter_count); | 362 intptr_t fixed_parameter_count); |
301 | 363 |
| 364 virtual const char* DebugName() const = 0; |
| 365 |
302 // Printing support. | 366 // Printing support. |
303 virtual void PrintTo(BufferFormatter* f) const = 0; | 367 virtual void PrintTo(BufferFormatter* f) const = 0; |
304 virtual void PrintToVisualizer(BufferFormatter* f) const = 0; | 368 virtual void PrintToVisualizer(BufferFormatter* f) const = 0; |
305 | 369 |
306 #define INSTRUCTION_TYPE_CHECK(type) \ | 370 #define INSTRUCTION_TYPE_CHECK(type) \ |
307 bool Is##type() { return (As##type() != NULL); } \ | 371 bool Is##type() { return (As##type() != NULL); } \ |
308 virtual type##Instr* As##type() { return NULL; } | 372 virtual type##Instr* As##type() { return NULL; } |
309 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 373 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
310 #undef INSTRUCTION_TYPE_CHECK | 374 #undef INSTRUCTION_TYPE_CHECK |
311 | 375 |
312 // Returns structure describing location constraints required | 376 // Returns structure describing location constraints required |
313 // to emit native code for this instruction. | 377 // to emit native code for this instruction. |
314 virtual LocationSummary* locs() { | 378 virtual LocationSummary* locs() { |
315 // TODO(vegorov): This should be pure virtual method. | 379 // TODO(vegorov): This should be pure virtual method. |
316 // However we are temporary using NULL for instructions that | 380 // However we are temporary using NULL for instructions that |
317 // were not converted to the location based code generation yet. | 381 // were not converted to the location based code generation yet. |
318 return NULL; | 382 return NULL; |
319 } | 383 } |
320 | 384 |
| 385 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 386 |
| 387 static LocationSummary* MakeCallSummary(); |
| 388 |
321 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 389 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
322 UNIMPLEMENTED(); | 390 UNIMPLEMENTED(); |
323 } | 391 } |
324 | 392 |
325 Environment* env() const { return env_; } | 393 Environment* env() const { return env_; } |
326 void set_env(Environment* env) { env_ = env; } | 394 void set_env(Environment* env) { env_ = env; } |
327 | 395 |
328 intptr_t lifetime_position() const { return lifetime_position_; } | 396 intptr_t lifetime_position() const { return lifetime_position_; } |
329 void set_lifetime_position(intptr_t pos) { | 397 void set_lifetime_position(intptr_t pos) { |
330 lifetime_position_ = pos; | 398 lifetime_position_ = pos; |
(...skipping 14 matching lines...) Expand all Loading... |
345 } | 413 } |
346 | 414 |
347 // Returns deoptimization id that corresponds to the deoptimization target | 415 // Returns deoptimization id that corresponds to the deoptimization target |
348 // that input operands conversions inserted for this instruction can jump | 416 // that input operands conversions inserted for this instruction can jump |
349 // to. | 417 // to. |
350 virtual intptr_t DeoptimizationTarget() const { | 418 virtual intptr_t DeoptimizationTarget() const { |
351 UNREACHABLE(); | 419 UNREACHABLE(); |
352 return Isolate::kNoDeoptId; | 420 return Isolate::kNoDeoptId; |
353 } | 421 } |
354 | 422 |
| 423 protected: |
| 424 // Fetch deopt id without checking if this computation can deoptimize. |
| 425 intptr_t GetDeoptId() const { |
| 426 return deopt_id_; |
| 427 } |
| 428 |
355 private: | 429 private: |
356 friend class Definition; // Needed for InsertBefore, InsertAfter. | 430 friend class Definition; // Needed for InsertBefore, InsertAfter. |
357 | 431 |
| 432 // Classes that set deopt_id_. |
| 433 friend class UnboxDoubleInstr; |
| 434 friend class UnboxedDoubleBinaryOpInstr; |
| 435 friend class CheckClassInstr; |
| 436 friend class CheckSmiInstr; |
| 437 friend class CheckNonSmiInstr; |
| 438 friend class CheckArrayBoundInstr; |
| 439 friend class CheckEitherNonSmiInstr; |
| 440 |
| 441 intptr_t deopt_id_; |
358 intptr_t lifetime_position_; // Position used by register allocator. | 442 intptr_t lifetime_position_; // Position used by register allocator. |
359 Instruction* previous_; | 443 Instruction* previous_; |
360 Instruction* next_; | 444 Instruction* next_; |
361 Environment* env_; | 445 Environment* env_; |
362 DISALLOW_COPY_AND_ASSIGN(Instruction); | 446 DISALLOW_COPY_AND_ASSIGN(Instruction); |
363 }; | 447 }; |
364 | 448 |
365 | 449 |
366 template<intptr_t N> | 450 template<intptr_t N> |
367 class TemplateInstruction: public Instruction { | 451 class TemplateInstruction: public Instruction { |
368 public: | 452 public: |
369 TemplateInstruction<N>() : locs_(NULL) { } | 453 TemplateInstruction<N>() : locs_(NULL) { } |
370 | 454 |
371 virtual intptr_t InputCount() const { return N; } | 455 virtual intptr_t InputCount() const { return N; } |
372 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 456 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
373 virtual void SetInputAt(intptr_t i, Value* value) { | 457 virtual void SetInputAt(intptr_t i, Value* value) { |
374 ASSERT(value != NULL); | 458 ASSERT(value != NULL); |
375 inputs_[i] = value; | 459 inputs_[i] = value; |
376 } | 460 } |
377 | 461 |
378 virtual LocationSummary* locs() { | 462 virtual LocationSummary* locs() { |
379 if (locs_ == NULL) { | 463 if (locs_ == NULL) { |
380 locs_ = MakeLocationSummary(); | 464 locs_ = MakeLocationSummary(); |
381 } | 465 } |
382 return locs_; | 466 return locs_; |
383 } | 467 } |
384 | 468 |
385 virtual LocationSummary* MakeLocationSummary() const = 0; | |
386 | |
387 protected: | 469 protected: |
388 EmbeddedArray<Value*, N> inputs_; | 470 EmbeddedArray<Value*, N> inputs_; |
389 | 471 |
390 private: | 472 private: |
391 LocationSummary* locs_; | 473 LocationSummary* locs_; |
392 }; | 474 }; |
393 | 475 |
394 | 476 |
395 class MoveOperands : public ZoneAllocated { | 477 class MoveOperands : public ZoneAllocated { |
396 public: | 478 public: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 return move; | 548 return move; |
467 } | 549 } |
468 | 550 |
469 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; } | 551 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; } |
470 | 552 |
471 void SetSrcSlotAt(intptr_t index, const Location& loc); | 553 void SetSrcSlotAt(intptr_t index, const Location& loc); |
472 void SetDestSlotAt(intptr_t index, const Location& loc); | 554 void SetDestSlotAt(intptr_t index, const Location& loc); |
473 | 555 |
474 intptr_t NumMoves() const { return moves_.length(); } | 556 intptr_t NumMoves() const { return moves_.length(); } |
475 | 557 |
476 LocationSummary* MakeLocationSummary() const { return NULL; } | 558 virtual void PrintTo(BufferFormatter* f) const; |
477 | 559 virtual void PrintToVisualizer(BufferFormatter* f) const; |
478 void EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } | |
479 | 560 |
480 private: | 561 private: |
481 GrowableArray<MoveOperands*> moves_; // Elements cannot be null. | 562 GrowableArray<MoveOperands*> moves_; // Elements cannot be null. |
482 | 563 |
483 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); | 564 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); |
484 }; | 565 }; |
485 | 566 |
486 | 567 |
487 // Basic block entries are administrative nodes. There is a distinguished | 568 // Basic block entries are administrative nodes. There is a distinguished |
488 // graph entry with no predecessor. Joins are the only nodes with multiple | 569 // graph entry with no predecessor. Joins are the only nodes with multiple |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 void Advance() { | 688 void Advance() { |
608 ASSERT(!Done()); | 689 ASSERT(!Done()); |
609 current_ = current_->next(); | 690 current_ = current_->next(); |
610 } | 691 } |
611 | 692 |
612 bool Done() const { return current_ == NULL; } | 693 bool Done() const { return current_ == NULL; } |
613 | 694 |
614 // Removes 'current_' from graph and sets 'current_' to previous instruction. | 695 // Removes 'current_' from graph and sets 'current_' to previous instruction. |
615 void RemoveCurrentFromGraph(); | 696 void RemoveCurrentFromGraph(); |
616 | 697 |
| 698 // Inserts replaces 'current_', which must be a definition, with another |
| 699 // definition. The new definition becomes 'current_'. |
| 700 void ReplaceCurrentWith(Definition* other); |
| 701 |
617 Instruction* Current() const { return current_; } | 702 Instruction* Current() const { return current_; } |
618 | 703 |
619 private: | 704 private: |
620 BlockEntryInstr* block_entry_; | 705 BlockEntryInstr* block_entry_; |
621 Instruction* current_; | 706 Instruction* current_; |
622 }; | 707 }; |
623 | 708 |
624 | 709 |
625 class BackwardInstructionIterator : public ValueObject { | 710 class BackwardInstructionIterator : public ValueObject { |
626 public: | 711 public: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 intptr_t variable_count, | 754 intptr_t variable_count, |
670 intptr_t fixed_parameter_count); | 755 intptr_t fixed_parameter_count); |
671 | 756 |
672 void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); } | 757 void AddCatchEntry(TargetEntryInstr* entry) { catch_entries_.Add(entry); } |
673 | 758 |
674 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 759 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
675 | 760 |
676 Environment* start_env() const { return start_env_; } | 761 Environment* start_env() const { return start_env_; } |
677 void set_start_env(Environment* env) { start_env_ = env; } | 762 void set_start_env(Environment* env) { start_env_ = env; } |
678 | 763 |
679 Definition* constant_null() const { return constant_null_; } | 764 ConstantInstr* constant_null() const { return constant_null_; } |
680 | 765 |
681 intptr_t spill_slot_count() const { return spill_slot_count_; } | 766 intptr_t spill_slot_count() const { return spill_slot_count_; } |
682 void set_spill_slot_count(intptr_t count) { | 767 void set_spill_slot_count(intptr_t count) { |
683 ASSERT(count >= 0); | 768 ASSERT(count >= 0); |
684 spill_slot_count_ = count; | 769 spill_slot_count_ = count; |
685 } | 770 } |
686 | 771 |
687 TargetEntryInstr* normal_entry() const { return normal_entry_; } | 772 TargetEntryInstr* normal_entry() const { return normal_entry_; } |
688 | 773 |
| 774 virtual void PrintTo(BufferFormatter* f) const; |
| 775 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 776 |
689 private: | 777 private: |
690 TargetEntryInstr* normal_entry_; | 778 TargetEntryInstr* normal_entry_; |
691 GrowableArray<TargetEntryInstr*> catch_entries_; | 779 GrowableArray<TargetEntryInstr*> catch_entries_; |
692 Environment* start_env_; | 780 Environment* start_env_; |
693 Definition* constant_null_; | 781 ConstantInstr* constant_null_; |
694 intptr_t spill_slot_count_; | 782 intptr_t spill_slot_count_; |
695 | 783 |
696 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 784 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
697 }; | 785 }; |
698 | 786 |
699 | 787 |
700 class JoinEntryInstr : public BlockEntryInstr { | 788 class JoinEntryInstr : public BlockEntryInstr { |
701 public: | 789 public: |
702 explicit JoinEntryInstr(intptr_t try_index) | 790 explicit JoinEntryInstr(intptr_t try_index) |
703 : BlockEntryInstr(try_index), | 791 : BlockEntryInstr(try_index), |
(...skipping 16 matching lines...) Expand all Loading... |
720 | 808 |
721 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } | 809 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } |
722 | 810 |
723 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 811 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
724 | 812 |
725 void InsertPhi(intptr_t var_index, intptr_t var_count); | 813 void InsertPhi(intptr_t var_index, intptr_t var_count); |
726 void RemoveDeadPhis(); | 814 void RemoveDeadPhis(); |
727 | 815 |
728 intptr_t phi_count() const { return phi_count_; } | 816 intptr_t phi_count() const { return phi_count_; } |
729 | 817 |
| 818 virtual void PrintTo(BufferFormatter* f) const; |
| 819 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 820 |
730 private: | 821 private: |
731 GrowableArray<BlockEntryInstr*> predecessors_; | 822 GrowableArray<BlockEntryInstr*> predecessors_; |
732 ZoneGrowableArray<PhiInstr*>* phis_; | 823 ZoneGrowableArray<PhiInstr*>* phis_; |
733 intptr_t phi_count_; | 824 intptr_t phi_count_; |
734 | 825 |
735 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); | 826 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); |
736 }; | 827 }; |
737 | 828 |
738 | 829 |
739 class TargetEntryInstr : public BlockEntryInstr { | 830 class TargetEntryInstr : public BlockEntryInstr { |
(...skipping 30 matching lines...) Expand all Loading... |
770 | 861 |
771 // Returns try index for the try block to which this catch handler | 862 // Returns try index for the try block to which this catch handler |
772 // corresponds. | 863 // corresponds. |
773 intptr_t catch_try_index() const { | 864 intptr_t catch_try_index() const { |
774 ASSERT(IsCatchEntry()); | 865 ASSERT(IsCatchEntry()); |
775 return catch_try_index_; | 866 return catch_try_index_; |
776 } | 867 } |
777 | 868 |
778 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 869 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
779 | 870 |
| 871 virtual void PrintTo(BufferFormatter* f) const; |
| 872 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 873 |
780 private: | 874 private: |
781 BlockEntryInstr* predecessor_; | 875 BlockEntryInstr* predecessor_; |
782 const intptr_t catch_try_index_; | 876 const intptr_t catch_try_index_; |
783 | 877 |
784 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 878 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
785 }; | 879 }; |
786 | 880 |
787 | 881 |
788 // Abstract super-class of all instructions that define a value (Bind, Phi). | 882 // Abstract super-class of all instructions that define a value (Bind, Phi). |
789 class Definition : public Instruction { | 883 class Definition : public Instruction { |
790 public: | 884 public: |
791 enum UseKind { kEffect, kValue }; | 885 enum UseKind { kEffect, kValue }; |
792 | 886 |
793 Definition() | 887 Definition() |
794 : temp_index_(-1), | 888 : temp_index_(-1), |
795 ssa_temp_index_(-1), | 889 ssa_temp_index_(-1), |
796 propagated_type_(AbstractType::Handle()), | 890 propagated_type_(AbstractType::Handle()), |
797 propagated_cid_(kIllegalCid), | 891 propagated_cid_(kIllegalCid), |
798 input_use_list_(NULL), | 892 input_use_list_(NULL), |
799 env_use_list_(NULL), | 893 env_use_list_(NULL), |
800 use_kind_(kValue) { // Phis and parameters rely on this default. | 894 use_kind_(kValue) { // Phis and parameters rely on this default. |
801 } | 895 } |
802 | 896 |
803 virtual Definition* AsDefinition() { return this; } | 897 virtual Definition* AsDefinition() { return this; } |
804 | 898 |
| 899 bool IsComparison() { return (AsComparison() != NULL); } |
| 900 virtual ComparisonInstr* AsComparison() { return NULL; } |
| 901 |
| 902 // Overridden by definitions that push arguments. |
| 903 virtual intptr_t ArgumentCount() const { return 0; } |
| 904 |
805 intptr_t temp_index() const { return temp_index_; } | 905 intptr_t temp_index() const { return temp_index_; } |
806 void set_temp_index(intptr_t index) { temp_index_ = index; } | 906 void set_temp_index(intptr_t index) { temp_index_ = index; } |
807 | 907 |
808 intptr_t ssa_temp_index() const { return ssa_temp_index_; } | 908 intptr_t ssa_temp_index() const { return ssa_temp_index_; } |
809 void set_ssa_temp_index(intptr_t index) { | 909 void set_ssa_temp_index(intptr_t index) { |
810 ASSERT(index >= 0); | 910 ASSERT(index >= 0); |
811 ASSERT(is_used()); | 911 ASSERT(is_used()); |
812 ssa_temp_index_ = index; | 912 ssa_temp_index_ = index; |
813 } | 913 } |
814 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } | 914 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } |
815 | 915 |
816 bool is_used() const { return (use_kind_ != kEffect); } | 916 bool is_used() const { return (use_kind_ != kEffect); } |
817 void set_use_kind(UseKind kind) { use_kind_ = kind; } | 917 void set_use_kind(UseKind kind) { use_kind_ = kind; } |
818 | 918 |
819 // Compile time type of the definition, which may be requested before type | 919 // Compile time type of the definition, which may be requested before type |
820 // propagation during graph building. | 920 // propagation during graph building. |
821 virtual RawAbstractType* CompileType() const = 0; | 921 virtual RawAbstractType* CompileType() const = 0; |
822 | 922 |
| 923 virtual intptr_t ResultCid() const = 0; |
| 924 |
823 bool HasPropagatedType() const { | 925 bool HasPropagatedType() const { |
824 return !propagated_type_.IsNull(); | 926 return !propagated_type_.IsNull(); |
825 } | 927 } |
826 RawAbstractType* PropagatedType() const { | 928 RawAbstractType* PropagatedType() const { |
827 ASSERT(HasPropagatedType()); | 929 ASSERT(HasPropagatedType()); |
828 return propagated_type_.raw(); | 930 return propagated_type_.raw(); |
829 } | 931 } |
830 // Returns true if the propagated type has changed. | 932 // Returns true if the propagated type has changed. |
831 bool SetPropagatedType(const AbstractType& propagated_type) { | 933 bool SetPropagatedType(const AbstractType& propagated_type) { |
832 if (propagated_type.IsNull()) { | 934 if (propagated_type.IsNull()) { |
833 // Not a typed definition, e.g. access to a VM field. | 935 // Not a typed definition, e.g. access to a VM field. |
834 return false; | 936 return false; |
835 } | 937 } |
836 const bool changed = | 938 const bool changed = |
837 propagated_type_.IsNull() || !propagated_type.Equals(propagated_type_); | 939 propagated_type_.IsNull() || !propagated_type.Equals(propagated_type_); |
838 propagated_type_ = propagated_type.raw(); | 940 propagated_type_ = propagated_type.raw(); |
839 return changed; | 941 return changed; |
840 } | 942 } |
841 | 943 |
842 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } | 944 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } |
843 intptr_t propagated_cid() const { return propagated_cid_; } | 945 intptr_t propagated_cid() const { return propagated_cid_; } |
| 946 |
844 // May compute and set propagated cid. | 947 // May compute and set propagated cid. |
845 virtual intptr_t GetPropagatedCid() = 0; | 948 virtual intptr_t GetPropagatedCid(); |
846 | 949 |
847 // Returns true if the propagated cid has changed. | 950 // Returns true if the propagated cid has changed. |
848 bool SetPropagatedCid(intptr_t cid); | 951 bool SetPropagatedCid(intptr_t cid); |
849 | 952 |
| 953 // Returns true if the definition may have side effects. |
| 954 // TODO(fschneider): Make this abstract and implement for all definitions |
| 955 // instead of returning the safe default (true). |
| 956 virtual bool HasSideEffect() const { return true; } |
| 957 |
850 Value* input_use_list() { return input_use_list_; } | 958 Value* input_use_list() { return input_use_list_; } |
851 void set_input_use_list(Value* head) { input_use_list_ = head; } | 959 void set_input_use_list(Value* head) { input_use_list_ = head; } |
852 | 960 |
853 Value* env_use_list() { return env_use_list_; } | 961 Value* env_use_list() { return env_use_list_; } |
854 void set_env_use_list(Value* head) { env_use_list_ = head; } | 962 void set_env_use_list(Value* head) { env_use_list_ = head; } |
855 | 963 |
| 964 // Returns a replacement for the definition or NULL if the definition can |
| 965 // be eliminated. By default returns the definition (input parameter) |
| 966 // which means no change. |
| 967 virtual Definition* Canonicalize(); |
| 968 |
856 // Replace uses of this definition with uses of other definition or value. | 969 // Replace uses of this definition with uses of other definition or value. |
857 // Precondition: use lists must be properly calculated. | 970 // Precondition: use lists must be properly calculated. |
858 // Postcondition: use lists and use values are still valid. | 971 // Postcondition: use lists and use values are still valid. |
859 void ReplaceUsesWith(Definition* other); | 972 void ReplaceUsesWith(Definition* other); |
860 | 973 |
| 974 // Replace this definition and all uses with another definition. If |
| 975 // replacing during iteration, pass the iterator so that the instruction |
| 976 // can be replaced without affecting iteration order, otherwise pass a |
| 977 // NULL iterator. |
| 978 void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator); |
| 979 |
861 // Insert this definition before 'next'. | 980 // Insert this definition before 'next'. |
862 void InsertBefore(Instruction* next); | 981 void InsertBefore(Instruction* next); |
863 | 982 |
864 // Insert this definition after 'prev'. | 983 // Insert this definition after 'prev'. |
865 void InsertAfter(Instruction* prev); | 984 void InsertAfter(Instruction* prev); |
866 | 985 |
867 // If this definition is a bind of a constant return it. | 986 // Compares two definitions. Returns true, iff: |
868 // Otherwise return NULL. | 987 // 1. They have the same tag. |
869 ConstantComp* AsConstant(); | 988 // 2. All input operands are Equals. |
| 989 // 3. They satisfy AttributesEqual. |
| 990 bool Equals(Definition* other) const; |
| 991 |
| 992 // Compare attributes of a definition (except input operands and tag). |
| 993 // All definition that participate in CSE have to override this function. |
| 994 // This function can assume that the argument has the same type as this. |
| 995 virtual bool AttributesEqual(Definition* other) const { |
| 996 UNREACHABLE(); |
| 997 return false; |
| 998 } |
| 999 |
| 1000 // Returns a hash code for use with hash maps. |
| 1001 virtual intptr_t Hashcode() const; |
| 1002 |
| 1003 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 1004 intptr_t fixed_parameter_count); |
| 1005 |
| 1006 // Printing support. These functions are sometimes overridden for custom |
| 1007 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". |
| 1008 virtual void PrintTo(BufferFormatter* f) const; |
| 1009 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1010 virtual void PrintToVisualizer(BufferFormatter* f) const; |
870 | 1011 |
871 private: | 1012 private: |
872 intptr_t temp_index_; | 1013 intptr_t temp_index_; |
873 intptr_t ssa_temp_index_; | 1014 intptr_t ssa_temp_index_; |
874 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; | 1015 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; |
875 // For now: | 1016 // For now: |
876 AbstractType& propagated_type_; | 1017 AbstractType& propagated_type_; |
877 intptr_t propagated_cid_; | 1018 intptr_t propagated_cid_; |
878 Value* input_use_list_; | 1019 Value* input_use_list_; |
879 Value* env_use_list_; | 1020 Value* env_use_list_; |
880 UseKind use_kind_; | 1021 UseKind use_kind_; |
881 | 1022 |
882 DISALLOW_COPY_AND_ASSIGN(Definition); | 1023 DISALLOW_COPY_AND_ASSIGN(Definition); |
883 }; | 1024 }; |
884 | 1025 |
885 | 1026 |
886 class BindInstr : public Definition { | |
887 public: | |
888 BindInstr(UseKind used, Computation* computation) | |
889 : computation_(computation) { | |
890 ASSERT(computation != NULL); | |
891 set_use_kind(used); | |
892 } | |
893 | |
894 DECLARE_INSTRUCTION(Bind) | |
895 | |
896 // Overridden functions from class Instruction. | |
897 virtual intptr_t ArgumentCount() const; | |
898 intptr_t InputCount() const; | |
899 Value* InputAt(intptr_t i) const; | |
900 void SetInputAt(intptr_t i, Value* value); | |
901 virtual bool CanDeoptimize() const; | |
902 virtual void RecordAssignedVars(BitVector* assigned_vars, | |
903 intptr_t fixed_parameter_count); | |
904 virtual LocationSummary* locs(); | |
905 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
906 virtual Representation RequiredInputRepresentation(intptr_t i) const; | |
907 virtual Representation representation() const; | |
908 virtual intptr_t DeoptimizationTarget() const; | |
909 | |
910 Computation* computation() const { return computation_; } | |
911 void set_computation(Computation* value) { computation_ = value; } | |
912 | |
913 // Overridden functions from class Definition. | |
914 virtual RawAbstractType* CompileType() const; | |
915 virtual intptr_t GetPropagatedCid(); | |
916 | |
917 // Other functions that forward to the computation. | |
918 intptr_t Hashcode() const; | |
919 bool Equals(BindInstr* other) const; | |
920 | |
921 private: | |
922 Computation* computation_; | |
923 | |
924 DISALLOW_COPY_AND_ASSIGN(BindInstr); | |
925 }; | |
926 | |
927 | |
928 class PhiInstr : public Definition { | 1027 class PhiInstr : public Definition { |
929 public: | 1028 public: |
930 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) | 1029 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) |
931 : block_(block), | 1030 : block_(block), |
932 inputs_(num_inputs), | 1031 inputs_(num_inputs), |
933 is_alive_(false), | 1032 is_alive_(false), |
934 representation_(kTagged) { | 1033 representation_(kTagged) { |
935 for (intptr_t i = 0; i < num_inputs; ++i) { | 1034 for (intptr_t i = 0; i < num_inputs; ++i) { |
936 inputs_.Add(NULL); | 1035 inputs_.Add(NULL); |
937 } | 1036 } |
938 } | 1037 } |
939 | 1038 |
940 JoinEntryInstr* block() const { return block_; } | 1039 JoinEntryInstr* block() const { return block_; } |
941 | 1040 |
942 virtual RawAbstractType* CompileType() const; | 1041 virtual RawAbstractType* CompileType() const; |
943 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 1042 virtual intptr_t GetPropagatedCid(); |
944 | 1043 |
945 virtual intptr_t ArgumentCount() const { return 0; } | 1044 virtual intptr_t ArgumentCount() const { return 0; } |
946 | 1045 |
947 intptr_t InputCount() const { return inputs_.length(); } | 1046 intptr_t InputCount() const { return inputs_.length(); } |
948 | 1047 |
949 Value* InputAt(intptr_t i) const { return inputs_[i]; } | 1048 Value* InputAt(intptr_t i) const { return inputs_[i]; } |
950 | 1049 |
951 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } | 1050 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
952 | 1051 |
953 virtual bool CanDeoptimize() const { return false; } | 1052 virtual bool CanDeoptimize() const { return false; } |
(...skipping 10 matching lines...) Expand all Loading... |
964 } | 1063 } |
965 | 1064 |
966 virtual Representation representation() const { | 1065 virtual Representation representation() const { |
967 return representation_; | 1066 return representation_; |
968 } | 1067 } |
969 | 1068 |
970 virtual void set_representation(Representation r) { | 1069 virtual void set_representation(Representation r) { |
971 representation_ = r; | 1070 representation_ = r; |
972 } | 1071 } |
973 | 1072 |
| 1073 virtual intptr_t Hashcode() const { |
| 1074 UNREACHABLE(); |
| 1075 return 0; |
| 1076 } |
| 1077 |
| 1078 virtual intptr_t ResultCid() const { |
| 1079 UNREACHABLE(); |
| 1080 return kIllegalCid; |
| 1081 } |
| 1082 |
974 DECLARE_INSTRUCTION(Phi) | 1083 DECLARE_INSTRUCTION(Phi) |
975 | 1084 |
| 1085 virtual void PrintTo(BufferFormatter* f) const; |
| 1086 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1087 |
976 private: | 1088 private: |
977 JoinEntryInstr* block_; | 1089 JoinEntryInstr* block_; |
978 GrowableArray<Value*> inputs_; | 1090 GrowableArray<Value*> inputs_; |
979 bool is_alive_; | 1091 bool is_alive_; |
980 Representation representation_; | 1092 Representation representation_; |
981 | 1093 |
982 DISALLOW_COPY_AND_ASSIGN(PhiInstr); | 1094 DISALLOW_COPY_AND_ASSIGN(PhiInstr); |
983 }; | 1095 }; |
984 | 1096 |
985 | 1097 |
986 class ParameterInstr : public Definition { | 1098 class ParameterInstr : public Definition { |
987 public: | 1099 public: |
988 explicit ParameterInstr(intptr_t index) : index_(index) { } | 1100 explicit ParameterInstr(intptr_t index) : index_(index) { } |
989 | 1101 |
990 DECLARE_INSTRUCTION(Parameter) | 1102 DECLARE_INSTRUCTION(Parameter) |
991 | 1103 |
992 intptr_t index() const { return index_; } | 1104 intptr_t index() const { return index_; } |
993 | 1105 |
994 // Compile type of the passed-in parameter. | 1106 // Compile type of the passed-in parameter. |
995 virtual RawAbstractType* CompileType() const; | 1107 virtual RawAbstractType* CompileType() const; |
| 1108 |
996 // No known propagated cid for parameters. | 1109 // No known propagated cid for parameters. |
997 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 1110 virtual intptr_t GetPropagatedCid(); |
998 | 1111 |
999 virtual intptr_t ArgumentCount() const { return 0; } | 1112 virtual intptr_t ArgumentCount() const { return 0; } |
1000 | 1113 |
1001 intptr_t InputCount() const { return 0; } | 1114 intptr_t InputCount() const { return 0; } |
1002 Value* InputAt(intptr_t i) const { | 1115 Value* InputAt(intptr_t i) const { |
1003 UNREACHABLE(); | 1116 UNREACHABLE(); |
1004 return NULL; | 1117 return NULL; |
1005 } | 1118 } |
1006 void SetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } | 1119 void SetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } |
1007 | 1120 |
1008 virtual bool CanDeoptimize() const { return false; } | 1121 virtual bool CanDeoptimize() const { return false; } |
1009 | 1122 |
| 1123 virtual intptr_t Hashcode() const { |
| 1124 UNREACHABLE(); |
| 1125 return 0; |
| 1126 } |
| 1127 |
| 1128 virtual intptr_t ResultCid() const { |
| 1129 UNREACHABLE(); |
| 1130 return kIllegalCid; |
| 1131 } |
| 1132 |
| 1133 virtual void PrintTo(BufferFormatter* f) const; |
| 1134 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1135 |
1010 private: | 1136 private: |
1011 const intptr_t index_; | 1137 const intptr_t index_; |
1012 | 1138 |
1013 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); | 1139 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); |
1014 }; | 1140 }; |
1015 | 1141 |
1016 | 1142 |
1017 class PushArgumentInstr : public Definition { | 1143 class PushArgumentInstr : public Definition { |
1018 public: | 1144 public: |
1019 explicit PushArgumentInstr(Value* value) : value_(value), locs_(NULL) { | 1145 explicit PushArgumentInstr(Value* value) : value_(value), locs_(NULL) { |
1020 ASSERT(value != NULL); | 1146 ASSERT(value != NULL); |
| 1147 set_use_kind(kEffect); // Override the default. |
1021 } | 1148 } |
1022 | 1149 |
1023 DECLARE_INSTRUCTION(PushArgument) | 1150 DECLARE_INSTRUCTION(PushArgument) |
1024 | 1151 |
1025 intptr_t InputCount() const { return 1; } | 1152 intptr_t InputCount() const { return 1; } |
1026 Value* InputAt(intptr_t i) const { | 1153 Value* InputAt(intptr_t i) const { |
1027 ASSERT(i == 0); | 1154 ASSERT(i == 0); |
1028 return value_; | 1155 return value_; |
1029 } | 1156 } |
1030 void SetInputAt(intptr_t i, Value* value) { | 1157 void SetInputAt(intptr_t i, Value* value) { |
1031 ASSERT(i == 0); | 1158 ASSERT(i == 0); |
1032 value_ = value; | 1159 value_ = value; |
1033 } | 1160 } |
1034 | 1161 |
1035 virtual intptr_t ArgumentCount() const { return 0; } | 1162 virtual intptr_t ArgumentCount() const { return 0; } |
1036 | 1163 |
1037 virtual RawAbstractType* CompileType() const; | 1164 virtual RawAbstractType* CompileType() const; |
1038 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } | 1165 virtual intptr_t GetPropagatedCid() { return propagated_cid(); } |
| 1166 virtual intptr_t ResultCid() const { |
| 1167 UNREACHABLE(); |
| 1168 return kIllegalCid; |
| 1169 } |
1039 | 1170 |
1040 Value* value() const { return value_; } | 1171 Value* value() const { return value_; } |
1041 | 1172 |
1042 virtual LocationSummary* locs() { | 1173 virtual LocationSummary* locs() { |
1043 if (locs_ == NULL) { | 1174 if (locs_ == NULL) { |
1044 locs_ = MakeLocationSummary(); | 1175 locs_ = MakeLocationSummary(); |
1045 } | 1176 } |
1046 return locs_; | 1177 return locs_; |
1047 } | 1178 } |
1048 | 1179 |
1049 LocationSummary* MakeLocationSummary() const; | 1180 virtual intptr_t Hashcode() const { |
1050 | 1181 UNREACHABLE(); |
1051 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 1182 return 0; |
| 1183 } |
1052 | 1184 |
1053 virtual bool CanDeoptimize() const { return false; } | 1185 virtual bool CanDeoptimize() const { return false; } |
1054 | 1186 |
| 1187 virtual void PrintTo(BufferFormatter* f) const; |
| 1188 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1189 |
1055 private: | 1190 private: |
1056 Value* value_; | 1191 Value* value_; |
1057 LocationSummary* locs_; | 1192 LocationSummary* locs_; |
1058 | 1193 |
1059 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); | 1194 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); |
1060 }; | 1195 }; |
1061 | 1196 |
1062 | 1197 |
1063 class ReturnInstr : public TemplateInstruction<1> { | 1198 class ReturnInstr : public TemplateInstruction<1> { |
1064 public: | 1199 public: |
1065 ReturnInstr(intptr_t token_pos, Value* value) | 1200 ReturnInstr(intptr_t token_pos, Value* value) |
1066 : deopt_id_(Isolate::Current()->GetNextDeoptId()), | 1201 : token_pos_(token_pos) { |
1067 token_pos_(token_pos) { | |
1068 ASSERT(value != NULL); | 1202 ASSERT(value != NULL); |
1069 inputs_[0] = value; | 1203 inputs_[0] = value; |
1070 } | 1204 } |
1071 | 1205 |
1072 DECLARE_INSTRUCTION(Return) | 1206 DECLARE_INSTRUCTION(Return) |
1073 | 1207 |
1074 virtual intptr_t ArgumentCount() const { return 0; } | 1208 virtual intptr_t ArgumentCount() const { return 0; } |
1075 | 1209 |
1076 intptr_t deopt_id() const { return deopt_id_; } | |
1077 intptr_t token_pos() const { return token_pos_; } | 1210 intptr_t token_pos() const { return token_pos_; } |
1078 Value* value() const { return inputs_[0]; } | 1211 Value* value() const { return inputs_[0]; } |
1079 | 1212 |
1080 virtual LocationSummary* MakeLocationSummary() const; | |
1081 | |
1082 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
1083 | |
1084 virtual bool CanDeoptimize() const { return false; } | 1213 virtual bool CanDeoptimize() const { return false; } |
1085 | 1214 |
| 1215 virtual void PrintTo(BufferFormatter* f) const; |
| 1216 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1217 |
1086 private: | 1218 private: |
1087 const intptr_t deopt_id_; | |
1088 const intptr_t token_pos_; | 1219 const intptr_t token_pos_; |
1089 | 1220 |
1090 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); | 1221 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); |
1091 }; | 1222 }; |
1092 | 1223 |
1093 | 1224 |
1094 class ThrowInstr : public TemplateInstruction<0> { | 1225 class ThrowInstr : public TemplateInstruction<0> { |
1095 public: | 1226 public: |
1096 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } | 1227 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } |
1097 | 1228 |
1098 DECLARE_INSTRUCTION(Throw) | 1229 DECLARE_INSTRUCTION(Throw) |
1099 | 1230 |
1100 virtual intptr_t ArgumentCount() const { return 1; } | 1231 virtual intptr_t ArgumentCount() const { return 1; } |
1101 | 1232 |
1102 intptr_t token_pos() const { return token_pos_; } | 1233 intptr_t token_pos() const { return token_pos_; } |
1103 | 1234 |
1104 virtual LocationSummary* MakeLocationSummary() const; | 1235 virtual bool CanDeoptimize() const { return false; } |
1105 | 1236 |
1106 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 1237 virtual void PrintTo(BufferFormatter* f) const; |
1107 | 1238 virtual void PrintToVisualizer(BufferFormatter* f) const; |
1108 virtual bool CanDeoptimize() const { return false; } | |
1109 | 1239 |
1110 private: | 1240 private: |
1111 const intptr_t token_pos_; | 1241 const intptr_t token_pos_; |
1112 | 1242 |
1113 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); | 1243 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); |
1114 }; | 1244 }; |
1115 | 1245 |
1116 | 1246 |
1117 class ReThrowInstr : public TemplateInstruction<0> { | 1247 class ReThrowInstr : public TemplateInstruction<0> { |
1118 public: | 1248 public: |
1119 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } | 1249 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } |
1120 | 1250 |
1121 DECLARE_INSTRUCTION(ReThrow) | 1251 DECLARE_INSTRUCTION(ReThrow) |
1122 | 1252 |
1123 virtual intptr_t ArgumentCount() const { return 2; } | 1253 virtual intptr_t ArgumentCount() const { return 2; } |
1124 | 1254 |
1125 intptr_t token_pos() const { return token_pos_; } | 1255 intptr_t token_pos() const { return token_pos_; } |
1126 | 1256 |
1127 virtual LocationSummary* MakeLocationSummary() const; | 1257 virtual bool CanDeoptimize() const { return false; } |
1128 | 1258 |
1129 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 1259 virtual void PrintTo(BufferFormatter* f) const; |
1130 | 1260 virtual void PrintToVisualizer(BufferFormatter* f) const; |
1131 virtual bool CanDeoptimize() const { return false; } | |
1132 | 1261 |
1133 private: | 1262 private: |
1134 const intptr_t token_pos_; | 1263 const intptr_t token_pos_; |
1135 | 1264 |
1136 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 1265 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
1137 }; | 1266 }; |
1138 | 1267 |
1139 | 1268 |
1140 class GotoInstr : public TemplateInstruction<0> { | 1269 class GotoInstr : public TemplateInstruction<0> { |
1141 public: | 1270 public: |
1142 explicit GotoInstr(JoinEntryInstr* entry) | 1271 explicit GotoInstr(JoinEntryInstr* entry) |
1143 : successor_(entry), | 1272 : successor_(entry), |
1144 parallel_move_(NULL) { } | 1273 parallel_move_(NULL) { } |
1145 | 1274 |
1146 DECLARE_INSTRUCTION(Goto) | 1275 DECLARE_INSTRUCTION(Goto) |
1147 | 1276 |
1148 virtual intptr_t ArgumentCount() const { return 0; } | 1277 virtual intptr_t ArgumentCount() const { return 0; } |
1149 | 1278 |
1150 JoinEntryInstr* successor() const { return successor_; } | 1279 JoinEntryInstr* successor() const { return successor_; } |
1151 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } | 1280 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } |
1152 virtual intptr_t SuccessorCount() const; | 1281 virtual intptr_t SuccessorCount() const; |
1153 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1282 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
1154 | 1283 |
1155 virtual LocationSummary* MakeLocationSummary() const; | |
1156 | |
1157 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
1158 | |
1159 virtual bool CanDeoptimize() const { return false; } | 1284 virtual bool CanDeoptimize() const { return false; } |
1160 | 1285 |
1161 ParallelMoveInstr* parallel_move() const { | 1286 ParallelMoveInstr* parallel_move() const { |
1162 return parallel_move_; | 1287 return parallel_move_; |
1163 } | 1288 } |
1164 | 1289 |
1165 bool HasParallelMove() const { | 1290 bool HasParallelMove() const { |
1166 return parallel_move_ != NULL; | 1291 return parallel_move_ != NULL; |
1167 } | 1292 } |
1168 | 1293 |
1169 ParallelMoveInstr* GetParallelMove() { | 1294 ParallelMoveInstr* GetParallelMove() { |
1170 if (parallel_move_ == NULL) { | 1295 if (parallel_move_ == NULL) { |
1171 parallel_move_ = new ParallelMoveInstr(); | 1296 parallel_move_ = new ParallelMoveInstr(); |
1172 } | 1297 } |
1173 return parallel_move_; | 1298 return parallel_move_; |
1174 } | 1299 } |
1175 | 1300 |
| 1301 virtual void PrintTo(BufferFormatter* f) const; |
| 1302 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1303 |
1176 private: | 1304 private: |
1177 JoinEntryInstr* successor_; | 1305 JoinEntryInstr* successor_; |
1178 | 1306 |
1179 // Parallel move that will be used by linear scan register allocator to | 1307 // Parallel move that will be used by linear scan register allocator to |
1180 // connect live ranges at the end of the block and resolve phis. | 1308 // connect live ranges at the end of the block and resolve phis. |
1181 ParallelMoveInstr* parallel_move_; | 1309 ParallelMoveInstr* parallel_move_; |
1182 }; | 1310 }; |
1183 | 1311 |
1184 | 1312 |
1185 class ControlInstruction : public Instruction { | 1313 class ControlInstruction : public Instruction { |
(...skipping 27 matching lines...) Expand all Loading... |
1213 private: | 1341 private: |
1214 TargetEntryInstr* true_successor_; | 1342 TargetEntryInstr* true_successor_; |
1215 TargetEntryInstr* false_successor_; | 1343 TargetEntryInstr* false_successor_; |
1216 | 1344 |
1217 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); | 1345 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); |
1218 }; | 1346 }; |
1219 | 1347 |
1220 | 1348 |
1221 class BranchInstr : public ControlInstruction { | 1349 class BranchInstr : public ControlInstruction { |
1222 public: | 1350 public: |
1223 explicit BranchInstr(ComparisonComp* computation) | 1351 explicit BranchInstr(ComparisonInstr* comparison) |
1224 : computation_(computation), locs_(NULL) { } | 1352 : comparison_(comparison) { } |
1225 | 1353 |
1226 DECLARE_INSTRUCTION(Branch) | 1354 DECLARE_INSTRUCTION(Branch) |
1227 | 1355 |
1228 virtual intptr_t ArgumentCount() const; | 1356 virtual intptr_t ArgumentCount() const; |
1229 intptr_t InputCount() const; | 1357 intptr_t InputCount() const; |
1230 Value* InputAt(intptr_t i) const; | 1358 Value* InputAt(intptr_t i) const; |
1231 void SetInputAt(intptr_t i, Value* value); | 1359 void SetInputAt(intptr_t i, Value* value); |
1232 virtual bool CanDeoptimize() const; | 1360 virtual bool CanDeoptimize() const; |
1233 | 1361 |
1234 ComparisonComp* computation() const { return computation_; } | 1362 ComparisonInstr* comparison() const { return comparison_; } |
1235 void set_computation(ComparisonComp* value) { computation_ = value; } | 1363 void set_comparison(ComparisonInstr* value) { comparison_ = value; } |
1236 | |
1237 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
1238 | 1364 |
1239 virtual LocationSummary* locs(); | 1365 virtual LocationSummary* locs(); |
1240 virtual intptr_t DeoptimizationTarget() const; | 1366 virtual intptr_t DeoptimizationTarget() const; |
1241 virtual Representation RequiredInputRepresentation(intptr_t i) const; | 1367 virtual Representation RequiredInputRepresentation(intptr_t i) const; |
1242 | 1368 |
| 1369 // Replace the comparison with another, leaving the branch intact. |
| 1370 void ReplaceWith(ComparisonInstr* other, |
| 1371 ForwardInstructionIterator* ignored) { |
| 1372 comparison_ = other; |
| 1373 } |
| 1374 |
| 1375 virtual void PrintTo(BufferFormatter* f) const; |
| 1376 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1377 |
1243 private: | 1378 private: |
1244 ComparisonComp* computation_; | 1379 ComparisonInstr* comparison_; |
1245 LocationSummary* locs_; | |
1246 | 1380 |
1247 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 1381 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
1248 }; | 1382 }; |
1249 | 1383 |
1250 | 1384 |
1251 #undef DECLARE_INSTRUCTION | 1385 template<intptr_t N> |
| 1386 class TemplateDefinition : public Definition { |
| 1387 public: |
| 1388 TemplateDefinition<N>() : locs_(NULL) { } |
1252 | 1389 |
1253 | 1390 virtual intptr_t InputCount() const { return N; } |
1254 // M is a two argument macro. It is applied to each concrete instruction's | 1391 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
1255 // (including the values) typename and classname. | 1392 virtual void SetInputAt(intptr_t i, Value* value) { |
1256 #define FOR_EACH_COMPUTATION(M) \ | 1393 ASSERT(value != NULL); |
1257 M(AssertAssignable, AssertAssignableComp) \ | 1394 inputs_[i] = value; |
1258 M(AssertBoolean, AssertBooleanComp) \ | |
1259 M(ArgumentDefinitionTest, ArgumentDefinitionTestComp) \ | |
1260 M(CurrentContext, CurrentContextComp) \ | |
1261 M(StoreContext, StoreContextComp) \ | |
1262 M(ClosureCall, ClosureCallComp) \ | |
1263 M(InstanceCall, InstanceCallComp) \ | |
1264 M(PolymorphicInstanceCall, PolymorphicInstanceCallComp) \ | |
1265 M(StaticCall, StaticCallComp) \ | |
1266 M(LoadLocal, LoadLocalComp) \ | |
1267 M(StoreLocal, StoreLocalComp) \ | |
1268 M(StrictCompare, StrictCompareComp) \ | |
1269 M(EqualityCompare, EqualityCompareComp) \ | |
1270 M(RelationalOp, RelationalOpComp) \ | |
1271 M(NativeCall, NativeCallComp) \ | |
1272 M(LoadIndexed, LoadIndexedComp) \ | |
1273 M(StoreIndexed, StoreIndexedComp) \ | |
1274 M(LoadInstanceField, LoadInstanceFieldComp) \ | |
1275 M(StoreInstanceField, StoreInstanceFieldComp) \ | |
1276 M(LoadStaticField, LoadStaticFieldComp) \ | |
1277 M(StoreStaticField, StoreStaticFieldComp) \ | |
1278 M(BooleanNegate, BooleanNegateComp) \ | |
1279 M(InstanceOf, InstanceOfComp) \ | |
1280 M(CreateArray, CreateArrayComp) \ | |
1281 M(CreateClosure, CreateClosureComp) \ | |
1282 M(AllocateObject, AllocateObjectComp) \ | |
1283 M(AllocateObjectWithBoundsCheck, AllocateObjectWithBoundsCheckComp) \ | |
1284 M(LoadVMField, LoadVMFieldComp) \ | |
1285 M(StoreVMField, StoreVMFieldComp) \ | |
1286 M(InstantiateTypeArguments, InstantiateTypeArgumentsComp) \ | |
1287 M(ExtractConstructorTypeArguments, ExtractConstructorTypeArgumentsComp) \ | |
1288 M(ExtractConstructorInstantiator, ExtractConstructorInstantiatorComp) \ | |
1289 M(AllocateContext, AllocateContextComp) \ | |
1290 M(ChainContext, ChainContextComp) \ | |
1291 M(CloneContext, CloneContextComp) \ | |
1292 M(CatchEntry, CatchEntryComp) \ | |
1293 M(BinarySmiOp, BinarySmiOpComp) \ | |
1294 M(BinaryMintOp, BinaryMintOpComp) \ | |
1295 M(UnarySmiOp, UnarySmiOpComp) \ | |
1296 M(NumberNegate, NumberNegateComp) \ | |
1297 M(CheckStackOverflow, CheckStackOverflowComp) \ | |
1298 M(DoubleToDouble, DoubleToDoubleComp) \ | |
1299 M(SmiToDouble, SmiToDoubleComp) \ | |
1300 M(CheckClass, CheckClassComp) \ | |
1301 M(CheckSmi, CheckSmiComp) \ | |
1302 M(Constant, ConstantComp) \ | |
1303 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ | |
1304 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ | |
1305 M(UnboxDouble, UnboxDoubleComp) \ | |
1306 M(BoxDouble, BoxDoubleComp) \ | |
1307 M(CheckArrayBound, CheckArrayBoundComp) | |
1308 | |
1309 | |
1310 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | |
1311 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | |
1312 #undef FORWARD_DECLARATION | |
1313 | |
1314 | |
1315 class Computation : public ZoneAllocated { | |
1316 public: | |
1317 Computation() | |
1318 : deopt_id_(Isolate::Current()->GetNextDeoptId()), locs_(NULL) { } | |
1319 | |
1320 // Unique id used for deoptimization. | |
1321 virtual intptr_t deopt_id() const { | |
1322 ASSERT(CanDeoptimize()); | |
1323 return deopt_id_; | |
1324 } | 1395 } |
1325 | 1396 |
1326 // Visiting support. | 1397 // Returns a structure describing the location constraints required |
1327 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; | 1398 // to emit native code for this definition. |
1328 | |
1329 virtual intptr_t InputCount() const = 0; | |
1330 virtual Value* InputAt(intptr_t i) const = 0; | |
1331 virtual void SetInputAt(intptr_t i, Value* value) = 0; | |
1332 | |
1333 // Call computations override this function and return the | |
1334 // number of pushed arguments. | |
1335 virtual intptr_t ArgumentCount() const = 0; | |
1336 | |
1337 // Returns true, if this computation can deoptimize. | |
1338 virtual bool CanDeoptimize() const = 0; | |
1339 | |
1340 // Returns a replacement for the instruction that wraps this computation. | |
1341 // Returns NULL if instr can be eliminated. | |
1342 // By default returns instr (input parameter) which means no change. | |
1343 virtual Definition* TryReplace(BindInstr* instr) const; | |
1344 | |
1345 // Compares two computations. Returns true, if: | |
1346 // 1. They are of the same kind. | |
1347 // 2. All input operands match. | |
1348 // 3. All other attributes match. | |
1349 bool Equals(Computation* other) const; | |
1350 | |
1351 // Returns a hash code for use with hash maps. | |
1352 virtual intptr_t Hashcode() const; | |
1353 | |
1354 // Compare attributes of an computation (except input operands and kind). | |
1355 // All computations that participate in CSE have to override this function. | |
1356 virtual bool AttributesEqual(Computation* other) const { | |
1357 UNREACHABLE(); | |
1358 return false; | |
1359 } | |
1360 | |
1361 // Returns true if the instruction may have side effects. | |
1362 // TODO(fschneider): Make this abstract and implement for all computations | |
1363 // instead of returning the safe default (true). | |
1364 virtual bool HasSideEffect() const { return true; } | |
1365 | |
1366 // Compile time type of the computation, which typically depends on the | |
1367 // compile time types (and possibly propagated types) of its inputs. | |
1368 virtual RawAbstractType* CompileType() const = 0; | |
1369 virtual intptr_t ResultCid() const = 0; | |
1370 | |
1371 // Mutate assigned_vars to add the local variable index for all | |
1372 // frame-allocated locals assigned to by the computation. | |
1373 virtual void RecordAssignedVars(BitVector* assigned_vars, | |
1374 intptr_t fixed_parameter_count); | |
1375 | |
1376 virtual const char* DebugName() const = 0; | |
1377 | |
1378 // Printing support. These functions are sometimes overridden for custom | |
1379 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". | |
1380 virtual void PrintTo(BufferFormatter* f) const; | |
1381 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
1382 | |
1383 // Returns structure describing location constraints required | |
1384 // to emit native code for this computation. | |
1385 LocationSummary* locs() { | 1399 LocationSummary* locs() { |
1386 if (locs_ == NULL) { | 1400 if (locs_ == NULL) { |
1387 locs_ = MakeLocationSummary(); | 1401 locs_ = MakeLocationSummary(); |
1388 } | 1402 } |
1389 return locs_; | 1403 return locs_; |
1390 } | 1404 } |
1391 | 1405 |
1392 virtual ComparisonComp* AsComparison() { return NULL; } | |
1393 | |
1394 // Create a location summary for this computation. | |
1395 // TODO(fschneider): Temporarily returns NULL for instructions | |
1396 // that are not yet converted to the location based code generation. | |
1397 virtual LocationSummary* MakeLocationSummary() const = 0; | |
1398 | |
1399 // TODO(fschneider): Make EmitNativeCode and locs const. | |
1400 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | |
1401 | |
1402 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | |
1403 BranchInstr* branch) { | |
1404 UNREACHABLE(); | |
1405 } | |
1406 | |
1407 static LocationSummary* MakeCallSummary(); | |
1408 | |
1409 // Declare an enum value used to define kind-test predicates. | |
1410 enum ComputationKind { | |
1411 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, | |
1412 | |
1413 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) | |
1414 | |
1415 #undef DECLARE_COMPUTATION_KIND | |
1416 }; | |
1417 | |
1418 virtual ComputationKind computation_kind() const = 0; | |
1419 | |
1420 // Returns representation expected for the input operand at the given index. | |
1421 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
1422 return kTagged; | |
1423 } | |
1424 | |
1425 // Representation of the value produced by this computation. | |
1426 virtual Representation representation() const { | |
1427 return kTagged; | |
1428 } | |
1429 | |
1430 // Returns deoptimization id that corresponds to the deoptimization target | |
1431 // that input operands conversions inserted for this instruction can jump | |
1432 // to. Can return kNoDeoptId. | |
1433 virtual intptr_t DeoptimizationTarget() const { | |
1434 UNREACHABLE(); | |
1435 return Isolate::kNoDeoptId; | |
1436 } | |
1437 | |
1438 // Declare predicate for each computation. | |
1439 #define DECLARE_PREDICATE(ShortName, ClassName) \ | |
1440 inline bool Is##ShortName() const; \ | |
1441 inline const ClassName* As##ShortName() const; \ | |
1442 inline ClassName* As##ShortName(); | |
1443 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | |
1444 #undef DECLARE_PREDICATE | |
1445 | |
1446 protected: | 1406 protected: |
1447 // Fetch deopt id without checking if this computation can deoptimize. | 1407 EmbeddedArray<Value*, N> inputs_; |
1448 intptr_t GetDeoptId() const { | |
1449 return deopt_id_; | |
1450 } | |
1451 | 1408 |
1452 private: | 1409 private: |
1453 friend class BranchInstr; | 1410 friend class BranchInstr; |
1454 | 1411 |
1455 intptr_t deopt_id_; | |
1456 LocationSummary* locs_; | 1412 LocationSummary* locs_; |
1457 | |
1458 DISALLOW_COPY_AND_ASSIGN(Computation); | |
1459 }; | 1413 }; |
1460 | 1414 |
1461 | 1415 |
1462 // Inlined functions from class BindInstr that forward to their computation. | 1416 class ConstantInstr : public TemplateDefinition<0> { |
1463 inline intptr_t BindInstr::ArgumentCount() const { | 1417 public: |
1464 return computation()->ArgumentCount(); | 1418 explicit ConstantInstr(const Object& value) : value_(value) { } |
1465 } | |
1466 | 1419 |
1467 | 1420 DECLARE_INSTRUCTION(Constant) |
1468 inline intptr_t BindInstr::InputCount() const { | 1421 virtual RawAbstractType* CompileType() const; |
1469 return computation()->InputCount(); | |
1470 } | |
1471 | |
1472 | |
1473 inline Value* BindInstr::InputAt(intptr_t i) const { | |
1474 return computation()->InputAt(i); | |
1475 } | |
1476 | |
1477 | |
1478 inline void BindInstr::SetInputAt(intptr_t i, Value* value) { | |
1479 computation()->SetInputAt(i, value); | |
1480 } | |
1481 | |
1482 inline bool BindInstr::CanDeoptimize() const { | |
1483 return computation()->CanDeoptimize(); | |
1484 } | |
1485 | |
1486 | |
1487 inline intptr_t BindInstr::Hashcode() const { | |
1488 return computation()->Hashcode(); | |
1489 } | |
1490 | |
1491 | |
1492 inline bool BindInstr::Equals(BindInstr* other) const { | |
1493 return computation()->Equals(other->computation()); | |
1494 } | |
1495 | |
1496 | |
1497 inline LocationSummary* BindInstr::locs() { | |
1498 return computation()->locs(); | |
1499 } | |
1500 | |
1501 | |
1502 inline Representation BindInstr::RequiredInputRepresentation(intptr_t i) const { | |
1503 return computation()->RequiredInputRepresentation(i); | |
1504 } | |
1505 | |
1506 | |
1507 inline Representation BindInstr::representation() const { | |
1508 return computation()->representation(); | |
1509 } | |
1510 | |
1511 | |
1512 inline intptr_t BindInstr::DeoptimizationTarget() const { | |
1513 return computation()->DeoptimizationTarget(); | |
1514 } | |
1515 | |
1516 | |
1517 template<intptr_t N> | |
1518 class TemplateComputation : public Computation { | |
1519 public: | |
1520 virtual intptr_t InputCount() const { return N; } | |
1521 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | |
1522 virtual void SetInputAt(intptr_t i, Value* value) { | |
1523 ASSERT(value != NULL); | |
1524 inputs_[i] = value; | |
1525 } | |
1526 | |
1527 protected: | |
1528 EmbeddedArray<Value*, N> inputs_; | |
1529 }; | |
1530 | |
1531 | |
1532 // Functions defined in all concrete computation classes. | |
1533 #define DECLARE_COMPUTATION(ShortName) \ | |
1534 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | |
1535 virtual ComputationKind computation_kind() const { \ | |
1536 return Computation::k##ShortName; \ | |
1537 } \ | |
1538 virtual intptr_t ArgumentCount() const { return 0; } \ | |
1539 virtual const char* DebugName() const { return #ShortName; } \ | |
1540 virtual RawAbstractType* CompileType() const; \ | |
1541 virtual LocationSummary* MakeLocationSummary() const; \ | |
1542 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
1543 | |
1544 | |
1545 // Function defined in all call computation classes. | |
1546 #define DECLARE_CALL_COMPUTATION(ShortName) \ | |
1547 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | |
1548 virtual ComputationKind computation_kind() const { \ | |
1549 return Computation::k##ShortName; \ | |
1550 } \ | |
1551 virtual const char* DebugName() const { return #ShortName; } \ | |
1552 virtual RawAbstractType* CompileType() const; \ | |
1553 virtual LocationSummary* MakeLocationSummary() const; \ | |
1554 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
1555 | |
1556 | |
1557 class ConstantComp : public TemplateComputation<0> { | |
1558 public: | |
1559 explicit ConstantComp(const Object& value) : value_(value) { } | |
1560 | |
1561 DECLARE_COMPUTATION(Constant) | |
1562 | 1422 |
1563 const Object& value() const { return value_; } | 1423 const Object& value() const { return value_; } |
1564 | 1424 |
1565 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1425 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1566 | 1426 |
1567 virtual bool CanDeoptimize() const { return false; } | 1427 virtual bool CanDeoptimize() const { return false; } |
1568 | 1428 |
1569 virtual intptr_t ResultCid() const; | 1429 virtual intptr_t ResultCid() const; |
1570 | 1430 |
1571 virtual bool AttributesEqual(Computation* other) const; | 1431 virtual bool AttributesEqual(Definition* other) const; |
1572 | 1432 |
1573 private: | 1433 private: |
1574 const Object& value_; | 1434 const Object& value_; |
1575 | 1435 |
1576 DISALLOW_COPY_AND_ASSIGN(ConstantComp); | 1436 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); |
1577 }; | 1437 }; |
1578 | 1438 |
1579 | 1439 |
1580 class AssertAssignableComp : public TemplateComputation<3> { | 1440 class AssertAssignableInstr : public TemplateDefinition<3> { |
1581 public: | 1441 public: |
1582 AssertAssignableComp(intptr_t token_pos, | 1442 AssertAssignableInstr(intptr_t token_pos, |
1583 Value* value, | 1443 Value* value, |
1584 Value* instantiator, | 1444 Value* instantiator, |
1585 Value* instantiator_type_arguments, | 1445 Value* instantiator_type_arguments, |
1586 const AbstractType& dst_type, | 1446 const AbstractType& dst_type, |
1587 const String& dst_name) | 1447 const String& dst_name) |
1588 : token_pos_(token_pos), | 1448 : token_pos_(token_pos), |
1589 dst_type_(dst_type), | 1449 dst_type_(dst_type), |
1590 dst_name_(dst_name), | 1450 dst_name_(dst_name), |
1591 is_eliminated_(false) { | 1451 is_eliminated_(false) { |
1592 ASSERT(value != NULL); | 1452 ASSERT(value != NULL); |
1593 ASSERT(instantiator != NULL); | 1453 ASSERT(instantiator != NULL); |
1594 ASSERT(instantiator_type_arguments != NULL); | 1454 ASSERT(instantiator_type_arguments != NULL); |
1595 ASSERT(!dst_type.IsNull()); | 1455 ASSERT(!dst_type.IsNull()); |
1596 ASSERT(!dst_name.IsNull()); | 1456 ASSERT(!dst_name.IsNull()); |
1597 inputs_[0] = value; | 1457 inputs_[0] = value; |
1598 inputs_[1] = instantiator; | 1458 inputs_[1] = instantiator; |
1599 inputs_[2] = instantiator_type_arguments; | 1459 inputs_[2] = instantiator_type_arguments; |
1600 } | 1460 } |
1601 | 1461 |
1602 DECLARE_COMPUTATION(AssertAssignable) | 1462 DECLARE_INSTRUCTION(AssertAssignable) |
| 1463 virtual RawAbstractType* CompileType() const; |
1603 | 1464 |
1604 Value* value() const { return inputs_[0]; } | 1465 Value* value() const { return inputs_[0]; } |
1605 Value* instantiator() const { return inputs_[1]; } | 1466 Value* instantiator() const { return inputs_[1]; } |
1606 Value* instantiator_type_arguments() const { return inputs_[2]; } | 1467 Value* instantiator_type_arguments() const { return inputs_[2]; } |
1607 | 1468 |
1608 intptr_t token_pos() const { return token_pos_; } | 1469 intptr_t token_pos() const { return token_pos_; } |
1609 const AbstractType& dst_type() const { return dst_type_; } | 1470 const AbstractType& dst_type() const { return dst_type_; } |
1610 const String& dst_name() const { return dst_name_; } | 1471 const String& dst_name() const { return dst_name_; } |
1611 | 1472 |
1612 bool is_eliminated() const { | 1473 bool is_eliminated() const { |
1613 return is_eliminated_; | 1474 return is_eliminated_; |
1614 } | 1475 } |
1615 void eliminate() { | 1476 void eliminate() { |
1616 ASSERT(!is_eliminated_); | 1477 ASSERT(!is_eliminated_); |
1617 is_eliminated_ = true; | 1478 is_eliminated_ = true; |
1618 } | 1479 } |
1619 | 1480 |
1620 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1481 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1621 | 1482 |
1622 virtual bool CanDeoptimize() const { return false; } | 1483 virtual bool CanDeoptimize() const { return false; } |
1623 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1484 virtual intptr_t ResultCid() const { return kDynamicCid; } |
1624 | 1485 |
1625 private: | 1486 private: |
1626 const intptr_t token_pos_; | 1487 const intptr_t token_pos_; |
1627 const AbstractType& dst_type_; | 1488 const AbstractType& dst_type_; |
1628 const String& dst_name_; | 1489 const String& dst_name_; |
1629 bool is_eliminated_; | 1490 bool is_eliminated_; |
1630 | 1491 |
1631 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); | 1492 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr); |
1632 }; | 1493 }; |
1633 | 1494 |
1634 | 1495 |
1635 class AssertBooleanComp : public TemplateComputation<1> { | 1496 class AssertBooleanInstr : public TemplateDefinition<1> { |
1636 public: | 1497 public: |
1637 AssertBooleanComp(intptr_t token_pos, | 1498 AssertBooleanInstr(intptr_t token_pos, Value* value) |
1638 Value* value) | |
1639 : token_pos_(token_pos), | 1499 : token_pos_(token_pos), |
1640 is_eliminated_(false) { | 1500 is_eliminated_(false) { |
1641 ASSERT(value != NULL); | 1501 ASSERT(value != NULL); |
1642 inputs_[0] = value; | 1502 inputs_[0] = value; |
1643 } | 1503 } |
1644 | 1504 |
1645 DECLARE_COMPUTATION(AssertBoolean) | 1505 DECLARE_INSTRUCTION(AssertBoolean) |
| 1506 virtual RawAbstractType* CompileType() const; |
1646 | 1507 |
1647 intptr_t token_pos() const { return token_pos_; } | 1508 intptr_t token_pos() const { return token_pos_; } |
1648 Value* value() const { return inputs_[0]; } | 1509 Value* value() const { return inputs_[0]; } |
1649 | 1510 |
1650 bool is_eliminated() const { | 1511 bool is_eliminated() const { |
1651 return is_eliminated_; | 1512 return is_eliminated_; |
1652 } | 1513 } |
1653 void eliminate() { | 1514 void eliminate() { |
1654 ASSERT(!is_eliminated_); | 1515 ASSERT(!is_eliminated_); |
1655 is_eliminated_ = true; | 1516 is_eliminated_ = true; |
1656 } | 1517 } |
1657 | 1518 |
1658 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1519 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1659 | 1520 |
1660 virtual bool CanDeoptimize() const { return false; } | 1521 virtual bool CanDeoptimize() const { return false; } |
1661 virtual intptr_t ResultCid() const { return kBoolCid; } | 1522 virtual intptr_t ResultCid() const { return kBoolCid; } |
1662 | 1523 |
1663 private: | 1524 private: |
1664 const intptr_t token_pos_; | 1525 const intptr_t token_pos_; |
1665 bool is_eliminated_; | 1526 bool is_eliminated_; |
1666 | 1527 |
1667 DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); | 1528 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); |
1668 }; | 1529 }; |
1669 | 1530 |
1670 | 1531 |
1671 class ArgumentDefinitionTestComp : public TemplateComputation<1> { | 1532 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> { |
1672 public: | 1533 public: |
1673 ArgumentDefinitionTestComp(ArgumentDefinitionTestNode* node, | 1534 ArgumentDefinitionTestInstr(ArgumentDefinitionTestNode* node, |
1674 Value* saved_arguments_descriptor) | 1535 Value* saved_arguments_descriptor) |
1675 : ast_node_(*node) { | 1536 : ast_node_(*node) { |
1676 ASSERT(saved_arguments_descriptor != NULL); | 1537 ASSERT(saved_arguments_descriptor != NULL); |
1677 inputs_[0] = saved_arguments_descriptor; | 1538 inputs_[0] = saved_arguments_descriptor; |
1678 } | 1539 } |
1679 | 1540 |
1680 DECLARE_COMPUTATION(ArgumentDefinitionTest) | 1541 DECLARE_INSTRUCTION(ArgumentDefinitionTest) |
| 1542 virtual RawAbstractType* CompileType() const; |
1681 | 1543 |
1682 intptr_t token_pos() const { return ast_node_.token_pos(); } | 1544 intptr_t token_pos() const { return ast_node_.token_pos(); } |
1683 intptr_t formal_parameter_index() const { | 1545 intptr_t formal_parameter_index() const { |
1684 return ast_node_.formal_parameter_index(); | 1546 return ast_node_.formal_parameter_index(); |
1685 } | 1547 } |
1686 const String& formal_parameter_name() const { | 1548 const String& formal_parameter_name() const { |
1687 return ast_node_.formal_parameter_name(); | 1549 return ast_node_.formal_parameter_name(); |
1688 } | 1550 } |
1689 Value* saved_arguments_descriptor() const { return inputs_[0]; } | 1551 Value* saved_arguments_descriptor() const { return inputs_[0]; } |
1690 | 1552 |
1691 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1553 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1692 | 1554 |
1693 virtual bool CanDeoptimize() const { return false; } | 1555 virtual bool CanDeoptimize() const { return false; } |
1694 virtual intptr_t ResultCid() const { return kBoolCid; } | 1556 virtual intptr_t ResultCid() const { return kBoolCid; } |
1695 | 1557 |
1696 private: | 1558 private: |
1697 const ArgumentDefinitionTestNode& ast_node_; | 1559 const ArgumentDefinitionTestNode& ast_node_; |
1698 | 1560 |
1699 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestComp); | 1561 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestInstr); |
1700 }; | 1562 }; |
1701 | 1563 |
1702 | 1564 |
1703 // Denotes the current context, normally held in a register. This is | 1565 // Denotes the current context, normally held in a register. This is |
1704 // a computation, not a value, because it's mutable. | 1566 // a computation, not a value, because it's mutable. |
1705 class CurrentContextComp : public TemplateComputation<0> { | 1567 class CurrentContextInstr : public TemplateDefinition<0> { |
1706 public: | 1568 public: |
1707 CurrentContextComp() { } | 1569 CurrentContextInstr() { } |
1708 | 1570 |
1709 DECLARE_COMPUTATION(CurrentContext) | 1571 DECLARE_INSTRUCTION(CurrentContext) |
| 1572 virtual RawAbstractType* CompileType() const; |
1710 | 1573 |
1711 virtual bool CanDeoptimize() const { return false; } | 1574 virtual bool CanDeoptimize() const { return false; } |
1712 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1575 virtual intptr_t ResultCid() const { return kDynamicCid; } |
1713 | 1576 |
1714 private: | 1577 private: |
1715 DISALLOW_COPY_AND_ASSIGN(CurrentContextComp); | 1578 DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr); |
1716 }; | 1579 }; |
1717 | 1580 |
1718 | 1581 |
1719 class StoreContextComp : public TemplateComputation<1> { | 1582 class StoreContextInstr : public TemplateDefinition<1> { |
1720 public: | 1583 public: |
1721 explicit StoreContextComp(Value* value) { | 1584 explicit StoreContextInstr(Value* value) { |
1722 ASSERT(value != NULL); | 1585 ASSERT(value != NULL); |
1723 inputs_[0] = value; | 1586 inputs_[0] = value; |
1724 } | 1587 } |
1725 | 1588 |
1726 DECLARE_COMPUTATION(StoreContext); | 1589 DECLARE_INSTRUCTION(StoreContext); |
| 1590 virtual RawAbstractType* CompileType() const; |
1727 | 1591 |
1728 Value* value() const { return inputs_[0]; } | 1592 Value* value() const { return inputs_[0]; } |
1729 | 1593 |
1730 virtual bool CanDeoptimize() const { return false; } | 1594 virtual bool CanDeoptimize() const { return false; } |
1731 virtual intptr_t ResultCid() const { return kIllegalCid; } | 1595 virtual intptr_t ResultCid() const { return kIllegalCid; } |
1732 | 1596 |
1733 private: | 1597 private: |
1734 DISALLOW_COPY_AND_ASSIGN(StoreContextComp); | 1598 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); |
1735 }; | 1599 }; |
1736 | 1600 |
1737 | 1601 |
1738 class ClosureCallComp : public TemplateComputation<0> { | 1602 class ClosureCallInstr : public TemplateDefinition<0> { |
1739 public: | 1603 public: |
1740 ClosureCallComp(ClosureCallNode* node, | 1604 ClosureCallInstr(ClosureCallNode* node, |
1741 ZoneGrowableArray<PushArgumentInstr*>* arguments) | 1605 ZoneGrowableArray<PushArgumentInstr*>* arguments) |
1742 : ast_node_(*node), | 1606 : ast_node_(*node), |
1743 arguments_(arguments) { } | 1607 arguments_(arguments) { } |
1744 | 1608 |
1745 DECLARE_CALL_COMPUTATION(ClosureCall) | 1609 DECLARE_INSTRUCTION(ClosureCall) |
| 1610 virtual RawAbstractType* CompileType() const; |
1746 | 1611 |
1747 const Array& argument_names() const { return ast_node_.arguments()->names(); } | 1612 const Array& argument_names() const { return ast_node_.arguments()->names(); } |
1748 intptr_t token_pos() const { return ast_node_.token_pos(); } | 1613 intptr_t token_pos() const { return ast_node_.token_pos(); } |
1749 | 1614 |
1750 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 1615 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
1751 PushArgumentInstr* ArgumentAt(intptr_t index) const { | 1616 PushArgumentInstr* ArgumentAt(intptr_t index) const { |
1752 return (*arguments_)[index]; | 1617 return (*arguments_)[index]; |
1753 } | 1618 } |
1754 | 1619 |
1755 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1620 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1756 | 1621 |
1757 virtual bool CanDeoptimize() const { return true; } | 1622 virtual bool CanDeoptimize() const { return true; } |
1758 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1623 virtual intptr_t ResultCid() const { return kDynamicCid; } |
1759 | 1624 |
1760 private: | 1625 private: |
1761 const ClosureCallNode& ast_node_; | 1626 const ClosureCallNode& ast_node_; |
1762 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 1627 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
1763 | 1628 |
1764 DISALLOW_COPY_AND_ASSIGN(ClosureCallComp); | 1629 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr); |
1765 }; | 1630 }; |
1766 | 1631 |
1767 | 1632 |
1768 class InstanceCallComp : public TemplateComputation<0> { | 1633 class InstanceCallInstr : public TemplateDefinition<0> { |
1769 public: | 1634 public: |
1770 InstanceCallComp(intptr_t token_pos, | 1635 InstanceCallInstr(intptr_t token_pos, |
1771 const String& function_name, | 1636 const String& function_name, |
1772 Token::Kind token_kind, | 1637 Token::Kind token_kind, |
1773 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1638 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
1774 const Array& argument_names, | 1639 const Array& argument_names, |
1775 intptr_t checked_argument_count) | 1640 intptr_t checked_argument_count) |
1776 : ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 1641 : ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), |
1777 token_pos_(token_pos), | 1642 token_pos_(token_pos), |
1778 function_name_(function_name), | 1643 function_name_(function_name), |
1779 token_kind_(token_kind), | 1644 token_kind_(token_kind), |
1780 arguments_(arguments), | 1645 arguments_(arguments), |
1781 argument_names_(argument_names), | 1646 argument_names_(argument_names), |
1782 checked_argument_count_(checked_argument_count) { | 1647 checked_argument_count_(checked_argument_count) { |
1783 ASSERT(function_name.IsZoneHandle()); | 1648 ASSERT(function_name.IsZoneHandle()); |
1784 ASSERT(!arguments->is_empty()); | 1649 ASSERT(!arguments->is_empty()); |
1785 ASSERT(argument_names.IsZoneHandle()); | 1650 ASSERT(argument_names.IsZoneHandle()); |
1786 ASSERT(Token::IsBinaryToken(token_kind) || | 1651 ASSERT(Token::IsBinaryToken(token_kind) || |
1787 Token::IsUnaryToken(token_kind) || | 1652 Token::IsUnaryToken(token_kind) || |
1788 Token::IsIndexOperator(token_kind) || | 1653 Token::IsIndexOperator(token_kind) || |
1789 token_kind == Token::kGET || | 1654 token_kind == Token::kGET || |
1790 token_kind == Token::kSET || | 1655 token_kind == Token::kSET || |
1791 token_kind == Token::kILLEGAL); | 1656 token_kind == Token::kILLEGAL); |
1792 } | 1657 } |
1793 | 1658 |
1794 DECLARE_CALL_COMPUTATION(InstanceCall) | 1659 DECLARE_INSTRUCTION(InstanceCall) |
| 1660 virtual RawAbstractType* CompileType() const; |
1795 | 1661 |
1796 const ICData* ic_data() const { return ic_data_; } | 1662 const ICData* ic_data() const { return ic_data_; } |
1797 bool HasICData() const { | 1663 bool HasICData() const { |
1798 return (ic_data() != NULL) && !ic_data()->IsNull(); | 1664 return (ic_data() != NULL) && !ic_data()->IsNull(); |
1799 } | 1665 } |
1800 | 1666 |
1801 intptr_t token_pos() const { return token_pos_; } | 1667 intptr_t token_pos() const { return token_pos_; } |
1802 const String& function_name() const { return function_name_; } | 1668 const String& function_name() const { return function_name_; } |
1803 Token::Kind token_kind() const { return token_kind_; } | 1669 Token::Kind token_kind() const { return token_kind_; } |
1804 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 1670 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
(...skipping 10 matching lines...) Expand all Loading... |
1815 | 1681 |
1816 private: | 1682 private: |
1817 const ICData* ic_data_; | 1683 const ICData* ic_data_; |
1818 const intptr_t token_pos_; | 1684 const intptr_t token_pos_; |
1819 const String& function_name_; | 1685 const String& function_name_; |
1820 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL. | 1686 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL. |
1821 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; | 1687 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; |
1822 const Array& argument_names_; | 1688 const Array& argument_names_; |
1823 const intptr_t checked_argument_count_; | 1689 const intptr_t checked_argument_count_; |
1824 | 1690 |
1825 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); | 1691 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); |
1826 }; | 1692 }; |
1827 | 1693 |
1828 | 1694 |
1829 class PolymorphicInstanceCallComp : public TemplateComputation<0> { | 1695 class PolymorphicInstanceCallInstr : public TemplateDefinition<0> { |
1830 public: | 1696 public: |
1831 PolymorphicInstanceCallComp(InstanceCallComp* comp, | 1697 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, |
1832 const ICData& ic_data, | 1698 const ICData& ic_data, |
1833 bool with_checks) | 1699 bool with_checks) |
1834 : instance_call_(comp), ic_data_(ic_data), with_checks_(with_checks) { | 1700 : instance_call_(instance_call), |
| 1701 ic_data_(ic_data), |
| 1702 with_checks_(with_checks) { |
1835 ASSERT(instance_call_ != NULL); | 1703 ASSERT(instance_call_ != NULL); |
1836 } | 1704 } |
1837 | 1705 |
1838 InstanceCallComp* instance_call() const { return instance_call_; } | 1706 InstanceCallInstr* instance_call() const { return instance_call_; } |
1839 bool with_checks() const { return with_checks_; } | 1707 bool with_checks() const { return with_checks_; } |
1840 | 1708 |
1841 void PrintTo(BufferFormatter* f) const; | |
1842 | |
1843 virtual intptr_t ArgumentCount() const { | 1709 virtual intptr_t ArgumentCount() const { |
1844 return instance_call()->ArgumentCount(); | 1710 return instance_call()->ArgumentCount(); |
1845 } | 1711 } |
1846 | 1712 |
1847 DECLARE_CALL_COMPUTATION(PolymorphicInstanceCall) | 1713 DECLARE_INSTRUCTION(PolymorphicInstanceCall) |
| 1714 virtual RawAbstractType* CompileType() const; |
1848 | 1715 |
1849 const ICData& ic_data() const { return ic_data_; } | 1716 const ICData& ic_data() const { return ic_data_; } |
1850 | 1717 |
1851 virtual bool CanDeoptimize() const { return true; } | 1718 virtual bool CanDeoptimize() const { return true; } |
1852 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1719 virtual intptr_t ResultCid() const { return kDynamicCid; } |
1853 | 1720 |
| 1721 virtual void PrintTo(BufferFormatter* f) const; |
| 1722 |
1854 private: | 1723 private: |
1855 InstanceCallComp* instance_call_; | 1724 InstanceCallInstr* instance_call_; |
1856 const ICData& ic_data_; | 1725 const ICData& ic_data_; |
1857 const bool with_checks_; | 1726 const bool with_checks_; |
1858 | 1727 |
1859 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); | 1728 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
1860 }; | 1729 }; |
1861 | 1730 |
1862 | 1731 |
1863 class ComparisonComp : public TemplateComputation<2> { | 1732 class ComparisonInstr : public TemplateDefinition<2> { |
1864 public: | 1733 public: |
1865 ComparisonComp(Token::Kind kind, Value* left, Value* right) : kind_(kind) { | 1734 ComparisonInstr(Token::Kind kind, Value* left, Value* right) : kind_(kind) { |
1866 ASSERT(left != NULL); | 1735 ASSERT(left != NULL); |
1867 ASSERT(right != NULL); | 1736 ASSERT(right != NULL); |
1868 inputs_[0] = left; | 1737 inputs_[0] = left; |
1869 inputs_[1] = right; | 1738 inputs_[1] = right; |
1870 } | 1739 } |
1871 | 1740 |
1872 Value* left() const { return inputs_[0]; } | 1741 Value* left() const { return inputs_[0]; } |
1873 Value* right() const { return inputs_[1]; } | 1742 Value* right() const { return inputs_[1]; } |
1874 | 1743 |
1875 virtual ComparisonComp* AsComparison() { return this; } | 1744 virtual ComparisonInstr* AsComparison() { return this; } |
1876 | 1745 |
1877 Token::Kind kind() const { return kind_; } | 1746 Token::Kind kind() const { return kind_; } |
1878 | 1747 |
| 1748 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 1749 BranchInstr* branch) = 0; |
| 1750 |
1879 private: | 1751 private: |
1880 Token::Kind kind_; | 1752 Token::Kind kind_; |
1881 }; | 1753 }; |
1882 | 1754 |
1883 | 1755 |
1884 // Inlined functions from class BranchInstr that forward to their comparison. | 1756 // Inlined functions from class BranchInstr that forward to their comparison. |
1885 inline intptr_t BranchInstr::ArgumentCount() const { | 1757 inline intptr_t BranchInstr::ArgumentCount() const { |
1886 return computation()->ArgumentCount(); | 1758 return comparison()->ArgumentCount(); |
1887 } | 1759 } |
1888 | 1760 |
1889 | 1761 |
1890 inline intptr_t BranchInstr::InputCount() const { | 1762 inline intptr_t BranchInstr::InputCount() const { |
1891 return computation()->InputCount(); | 1763 return comparison()->InputCount(); |
1892 } | 1764 } |
1893 | 1765 |
1894 | 1766 |
1895 inline Value* BranchInstr::InputAt(intptr_t i) const { | 1767 inline Value* BranchInstr::InputAt(intptr_t i) const { |
1896 return computation()->InputAt(i); | 1768 return comparison()->InputAt(i); |
1897 } | 1769 } |
1898 | 1770 |
1899 | 1771 |
1900 inline void BranchInstr::SetInputAt(intptr_t i, Value* value) { | 1772 inline void BranchInstr::SetInputAt(intptr_t i, Value* value) { |
1901 computation()->SetInputAt(i, value); | 1773 comparison()->SetInputAt(i, value); |
1902 } | 1774 } |
1903 | 1775 |
1904 | 1776 |
1905 inline bool BranchInstr::CanDeoptimize() const { | 1777 inline bool BranchInstr::CanDeoptimize() const { |
1906 return computation()->CanDeoptimize(); | 1778 return comparison()->CanDeoptimize(); |
1907 } | 1779 } |
1908 | 1780 |
1909 | 1781 |
1910 inline LocationSummary* BranchInstr::locs() { | 1782 inline LocationSummary* BranchInstr::locs() { |
1911 if (computation_->locs_ == NULL) { | 1783 if (comparison()->locs_ == NULL) { |
1912 LocationSummary* summary = computation_->MakeLocationSummary(); | 1784 LocationSummary* summary = comparison()->MakeLocationSummary(); |
1913 // Branches don't produce a result. | 1785 // Branches don't produce a result. |
1914 summary->set_out(Location::NoLocation()); | 1786 summary->set_out(Location::NoLocation()); |
1915 computation_->locs_ = summary; | 1787 comparison()->locs_ = summary; |
1916 } | 1788 } |
1917 return computation_->locs_; | 1789 return comparison()->locs_; |
1918 } | 1790 } |
1919 | 1791 |
1920 | 1792 |
1921 inline intptr_t BranchInstr::DeoptimizationTarget() const { | 1793 inline intptr_t BranchInstr::DeoptimizationTarget() const { |
1922 return computation_->DeoptimizationTarget(); | 1794 return comparison()->DeoptimizationTarget(); |
1923 } | 1795 } |
1924 | 1796 |
1925 | 1797 |
1926 inline Representation BranchInstr::RequiredInputRepresentation( | 1798 inline Representation BranchInstr::RequiredInputRepresentation( |
1927 intptr_t i) const { | 1799 intptr_t i) const { |
1928 return computation()->RequiredInputRepresentation(i); | 1800 return comparison()->RequiredInputRepresentation(i); |
1929 } | 1801 } |
1930 | 1802 |
1931 | 1803 |
1932 class StrictCompareComp : public ComparisonComp { | 1804 class StrictCompareInstr : public ComparisonInstr { |
1933 public: | 1805 public: |
1934 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 1806 StrictCompareInstr(Token::Kind kind, Value* left, Value* right) |
1935 : ComparisonComp(kind, left, right) { | 1807 : ComparisonInstr(kind, left, right) { |
1936 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 1808 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); |
1937 } | 1809 } |
1938 | 1810 |
1939 DECLARE_COMPUTATION(StrictCompare) | 1811 DECLARE_INSTRUCTION(StrictCompare) |
| 1812 virtual RawAbstractType* CompileType() const; |
1940 | 1813 |
1941 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1814 virtual void PrintOperandsTo(BufferFormatter* f) const; |
1942 | 1815 |
1943 virtual bool CanDeoptimize() const { return false; } | 1816 virtual bool CanDeoptimize() const { return false; } |
1944 | 1817 |
1945 virtual Definition* TryReplace(BindInstr* instr) const; | 1818 virtual Definition* Canonicalize(); |
1946 | 1819 |
1947 virtual intptr_t ResultCid() const { return kBoolCid; } | 1820 virtual intptr_t ResultCid() const { return kBoolCid; } |
1948 | 1821 |
1949 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 1822 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
1950 BranchInstr* branch); | 1823 BranchInstr* branch); |
1951 | 1824 |
1952 private: | 1825 private: |
1953 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 1826 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr); |
1954 }; | 1827 }; |
1955 | 1828 |
1956 | 1829 |
1957 class EqualityCompareComp : public ComparisonComp { | 1830 class EqualityCompareInstr : public ComparisonInstr { |
1958 public: | 1831 public: |
1959 EqualityCompareComp(intptr_t token_pos, | 1832 EqualityCompareInstr(intptr_t token_pos, |
1960 Token::Kind kind, | 1833 Token::Kind kind, |
1961 Value* left, | 1834 Value* left, |
1962 Value* right) | 1835 Value* right) |
1963 : ComparisonComp(kind, left, right), | 1836 : ComparisonInstr(kind, left, right), |
1964 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 1837 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), |
1965 token_pos_(token_pos), | 1838 token_pos_(token_pos), |
1966 receiver_class_id_(kIllegalCid) { | 1839 receiver_class_id_(kIllegalCid) { |
1967 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 1840 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
1968 } | 1841 } |
1969 | 1842 |
1970 DECLARE_COMPUTATION(EqualityCompare) | 1843 DECLARE_INSTRUCTION(EqualityCompare) |
| 1844 virtual RawAbstractType* CompileType() const; |
1971 | 1845 |
1972 const ICData* ic_data() const { return ic_data_; } | 1846 const ICData* ic_data() const { return ic_data_; } |
1973 bool HasICData() const { | 1847 bool HasICData() const { |
1974 return (ic_data() != NULL) && !ic_data()->IsNull(); | 1848 return (ic_data() != NULL) && !ic_data()->IsNull(); |
1975 } | 1849 } |
1976 | 1850 |
1977 intptr_t token_pos() const { return token_pos_; } | 1851 intptr_t token_pos() const { return token_pos_; } |
1978 | 1852 |
1979 // Receiver class id is computed from collected ICData. | 1853 // Receiver class id is computed from collected ICData. |
1980 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | 1854 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } |
(...skipping 18 matching lines...) Expand all Loading... |
1999 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 1873 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
2000 ASSERT((idx == 0) || (idx == 1)); | 1874 ASSERT((idx == 0) || (idx == 1)); |
2001 return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; | 1875 return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; |
2002 } | 1876 } |
2003 | 1877 |
2004 private: | 1878 private: |
2005 const ICData* ic_data_; | 1879 const ICData* ic_data_; |
2006 const intptr_t token_pos_; | 1880 const intptr_t token_pos_; |
2007 intptr_t receiver_class_id_; // Set by optimizer. | 1881 intptr_t receiver_class_id_; // Set by optimizer. |
2008 | 1882 |
2009 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 1883 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); |
2010 }; | 1884 }; |
2011 | 1885 |
2012 | 1886 |
2013 class RelationalOpComp : public ComparisonComp { | 1887 class RelationalOpInstr : public ComparisonInstr { |
2014 public: | 1888 public: |
2015 RelationalOpComp(intptr_t token_pos, | 1889 RelationalOpInstr(intptr_t token_pos, |
2016 Token::Kind kind, | 1890 Token::Kind kind, |
2017 Value* left, | 1891 Value* left, |
2018 Value* right) | 1892 Value* right) |
2019 : ComparisonComp(kind, left, right), | 1893 : ComparisonInstr(kind, left, right), |
2020 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), | 1894 ic_data_(Isolate::Current()->GetICDataForDeoptId(deopt_id())), |
2021 token_pos_(token_pos), | 1895 token_pos_(token_pos), |
2022 operands_class_id_(kIllegalCid) { | 1896 operands_class_id_(kIllegalCid) { |
2023 ASSERT(Token::IsRelationalOperator(kind)); | 1897 ASSERT(Token::IsRelationalOperator(kind)); |
2024 } | 1898 } |
2025 | 1899 |
2026 DECLARE_COMPUTATION(RelationalOp) | 1900 DECLARE_INSTRUCTION(RelationalOp) |
| 1901 virtual RawAbstractType* CompileType() const; |
2027 | 1902 |
2028 const ICData* ic_data() const { return ic_data_; } | 1903 const ICData* ic_data() const { return ic_data_; } |
2029 bool HasICData() const { | 1904 bool HasICData() const { |
2030 return (ic_data() != NULL) && !ic_data()->IsNull(); | 1905 return (ic_data() != NULL) && !ic_data()->IsNull(); |
2031 } | 1906 } |
2032 | 1907 |
2033 intptr_t token_pos() const { return token_pos_; } | 1908 intptr_t token_pos() const { return token_pos_; } |
2034 | 1909 |
2035 // TODO(srdjan): instead of class-id pass an enum that can differentiate | 1910 // TODO(srdjan): instead of class-id pass an enum that can differentiate |
2036 // between boxed and unboxed doubles and integers. | 1911 // between boxed and unboxed doubles and integers. |
(...skipping 23 matching lines...) Expand all Loading... |
2060 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 1935 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
2061 ASSERT((idx == 0) || (idx == 1)); | 1936 ASSERT((idx == 0) || (idx == 1)); |
2062 return (operands_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; | 1937 return (operands_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; |
2063 } | 1938 } |
2064 | 1939 |
2065 private: | 1940 private: |
2066 const ICData* ic_data_; | 1941 const ICData* ic_data_; |
2067 const intptr_t token_pos_; | 1942 const intptr_t token_pos_; |
2068 intptr_t operands_class_id_; // class id of both operands. | 1943 intptr_t operands_class_id_; // class id of both operands. |
2069 | 1944 |
2070 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); | 1945 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); |
2071 }; | 1946 }; |
2072 | 1947 |
2073 | 1948 |
2074 class StaticCallComp : public TemplateComputation<0> { | 1949 class StaticCallInstr : public TemplateDefinition<0> { |
2075 public: | 1950 public: |
2076 StaticCallComp(intptr_t token_pos, | 1951 StaticCallInstr(intptr_t token_pos, |
2077 const Function& function, | 1952 const Function& function, |
2078 const Array& argument_names, | 1953 const Array& argument_names, |
2079 ZoneGrowableArray<PushArgumentInstr*>* arguments) | 1954 ZoneGrowableArray<PushArgumentInstr*>* arguments) |
2080 : token_pos_(token_pos), | 1955 : token_pos_(token_pos), |
2081 function_(function), | 1956 function_(function), |
2082 argument_names_(argument_names), | 1957 argument_names_(argument_names), |
2083 arguments_(arguments), | 1958 arguments_(arguments), |
2084 recognized_(MethodRecognizer::kUnknown) { | 1959 recognized_(MethodRecognizer::kUnknown) { |
2085 ASSERT(function.IsZoneHandle()); | 1960 ASSERT(function.IsZoneHandle()); |
2086 ASSERT(argument_names.IsZoneHandle()); | 1961 ASSERT(argument_names.IsZoneHandle()); |
2087 } | 1962 } |
2088 | 1963 |
2089 DECLARE_CALL_COMPUTATION(StaticCall) | 1964 DECLARE_INSTRUCTION(StaticCall) |
| 1965 virtual RawAbstractType* CompileType() const; |
2090 | 1966 |
2091 // Accessors forwarded to the AST node. | 1967 // Accessors forwarded to the AST node. |
2092 const Function& function() const { return function_; } | 1968 const Function& function() const { return function_; } |
2093 const Array& argument_names() const { return argument_names_; } | 1969 const Array& argument_names() const { return argument_names_; } |
2094 intptr_t token_pos() const { return token_pos_; } | 1970 intptr_t token_pos() const { return token_pos_; } |
2095 | 1971 |
2096 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 1972 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2097 PushArgumentInstr* ArgumentAt(intptr_t index) const { | 1973 PushArgumentInstr* ArgumentAt(intptr_t index) const { |
2098 return (*arguments_)[index]; | 1974 return (*arguments_)[index]; |
2099 } | 1975 } |
2100 | 1976 |
2101 MethodRecognizer::Kind recognized() const { return recognized_; } | 1977 MethodRecognizer::Kind recognized() const { return recognized_; } |
2102 void set_recognized(MethodRecognizer::Kind kind) { recognized_ = kind; } | 1978 void set_recognized(MethodRecognizer::Kind kind) { recognized_ = kind; } |
2103 | 1979 |
2104 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1980 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2105 | 1981 |
2106 virtual bool CanDeoptimize() const { return true; } | 1982 virtual bool CanDeoptimize() const { return true; } |
2107 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1983 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2108 | 1984 |
2109 private: | 1985 private: |
2110 const intptr_t token_pos_; | 1986 const intptr_t token_pos_; |
2111 const Function& function_; | 1987 const Function& function_; |
2112 const Array& argument_names_; | 1988 const Array& argument_names_; |
2113 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 1989 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
2114 MethodRecognizer::Kind recognized_; | 1990 MethodRecognizer::Kind recognized_; |
2115 | 1991 |
2116 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); | 1992 DISALLOW_COPY_AND_ASSIGN(StaticCallInstr); |
2117 }; | 1993 }; |
2118 | 1994 |
2119 | 1995 |
2120 class LoadLocalComp : public TemplateComputation<0> { | 1996 class LoadLocalInstr : public TemplateDefinition<0> { |
2121 public: | 1997 public: |
2122 LoadLocalComp(const LocalVariable& local, intptr_t context_level) | 1998 LoadLocalInstr(const LocalVariable& local, intptr_t context_level) |
2123 : local_(local), | 1999 : local_(local), |
2124 context_level_(context_level) { } | 2000 context_level_(context_level) { } |
2125 | 2001 |
2126 DECLARE_COMPUTATION(LoadLocal) | 2002 DECLARE_INSTRUCTION(LoadLocal) |
| 2003 virtual RawAbstractType* CompileType() const; |
2127 | 2004 |
2128 const LocalVariable& local() const { return local_; } | 2005 const LocalVariable& local() const { return local_; } |
2129 intptr_t context_level() const { return context_level_; } | 2006 intptr_t context_level() const { return context_level_; } |
2130 | 2007 |
2131 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2008 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2132 | 2009 |
2133 virtual bool CanDeoptimize() const { return false; } | 2010 virtual bool CanDeoptimize() const { return false; } |
2134 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2011 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2135 | 2012 |
2136 private: | 2013 private: |
2137 const LocalVariable& local_; | 2014 const LocalVariable& local_; |
2138 const intptr_t context_level_; | 2015 const intptr_t context_level_; |
2139 | 2016 |
2140 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); | 2017 DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr); |
2141 }; | 2018 }; |
2142 | 2019 |
2143 | 2020 |
2144 class StoreLocalComp : public TemplateComputation<1> { | 2021 class StoreLocalInstr : public TemplateDefinition<1> { |
2145 public: | 2022 public: |
2146 StoreLocalComp(const LocalVariable& local, | 2023 StoreLocalInstr(const LocalVariable& local, |
2147 Value* value, | 2024 Value* value, |
2148 intptr_t context_level) | 2025 intptr_t context_level) |
2149 : local_(local), | 2026 : local_(local), |
2150 context_level_(context_level) { | 2027 context_level_(context_level) { |
2151 ASSERT(value != NULL); | 2028 ASSERT(value != NULL); |
2152 inputs_[0] = value; | 2029 inputs_[0] = value; |
2153 } | 2030 } |
2154 | 2031 |
2155 DECLARE_COMPUTATION(StoreLocal) | 2032 DECLARE_INSTRUCTION(StoreLocal) |
| 2033 virtual RawAbstractType* CompileType() const; |
2156 | 2034 |
2157 const LocalVariable& local() const { return local_; } | 2035 const LocalVariable& local() const { return local_; } |
2158 Value* value() const { return inputs_[0]; } | 2036 Value* value() const { return inputs_[0]; } |
2159 intptr_t context_level() const { return context_level_; } | 2037 intptr_t context_level() const { return context_level_; } |
2160 | 2038 |
2161 virtual void RecordAssignedVars(BitVector* assigned_vars, | 2039 virtual void RecordAssignedVars(BitVector* assigned_vars, |
2162 intptr_t fixed_parameter_count); | 2040 intptr_t fixed_parameter_count); |
2163 | 2041 |
2164 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2042 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2165 | 2043 |
2166 virtual bool CanDeoptimize() const { return false; } | 2044 virtual bool CanDeoptimize() const { return false; } |
2167 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2045 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2168 | 2046 |
2169 private: | 2047 private: |
2170 const LocalVariable& local_; | 2048 const LocalVariable& local_; |
2171 const intptr_t context_level_; | 2049 const intptr_t context_level_; |
2172 | 2050 |
2173 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); | 2051 DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr); |
2174 }; | 2052 }; |
2175 | 2053 |
2176 | 2054 |
2177 class NativeCallComp : public TemplateComputation<0> { | 2055 class NativeCallInstr : public TemplateDefinition<0> { |
2178 public: | 2056 public: |
2179 explicit NativeCallComp(NativeBodyNode* node) | 2057 explicit NativeCallInstr(NativeBodyNode* node) |
2180 : ast_node_(*node) {} | 2058 : ast_node_(*node) {} |
2181 | 2059 |
2182 DECLARE_COMPUTATION(NativeCall) | 2060 DECLARE_INSTRUCTION(NativeCall) |
| 2061 virtual RawAbstractType* CompileType() const; |
2183 | 2062 |
2184 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2063 intptr_t token_pos() const { return ast_node_.token_pos(); } |
2185 | 2064 |
2186 const String& native_name() const { | 2065 const String& native_name() const { |
2187 return ast_node_.native_c_function_name(); | 2066 return ast_node_.native_c_function_name(); |
2188 } | 2067 } |
2189 | 2068 |
2190 NativeFunction native_c_function() const { | 2069 NativeFunction native_c_function() const { |
2191 return ast_node_.native_c_function(); | 2070 return ast_node_.native_c_function(); |
2192 } | 2071 } |
2193 | 2072 |
2194 intptr_t argument_count() const { return ast_node_.argument_count(); } | 2073 intptr_t argument_count() const { return ast_node_.argument_count(); } |
2195 | 2074 |
2196 bool has_optional_parameters() const { | 2075 bool has_optional_parameters() const { |
2197 return ast_node_.has_optional_parameters(); | 2076 return ast_node_.has_optional_parameters(); |
2198 } | 2077 } |
2199 | 2078 |
2200 bool is_native_instance_closure() const { | 2079 bool is_native_instance_closure() const { |
2201 return ast_node_.is_native_instance_closure(); | 2080 return ast_node_.is_native_instance_closure(); |
2202 } | 2081 } |
2203 | 2082 |
2204 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2083 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2205 | 2084 |
2206 virtual bool CanDeoptimize() const { return false; } | 2085 virtual bool CanDeoptimize() const { return false; } |
2207 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2086 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2208 | 2087 |
2209 private: | 2088 private: |
2210 const NativeBodyNode& ast_node_; | 2089 const NativeBodyNode& ast_node_; |
2211 | 2090 |
2212 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); | 2091 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); |
2213 }; | 2092 }; |
2214 | 2093 |
2215 | 2094 |
2216 class LoadInstanceFieldComp : public TemplateComputation<1> { | 2095 class LoadInstanceFieldInstr : public TemplateDefinition<1> { |
2217 public: | 2096 public: |
2218 LoadInstanceFieldComp(const Field& field, Value* instance) : field_(field) { | 2097 LoadInstanceFieldInstr(const Field& field, Value* instance) : field_(field) { |
2219 ASSERT(instance != NULL); | 2098 ASSERT(instance != NULL); |
2220 inputs_[0] = instance; | 2099 inputs_[0] = instance; |
2221 } | 2100 } |
2222 | 2101 |
2223 DECLARE_COMPUTATION(LoadInstanceField) | 2102 DECLARE_INSTRUCTION(LoadInstanceField) |
| 2103 virtual RawAbstractType* CompileType() const; |
2224 | 2104 |
2225 const Field& field() const { return field_; } | 2105 const Field& field() const { return field_; } |
2226 Value* instance() const { return inputs_[0]; } | 2106 Value* instance() const { return inputs_[0]; } |
2227 | 2107 |
2228 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2108 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2229 | 2109 |
2230 virtual bool CanDeoptimize() const { return false; } | 2110 virtual bool CanDeoptimize() const { return false; } |
2231 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2111 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2232 | 2112 |
2233 private: | 2113 private: |
2234 const Field& field_; | 2114 const Field& field_; |
2235 | 2115 |
2236 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 2116 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldInstr); |
2237 }; | 2117 }; |
2238 | 2118 |
2239 | 2119 |
2240 class StoreInstanceFieldComp : public TemplateComputation<2> { | 2120 class StoreInstanceFieldInstr : public TemplateDefinition<2> { |
2241 public: | 2121 public: |
2242 StoreInstanceFieldComp(const Field& field, | 2122 StoreInstanceFieldInstr(const Field& field, Value* instance, Value* value) |
2243 Value* instance, | |
2244 Value* value) | |
2245 : field_(field) { | 2123 : field_(field) { |
2246 ASSERT(instance != NULL); | 2124 ASSERT(instance != NULL); |
2247 ASSERT(value != NULL); | 2125 ASSERT(value != NULL); |
2248 inputs_[0] = instance; | 2126 inputs_[0] = instance; |
2249 inputs_[1] = value; | 2127 inputs_[1] = value; |
2250 } | 2128 } |
2251 | 2129 |
2252 DECLARE_COMPUTATION(StoreInstanceField) | 2130 DECLARE_INSTRUCTION(StoreInstanceField) |
| 2131 virtual RawAbstractType* CompileType() const; |
2253 | 2132 |
2254 const Field& field() const { return field_; } | 2133 const Field& field() const { return field_; } |
2255 | 2134 |
2256 Value* instance() const { return inputs_[0]; } | 2135 Value* instance() const { return inputs_[0]; } |
2257 Value* value() const { return inputs_[1]; } | 2136 Value* value() const { return inputs_[1]; } |
2258 | 2137 |
2259 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2138 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2260 | 2139 |
2261 virtual bool CanDeoptimize() const { return false; } | 2140 virtual bool CanDeoptimize() const { return false; } |
2262 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2141 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2263 | 2142 |
2264 private: | 2143 private: |
2265 const Field& field_; | 2144 const Field& field_; |
2266 | 2145 |
2267 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); | 2146 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); |
2268 }; | 2147 }; |
2269 | 2148 |
2270 | 2149 |
2271 class LoadStaticFieldComp : public TemplateComputation<0> { | 2150 class LoadStaticFieldInstr : public TemplateDefinition<0> { |
2272 public: | 2151 public: |
2273 explicit LoadStaticFieldComp(const Field& field) : field_(field) {} | 2152 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} |
2274 | 2153 |
2275 DECLARE_COMPUTATION(LoadStaticField); | 2154 DECLARE_INSTRUCTION(LoadStaticField); |
| 2155 virtual RawAbstractType* CompileType() const; |
2276 | 2156 |
2277 const Field& field() const { return field_; } | 2157 const Field& field() const { return field_; } |
2278 | 2158 |
2279 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2159 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2280 | 2160 |
2281 virtual bool CanDeoptimize() const { return false; } | 2161 virtual bool CanDeoptimize() const { return false; } |
2282 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2162 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2283 | 2163 |
2284 private: | 2164 private: |
2285 const Field& field_; | 2165 const Field& field_; |
2286 | 2166 |
2287 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldComp); | 2167 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr); |
2288 }; | 2168 }; |
2289 | 2169 |
2290 | 2170 |
2291 class StoreStaticFieldComp : public TemplateComputation<1> { | 2171 class StoreStaticFieldInstr : public TemplateDefinition<1> { |
2292 public: | 2172 public: |
2293 StoreStaticFieldComp(const Field& field, Value* value) | 2173 StoreStaticFieldInstr(const Field& field, Value* value) |
2294 : field_(field) { | 2174 : field_(field) { |
2295 ASSERT(field.IsZoneHandle()); | 2175 ASSERT(field.IsZoneHandle()); |
2296 ASSERT(value != NULL); | 2176 ASSERT(value != NULL); |
2297 inputs_[0] = value; | 2177 inputs_[0] = value; |
2298 } | 2178 } |
2299 | 2179 |
2300 DECLARE_COMPUTATION(StoreStaticField); | 2180 DECLARE_INSTRUCTION(StoreStaticField); |
| 2181 virtual RawAbstractType* CompileType() const; |
2301 | 2182 |
2302 const Field& field() const { return field_; } | 2183 const Field& field() const { return field_; } |
2303 Value* value() const { return inputs_[0]; } | 2184 Value* value() const { return inputs_[0]; } |
2304 | 2185 |
2305 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2186 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2306 | 2187 |
2307 virtual bool CanDeoptimize() const { return false; } | 2188 virtual bool CanDeoptimize() const { return false; } |
2308 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2189 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2309 | 2190 |
2310 private: | 2191 private: |
2311 const Field& field_; | 2192 const Field& field_; |
2312 | 2193 |
2313 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); | 2194 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr); |
2314 }; | 2195 }; |
2315 | 2196 |
2316 | 2197 |
2317 class LoadIndexedComp : public TemplateComputation<2> { | 2198 class LoadIndexedInstr : public TemplateDefinition<2> { |
2318 public: | 2199 public: |
2319 LoadIndexedComp(Value* array, | 2200 LoadIndexedInstr(Value* array, Value* index, intptr_t receiver_type) |
2320 Value* index, | |
2321 intptr_t receiver_type) | |
2322 : receiver_type_(receiver_type) { | 2201 : receiver_type_(receiver_type) { |
2323 ASSERT(array != NULL); | 2202 ASSERT(array != NULL); |
2324 ASSERT(index != NULL); | 2203 ASSERT(index != NULL); |
2325 inputs_[0] = array; | 2204 inputs_[0] = array; |
2326 inputs_[1] = index; | 2205 inputs_[1] = index; |
2327 } | 2206 } |
2328 | 2207 |
2329 DECLARE_COMPUTATION(LoadIndexed) | 2208 DECLARE_INSTRUCTION(LoadIndexed) |
| 2209 virtual RawAbstractType* CompileType() const; |
2330 | 2210 |
2331 Value* array() const { return inputs_[0]; } | 2211 Value* array() const { return inputs_[0]; } |
2332 Value* index() const { return inputs_[1]; } | 2212 Value* index() const { return inputs_[1]; } |
2333 | 2213 |
2334 intptr_t receiver_type() const { return receiver_type_; } | 2214 intptr_t receiver_type() const { return receiver_type_; } |
2335 | 2215 |
2336 virtual bool CanDeoptimize() const { return false; } | 2216 virtual bool CanDeoptimize() const { return false; } |
2337 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2217 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2338 | 2218 |
2339 private: | 2219 private: |
2340 intptr_t receiver_type_; | 2220 intptr_t receiver_type_; |
2341 | 2221 |
2342 DISALLOW_COPY_AND_ASSIGN(LoadIndexedComp); | 2222 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); |
2343 }; | 2223 }; |
2344 | 2224 |
2345 | 2225 |
2346 class StoreIndexedComp : public TemplateComputation<3> { | 2226 class StoreIndexedInstr : public TemplateDefinition<3> { |
2347 public: | 2227 public: |
2348 StoreIndexedComp(Value* array, | 2228 StoreIndexedInstr(Value* array, |
2349 Value* index, | 2229 Value* index, |
2350 Value* value, | 2230 Value* value, |
2351 intptr_t receiver_type) | 2231 intptr_t receiver_type) |
2352 : receiver_type_(receiver_type) { | 2232 : receiver_type_(receiver_type) { |
2353 ASSERT(array != NULL); | 2233 ASSERT(array != NULL); |
2354 ASSERT(index != NULL); | 2234 ASSERT(index != NULL); |
2355 ASSERT(value != NULL); | 2235 ASSERT(value != NULL); |
2356 inputs_[0] = array; | 2236 inputs_[0] = array; |
2357 inputs_[1] = index; | 2237 inputs_[1] = index; |
2358 inputs_[2] = value; | 2238 inputs_[2] = value; |
2359 } | 2239 } |
2360 | 2240 |
2361 DECLARE_COMPUTATION(StoreIndexed) | 2241 DECLARE_INSTRUCTION(StoreIndexed) |
| 2242 virtual RawAbstractType* CompileType() const; |
2362 | 2243 |
2363 Value* array() const { return inputs_[0]; } | 2244 Value* array() const { return inputs_[0]; } |
2364 Value* index() const { return inputs_[1]; } | 2245 Value* index() const { return inputs_[1]; } |
2365 Value* value() const { return inputs_[2]; } | 2246 Value* value() const { return inputs_[2]; } |
2366 | 2247 |
2367 intptr_t receiver_type() const { return receiver_type_; } | 2248 intptr_t receiver_type() const { return receiver_type_; } |
2368 | 2249 |
2369 virtual bool CanDeoptimize() const { return false; } | 2250 virtual bool CanDeoptimize() const { return false; } |
2370 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2251 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2371 | 2252 |
2372 private: | 2253 private: |
2373 intptr_t receiver_type_; | 2254 intptr_t receiver_type_; |
2374 | 2255 |
2375 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); | 2256 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); |
2376 }; | 2257 }; |
2377 | 2258 |
2378 | 2259 |
2379 // Note overrideable, built-in: value? false : true. | 2260 // Note overrideable, built-in: value? false : true. |
2380 class BooleanNegateComp : public TemplateComputation<1> { | 2261 class BooleanNegateInstr : public TemplateDefinition<1> { |
2381 public: | 2262 public: |
2382 explicit BooleanNegateComp(Value* value) { | 2263 explicit BooleanNegateInstr(Value* value) { |
2383 ASSERT(value != NULL); | 2264 ASSERT(value != NULL); |
2384 inputs_[0] = value; | 2265 inputs_[0] = value; |
2385 } | 2266 } |
2386 | 2267 |
2387 DECLARE_COMPUTATION(BooleanNegate) | 2268 DECLARE_INSTRUCTION(BooleanNegate) |
| 2269 virtual RawAbstractType* CompileType() const; |
2388 | 2270 |
2389 Value* value() const { return inputs_[0]; } | 2271 Value* value() const { return inputs_[0]; } |
2390 | 2272 |
2391 virtual bool CanDeoptimize() const { return false; } | 2273 virtual bool CanDeoptimize() const { return false; } |
2392 virtual intptr_t ResultCid() const { return kBoolCid; } | 2274 virtual intptr_t ResultCid() const { return kBoolCid; } |
2393 | 2275 |
2394 private: | 2276 private: |
2395 DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); | 2277 DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr); |
2396 }; | 2278 }; |
2397 | 2279 |
2398 | 2280 |
2399 class InstanceOfComp : public TemplateComputation<3> { | 2281 class InstanceOfInstr : public TemplateDefinition<3> { |
2400 public: | 2282 public: |
2401 InstanceOfComp(intptr_t token_pos, | 2283 InstanceOfInstr(intptr_t token_pos, |
2402 Value* value, | 2284 Value* value, |
2403 Value* instantiator, | 2285 Value* instantiator, |
2404 Value* instantiator_type_arguments, | 2286 Value* instantiator_type_arguments, |
2405 const AbstractType& type, | 2287 const AbstractType& type, |
2406 bool negate_result) | 2288 bool negate_result) |
2407 : token_pos_(token_pos), | 2289 : token_pos_(token_pos), |
2408 type_(type), | 2290 type_(type), |
2409 negate_result_(negate_result) { | 2291 negate_result_(negate_result) { |
2410 ASSERT(value != NULL); | 2292 ASSERT(value != NULL); |
2411 ASSERT(instantiator != NULL); | 2293 ASSERT(instantiator != NULL); |
2412 ASSERT(instantiator_type_arguments != NULL); | 2294 ASSERT(instantiator_type_arguments != NULL); |
2413 ASSERT(!type.IsNull()); | 2295 ASSERT(!type.IsNull()); |
2414 inputs_[0] = value; | 2296 inputs_[0] = value; |
2415 inputs_[1] = instantiator; | 2297 inputs_[1] = instantiator; |
2416 inputs_[2] = instantiator_type_arguments; | 2298 inputs_[2] = instantiator_type_arguments; |
2417 } | 2299 } |
2418 | 2300 |
2419 DECLARE_COMPUTATION(InstanceOf) | 2301 DECLARE_INSTRUCTION(InstanceOf) |
| 2302 virtual RawAbstractType* CompileType() const; |
2420 | 2303 |
2421 Value* value() const { return inputs_[0]; } | 2304 Value* value() const { return inputs_[0]; } |
2422 Value* instantiator() const { return inputs_[1]; } | 2305 Value* instantiator() const { return inputs_[1]; } |
2423 Value* instantiator_type_arguments() const { return inputs_[2]; } | 2306 Value* instantiator_type_arguments() const { return inputs_[2]; } |
2424 | 2307 |
2425 bool negate_result() const { return negate_result_; } | 2308 bool negate_result() const { return negate_result_; } |
2426 const AbstractType& type() const { return type_; } | 2309 const AbstractType& type() const { return type_; } |
2427 intptr_t token_pos() const { return token_pos_; } | 2310 intptr_t token_pos() const { return token_pos_; } |
2428 | 2311 |
2429 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2312 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2430 | 2313 |
2431 virtual bool CanDeoptimize() const { return false; } | 2314 virtual bool CanDeoptimize() const { return false; } |
2432 virtual intptr_t ResultCid() const { return kBoolCid; } | 2315 virtual intptr_t ResultCid() const { return kBoolCid; } |
2433 | 2316 |
2434 private: | 2317 private: |
2435 const intptr_t token_pos_; | 2318 const intptr_t token_pos_; |
2436 Value* value_; | 2319 Value* value_; |
2437 Value* instantiator_; | 2320 Value* instantiator_; |
2438 Value* type_arguments_; | 2321 Value* type_arguments_; |
2439 const AbstractType& type_; | 2322 const AbstractType& type_; |
2440 const bool negate_result_; | 2323 const bool negate_result_; |
2441 | 2324 |
2442 DISALLOW_COPY_AND_ASSIGN(InstanceOfComp); | 2325 DISALLOW_COPY_AND_ASSIGN(InstanceOfInstr); |
2443 }; | 2326 }; |
2444 | 2327 |
2445 | 2328 |
2446 class AllocateObjectComp : public TemplateComputation<0> { | 2329 class AllocateObjectInstr : public TemplateDefinition<0> { |
2447 public: | 2330 public: |
2448 AllocateObjectComp(ConstructorCallNode* node, | 2331 AllocateObjectInstr(ConstructorCallNode* node, |
2449 ZoneGrowableArray<PushArgumentInstr*>* arguments) | 2332 ZoneGrowableArray<PushArgumentInstr*>* arguments) |
2450 : ast_node_(*node), arguments_(arguments) { | 2333 : ast_node_(*node), arguments_(arguments) { |
2451 // Either no arguments or one type-argument and one instantiator. | 2334 // Either no arguments or one type-argument and one instantiator. |
2452 ASSERT(arguments->is_empty() || (arguments->length() == 2)); | 2335 ASSERT(arguments->is_empty() || (arguments->length() == 2)); |
2453 } | 2336 } |
2454 | 2337 |
2455 DECLARE_CALL_COMPUTATION(AllocateObject) | 2338 DECLARE_INSTRUCTION(AllocateObject) |
| 2339 virtual RawAbstractType* CompileType() const; |
2456 | 2340 |
2457 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2341 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2458 PushArgumentInstr* ArgumentAt(intptr_t index) const { | 2342 PushArgumentInstr* ArgumentAt(intptr_t index) const { |
2459 return (*arguments_)[index]; | 2343 return (*arguments_)[index]; |
2460 } | 2344 } |
2461 | 2345 |
2462 const Function& constructor() const { return ast_node_.constructor(); } | 2346 const Function& constructor() const { return ast_node_.constructor(); } |
2463 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2347 intptr_t token_pos() const { return ast_node_.token_pos(); } |
2464 | 2348 |
2465 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2349 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2466 | 2350 |
2467 virtual bool CanDeoptimize() const { return false; } | 2351 virtual bool CanDeoptimize() const { return false; } |
2468 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2352 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2469 | 2353 |
2470 private: | 2354 private: |
2471 const ConstructorCallNode& ast_node_; | 2355 const ConstructorCallNode& ast_node_; |
2472 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; | 2356 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; |
2473 | 2357 |
2474 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); | 2358 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr); |
2475 }; | 2359 }; |
2476 | 2360 |
2477 | 2361 |
2478 class AllocateObjectWithBoundsCheckComp : public TemplateComputation<2> { | 2362 class AllocateObjectWithBoundsCheckInstr : public TemplateDefinition<2> { |
2479 public: | 2363 public: |
2480 AllocateObjectWithBoundsCheckComp(ConstructorCallNode* node, | 2364 AllocateObjectWithBoundsCheckInstr(ConstructorCallNode* node, |
2481 Value* type_arguments, | 2365 Value* type_arguments, |
2482 Value* instantiator) | 2366 Value* instantiator) |
2483 : ast_node_(*node) { | 2367 : ast_node_(*node) { |
2484 ASSERT(type_arguments != NULL); | 2368 ASSERT(type_arguments != NULL); |
2485 ASSERT(instantiator != NULL); | 2369 ASSERT(instantiator != NULL); |
2486 inputs_[0] = type_arguments; | 2370 inputs_[0] = type_arguments; |
2487 inputs_[1] = instantiator; | 2371 inputs_[1] = instantiator; |
2488 } | 2372 } |
2489 | 2373 |
2490 DECLARE_COMPUTATION(AllocateObjectWithBoundsCheck) | 2374 DECLARE_INSTRUCTION(AllocateObjectWithBoundsCheck) |
| 2375 virtual RawAbstractType* CompileType() const; |
2491 | 2376 |
2492 const Function& constructor() const { return ast_node_.constructor(); } | 2377 const Function& constructor() const { return ast_node_.constructor(); } |
2493 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2378 intptr_t token_pos() const { return ast_node_.token_pos(); } |
2494 | 2379 |
2495 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2380 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2496 | 2381 |
2497 virtual bool CanDeoptimize() const { return false; } | 2382 virtual bool CanDeoptimize() const { return false; } |
2498 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2383 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2499 | 2384 |
2500 private: | 2385 private: |
2501 const ConstructorCallNode& ast_node_; | 2386 const ConstructorCallNode& ast_node_; |
2502 | 2387 |
2503 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); | 2388 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckInstr); |
2504 }; | 2389 }; |
2505 | 2390 |
2506 | 2391 |
2507 class CreateArrayComp : public TemplateComputation<1> { | 2392 class CreateArrayInstr : public TemplateDefinition<1> { |
2508 public: | 2393 public: |
2509 CreateArrayComp(intptr_t token_pos, | 2394 CreateArrayInstr(intptr_t token_pos, |
2510 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 2395 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
2511 const AbstractType& type, | 2396 const AbstractType& type, |
2512 Value* element_type) | 2397 Value* element_type) |
2513 : token_pos_(token_pos), | 2398 : token_pos_(token_pos), |
2514 arguments_(arguments), | 2399 arguments_(arguments), |
2515 type_(type) { | 2400 type_(type) { |
2516 #if defined(DEBUG) | 2401 #if defined(DEBUG) |
2517 for (int i = 0; i < ArgumentCount(); ++i) { | 2402 for (int i = 0; i < ArgumentCount(); ++i) { |
2518 ASSERT(ArgumentAt(i) != NULL); | 2403 ASSERT(ArgumentAt(i) != NULL); |
2519 } | 2404 } |
2520 ASSERT(element_type != NULL); | 2405 ASSERT(element_type != NULL); |
2521 ASSERT(type_.IsZoneHandle()); | 2406 ASSERT(type_.IsZoneHandle()); |
2522 ASSERT(!type_.IsNull()); | 2407 ASSERT(!type_.IsNull()); |
2523 ASSERT(type_.IsFinalized()); | 2408 ASSERT(type_.IsFinalized()); |
2524 #endif | 2409 #endif |
2525 inputs_[0] = element_type; | 2410 inputs_[0] = element_type; |
2526 } | 2411 } |
2527 | 2412 |
2528 DECLARE_CALL_COMPUTATION(CreateArray) | 2413 DECLARE_INSTRUCTION(CreateArray) |
| 2414 virtual RawAbstractType* CompileType() const; |
2529 | 2415 |
2530 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2416 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2531 | 2417 |
2532 intptr_t token_pos() const { return token_pos_; } | 2418 intptr_t token_pos() const { return token_pos_; } |
2533 PushArgumentInstr* ArgumentAt(intptr_t i) const { return (*arguments_)[i]; } | 2419 PushArgumentInstr* ArgumentAt(intptr_t i) const { return (*arguments_)[i]; } |
2534 const AbstractType& type() const { return type_; } | 2420 const AbstractType& type() const { return type_; } |
2535 Value* element_type() const { return inputs_[0]; } | 2421 Value* element_type() const { return inputs_[0]; } |
2536 | 2422 |
2537 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2423 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2538 | 2424 |
2539 virtual bool CanDeoptimize() const { return false; } | 2425 virtual bool CanDeoptimize() const { return false; } |
2540 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2426 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2541 | 2427 |
2542 private: | 2428 private: |
2543 const intptr_t token_pos_; | 2429 const intptr_t token_pos_; |
2544 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; | 2430 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; |
2545 const AbstractType& type_; | 2431 const AbstractType& type_; |
2546 | 2432 |
2547 DISALLOW_COPY_AND_ASSIGN(CreateArrayComp); | 2433 DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr); |
2548 }; | 2434 }; |
2549 | 2435 |
2550 | 2436 |
2551 class CreateClosureComp : public TemplateComputation<0> { | 2437 class CreateClosureInstr : public TemplateDefinition<0> { |
2552 public: | 2438 public: |
2553 CreateClosureComp(ClosureNode* node, | 2439 CreateClosureInstr(ClosureNode* node, |
2554 ZoneGrowableArray<PushArgumentInstr*>* arguments) | 2440 ZoneGrowableArray<PushArgumentInstr*>* arguments) |
2555 : ast_node_(*node), | 2441 : ast_node_(*node), |
2556 arguments_(arguments) { } | 2442 arguments_(arguments) { } |
2557 | 2443 |
2558 DECLARE_CALL_COMPUTATION(CreateClosure) | 2444 DECLARE_INSTRUCTION(CreateClosure) |
| 2445 virtual RawAbstractType* CompileType() const; |
2559 | 2446 |
2560 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2447 intptr_t token_pos() const { return ast_node_.token_pos(); } |
2561 const Function& function() const { return ast_node_.function(); } | 2448 const Function& function() const { return ast_node_.function(); } |
2562 | 2449 |
2563 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2450 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2564 PushArgumentInstr* ArgumentAt(intptr_t index) const { | 2451 PushArgumentInstr* ArgumentAt(intptr_t index) const { |
2565 return (*arguments_)[index]; | 2452 return (*arguments_)[index]; |
2566 } | 2453 } |
2567 | 2454 |
2568 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2455 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2569 | 2456 |
2570 virtual bool CanDeoptimize() const { return false; } | 2457 virtual bool CanDeoptimize() const { return false; } |
2571 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2458 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2572 | 2459 |
2573 private: | 2460 private: |
2574 const ClosureNode& ast_node_; | 2461 const ClosureNode& ast_node_; |
2575 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 2462 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
2576 | 2463 |
2577 DISALLOW_COPY_AND_ASSIGN(CreateClosureComp); | 2464 DISALLOW_COPY_AND_ASSIGN(CreateClosureInstr); |
2578 }; | 2465 }; |
2579 | 2466 |
2580 | 2467 |
2581 class LoadVMFieldComp : public TemplateComputation<1> { | 2468 class LoadVMFieldInstr : public TemplateDefinition<1> { |
2582 public: | 2469 public: |
2583 LoadVMFieldComp(Value* value, | 2470 LoadVMFieldInstr(Value* value, |
2584 intptr_t offset_in_bytes, | 2471 intptr_t offset_in_bytes, |
2585 const AbstractType& type) | 2472 const AbstractType& type) |
2586 : offset_in_bytes_(offset_in_bytes), | 2473 : offset_in_bytes_(offset_in_bytes), |
2587 type_(type), | 2474 type_(type), |
2588 result_cid_(kDynamicCid) { | 2475 result_cid_(kDynamicCid) { |
2589 ASSERT(value != NULL); | 2476 ASSERT(value != NULL); |
2590 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. | 2477 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. |
2591 inputs_[0] = value; | 2478 inputs_[0] = value; |
2592 } | 2479 } |
2593 | 2480 |
2594 DECLARE_COMPUTATION(LoadVMField) | 2481 DECLARE_INSTRUCTION(LoadVMField) |
| 2482 virtual RawAbstractType* CompileType() const; |
2595 | 2483 |
2596 Value* value() const { return inputs_[0]; } | 2484 Value* value() const { return inputs_[0]; } |
2597 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 2485 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
2598 const AbstractType& type() const { return type_; } | 2486 const AbstractType& type() const { return type_; } |
2599 void set_result_cid(intptr_t value) { result_cid_ = value; } | 2487 void set_result_cid(intptr_t value) { result_cid_ = value; } |
2600 | 2488 |
2601 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2489 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2602 | 2490 |
2603 virtual bool CanDeoptimize() const { return false; } | 2491 virtual bool CanDeoptimize() const { return false; } |
2604 virtual intptr_t ResultCid() const { return result_cid_; } | 2492 virtual intptr_t ResultCid() const { return result_cid_; } |
2605 | 2493 |
2606 private: | 2494 private: |
2607 const intptr_t offset_in_bytes_; | 2495 const intptr_t offset_in_bytes_; |
2608 const AbstractType& type_; | 2496 const AbstractType& type_; |
2609 intptr_t result_cid_; | 2497 intptr_t result_cid_; |
2610 | 2498 |
2611 DISALLOW_COPY_AND_ASSIGN(LoadVMFieldComp); | 2499 DISALLOW_COPY_AND_ASSIGN(LoadVMFieldInstr); |
2612 }; | 2500 }; |
2613 | 2501 |
2614 | 2502 |
2615 class StoreVMFieldComp : public TemplateComputation<2> { | 2503 class StoreVMFieldInstr : public TemplateDefinition<2> { |
2616 public: | 2504 public: |
2617 StoreVMFieldComp(Value* dest, | 2505 StoreVMFieldInstr(Value* dest, |
2618 intptr_t offset_in_bytes, | 2506 intptr_t offset_in_bytes, |
2619 Value* value, | 2507 Value* value, |
2620 const AbstractType& type) | 2508 const AbstractType& type) |
2621 : offset_in_bytes_(offset_in_bytes), type_(type) { | 2509 : offset_in_bytes_(offset_in_bytes), type_(type) { |
2622 ASSERT(value != NULL); | 2510 ASSERT(value != NULL); |
2623 ASSERT(dest != NULL); | 2511 ASSERT(dest != NULL); |
2624 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. | 2512 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. |
2625 inputs_[0] = value; | 2513 inputs_[0] = value; |
2626 inputs_[1] = dest; | 2514 inputs_[1] = dest; |
2627 } | 2515 } |
2628 | 2516 |
2629 DECLARE_COMPUTATION(StoreVMField) | 2517 DECLARE_INSTRUCTION(StoreVMField) |
| 2518 virtual RawAbstractType* CompileType() const; |
2630 | 2519 |
2631 Value* value() const { return inputs_[0]; } | 2520 Value* value() const { return inputs_[0]; } |
2632 Value* dest() const { return inputs_[1]; } | 2521 Value* dest() const { return inputs_[1]; } |
2633 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 2522 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
2634 const AbstractType& type() const { return type_; } | 2523 const AbstractType& type() const { return type_; } |
2635 | 2524 |
2636 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2525 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2637 | 2526 |
2638 virtual bool CanDeoptimize() const { return false; } | 2527 virtual bool CanDeoptimize() const { return false; } |
2639 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2528 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2640 | 2529 |
2641 private: | 2530 private: |
2642 const intptr_t offset_in_bytes_; | 2531 const intptr_t offset_in_bytes_; |
2643 const AbstractType& type_; | 2532 const AbstractType& type_; |
2644 | 2533 |
2645 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldComp); | 2534 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldInstr); |
2646 }; | 2535 }; |
2647 | 2536 |
2648 | 2537 |
2649 class InstantiateTypeArgumentsComp : public TemplateComputation<1> { | 2538 class InstantiateTypeArgumentsInstr : public TemplateDefinition<1> { |
2650 public: | 2539 public: |
2651 InstantiateTypeArgumentsComp(intptr_t token_pos, | 2540 InstantiateTypeArgumentsInstr(intptr_t token_pos, |
2652 const AbstractTypeArguments& type_arguments, | 2541 const AbstractTypeArguments& type_arguments, |
2653 Value* instantiator) | 2542 Value* instantiator) |
2654 : token_pos_(token_pos), | 2543 : token_pos_(token_pos), |
2655 type_arguments_(type_arguments) { | 2544 type_arguments_(type_arguments) { |
2656 ASSERT(type_arguments.IsZoneHandle()); | 2545 ASSERT(type_arguments.IsZoneHandle()); |
2657 ASSERT(instantiator != NULL); | 2546 ASSERT(instantiator != NULL); |
2658 inputs_[0] = instantiator; | 2547 inputs_[0] = instantiator; |
2659 } | 2548 } |
2660 | 2549 |
2661 DECLARE_COMPUTATION(InstantiateTypeArguments) | 2550 DECLARE_INSTRUCTION(InstantiateTypeArguments) |
| 2551 virtual RawAbstractType* CompileType() const; |
2662 | 2552 |
2663 Value* instantiator() const { return inputs_[0]; } | 2553 Value* instantiator() const { return inputs_[0]; } |
2664 const AbstractTypeArguments& type_arguments() const { | 2554 const AbstractTypeArguments& type_arguments() const { |
2665 return type_arguments_; | 2555 return type_arguments_; |
2666 } | 2556 } |
2667 intptr_t token_pos() const { return token_pos_; } | 2557 intptr_t token_pos() const { return token_pos_; } |
2668 | 2558 |
2669 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2559 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2670 | 2560 |
2671 virtual bool CanDeoptimize() const { return false; } | 2561 virtual bool CanDeoptimize() const { return false; } |
2672 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2562 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2673 | 2563 |
2674 private: | 2564 private: |
2675 const intptr_t token_pos_; | 2565 const intptr_t token_pos_; |
2676 const AbstractTypeArguments& type_arguments_; | 2566 const AbstractTypeArguments& type_arguments_; |
2677 | 2567 |
2678 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsComp); | 2568 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr); |
2679 }; | 2569 }; |
2680 | 2570 |
2681 | 2571 |
2682 class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { | 2572 class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> { |
2683 public: | 2573 public: |
2684 ExtractConstructorTypeArgumentsComp( | 2574 ExtractConstructorTypeArgumentsInstr( |
2685 intptr_t token_pos, | 2575 intptr_t token_pos, |
2686 const AbstractTypeArguments& type_arguments, | 2576 const AbstractTypeArguments& type_arguments, |
2687 Value* instantiator) | 2577 Value* instantiator) |
2688 : token_pos_(token_pos), | 2578 : token_pos_(token_pos), |
2689 type_arguments_(type_arguments) { | 2579 type_arguments_(type_arguments) { |
2690 ASSERT(instantiator != NULL); | 2580 ASSERT(instantiator != NULL); |
2691 inputs_[0] = instantiator; | 2581 inputs_[0] = instantiator; |
2692 } | 2582 } |
2693 | 2583 |
2694 DECLARE_COMPUTATION(ExtractConstructorTypeArguments) | 2584 DECLARE_INSTRUCTION(ExtractConstructorTypeArguments) |
| 2585 virtual RawAbstractType* CompileType() const; |
2695 | 2586 |
2696 Value* instantiator() const { return inputs_[0]; } | 2587 Value* instantiator() const { return inputs_[0]; } |
2697 const AbstractTypeArguments& type_arguments() const { | 2588 const AbstractTypeArguments& type_arguments() const { |
2698 return type_arguments_; | 2589 return type_arguments_; |
2699 } | 2590 } |
2700 intptr_t token_pos() const { return token_pos_; } | 2591 intptr_t token_pos() const { return token_pos_; } |
2701 | 2592 |
2702 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2593 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2703 | 2594 |
2704 virtual bool CanDeoptimize() const { return false; } | 2595 virtual bool CanDeoptimize() const { return false; } |
2705 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2596 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2706 | 2597 |
2707 private: | 2598 private: |
2708 const intptr_t token_pos_; | 2599 const intptr_t token_pos_; |
2709 const AbstractTypeArguments& type_arguments_; | 2600 const AbstractTypeArguments& type_arguments_; |
2710 | 2601 |
2711 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); | 2602 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr); |
2712 }; | 2603 }; |
2713 | 2604 |
2714 | 2605 |
2715 class ExtractConstructorInstantiatorComp : public TemplateComputation<1> { | 2606 class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> { |
2716 public: | 2607 public: |
2717 ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, | 2608 ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node, |
2718 Value* instantiator) | 2609 Value* instantiator) |
2719 : ast_node_(*ast_node) { | 2610 : ast_node_(*ast_node) { |
2720 ASSERT(instantiator != NULL); | 2611 ASSERT(instantiator != NULL); |
2721 inputs_[0] = instantiator; | 2612 inputs_[0] = instantiator; |
2722 } | 2613 } |
2723 | 2614 |
2724 DECLARE_COMPUTATION(ExtractConstructorInstantiator) | 2615 DECLARE_INSTRUCTION(ExtractConstructorInstantiator) |
| 2616 virtual RawAbstractType* CompileType() const; |
2725 | 2617 |
2726 Value* instantiator() const { return inputs_[0]; } | 2618 Value* instantiator() const { return inputs_[0]; } |
2727 const AbstractTypeArguments& type_arguments() const { | 2619 const AbstractTypeArguments& type_arguments() const { |
2728 return ast_node_.type_arguments(); | 2620 return ast_node_.type_arguments(); |
2729 } | 2621 } |
2730 const Function& constructor() const { return ast_node_.constructor(); } | 2622 const Function& constructor() const { return ast_node_.constructor(); } |
2731 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2623 intptr_t token_pos() const { return ast_node_.token_pos(); } |
2732 | 2624 |
2733 virtual bool CanDeoptimize() const { return false; } | 2625 virtual bool CanDeoptimize() const { return false; } |
2734 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2626 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2735 | 2627 |
2736 private: | 2628 private: |
2737 const ConstructorCallNode& ast_node_; | 2629 const ConstructorCallNode& ast_node_; |
2738 | 2630 |
2739 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); | 2631 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr); |
2740 }; | 2632 }; |
2741 | 2633 |
2742 | 2634 |
2743 class AllocateContextComp : public TemplateComputation<0> { | 2635 class AllocateContextInstr : public TemplateDefinition<0> { |
2744 public: | 2636 public: |
2745 AllocateContextComp(intptr_t token_pos, | 2637 AllocateContextInstr(intptr_t token_pos, |
2746 intptr_t num_context_variables) | 2638 intptr_t num_context_variables) |
2747 : token_pos_(token_pos), | 2639 : token_pos_(token_pos), |
2748 num_context_variables_(num_context_variables) {} | 2640 num_context_variables_(num_context_variables) {} |
2749 | 2641 |
2750 DECLARE_COMPUTATION(AllocateContext); | 2642 DECLARE_INSTRUCTION(AllocateContext); |
| 2643 virtual RawAbstractType* CompileType() const; |
2751 | 2644 |
2752 intptr_t token_pos() const { return token_pos_; } | 2645 intptr_t token_pos() const { return token_pos_; } |
2753 intptr_t num_context_variables() const { return num_context_variables_; } | 2646 intptr_t num_context_variables() const { return num_context_variables_; } |
2754 | 2647 |
2755 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2648 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2756 | 2649 |
2757 virtual bool CanDeoptimize() const { return false; } | 2650 virtual bool CanDeoptimize() const { return false; } |
2758 virtual intptr_t ResultCid() const { return kDynamicCid; } | 2651 virtual intptr_t ResultCid() const { return kDynamicCid; } |
2759 | 2652 |
2760 private: | 2653 private: |
2761 const intptr_t token_pos_; | 2654 const intptr_t token_pos_; |
2762 const intptr_t num_context_variables_; | 2655 const intptr_t num_context_variables_; |
2763 | 2656 |
2764 DISALLOW_COPY_AND_ASSIGN(AllocateContextComp); | 2657 DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr); |
2765 }; | 2658 }; |
2766 | 2659 |
2767 | 2660 |
2768 class ChainContextComp : public TemplateComputation<1> { | 2661 class ChainContextInstr : public TemplateDefinition<1> { |
2769 public: | 2662 public: |
2770 explicit ChainContextComp(Value* context_value) { | 2663 explicit ChainContextInstr(Value* context_value) { |
2771 ASSERT(context_value != NULL); | 2664 ASSERT(context_value != NULL); |
2772 inputs_[0] = context_value; | 2665 inputs_[0] = context_value; |
2773 } | 2666 } |
2774 | 2667 |
2775 DECLARE_COMPUTATION(ChainContext) | 2668 DECLARE_INSTRUCTION(ChainContext) |
| 2669 virtual RawAbstractType* CompileType() const; |
2776 | 2670 |
2777 Value* context_value() const { return inputs_[0]; } | 2671 Value* context_value() const { return inputs_[0]; } |
2778 | 2672 |
2779 virtual bool CanDeoptimize() const { return false; } | 2673 virtual bool CanDeoptimize() const { return false; } |
2780 virtual intptr_t ResultCid() const { return kIllegalCid; } | 2674 virtual intptr_t ResultCid() const { return kIllegalCid; } |
2781 | 2675 |
2782 private: | 2676 private: |
2783 DISALLOW_COPY_AND_ASSIGN(ChainContextComp); | 2677 DISALLOW_COPY_AND_ASSIGN(ChainContextInstr); |
2784 }; | 2678 }; |
2785 | 2679 |
2786 | 2680 |
2787 class CloneContextComp : public TemplateComputation<1> { | 2681 class CloneContextInstr : public TemplateDefinition<1> { |
2788 public: | 2682 public: |
2789 CloneContextComp(intptr_t token_pos, | 2683 CloneContextInstr(intptr_t token_pos, Value* context_value) |
2790 Value* context_value) | |
2791 : token_pos_(token_pos) { | 2684 : token_pos_(token_pos) { |
2792 ASSERT(context_value != NULL); | 2685 ASSERT(context_value != NULL); |
2793 inputs_[0] = context_value; | 2686 inputs_[0] = context_value; |
2794 } | 2687 } |
2795 | 2688 |
2796 intptr_t token_pos() const { return token_pos_; } | 2689 intptr_t token_pos() const { return token_pos_; } |
2797 Value* context_value() const { return inputs_[0]; } | 2690 Value* context_value() const { return inputs_[0]; } |
2798 | 2691 |
2799 DECLARE_COMPUTATION(CloneContext) | 2692 DECLARE_INSTRUCTION(CloneContext) |
| 2693 virtual RawAbstractType* CompileType() const; |
2800 | 2694 |
2801 virtual bool CanDeoptimize() const { return false; } | 2695 virtual bool CanDeoptimize() const { return false; } |
2802 virtual intptr_t ResultCid() const { return kIllegalCid; } | 2696 virtual intptr_t ResultCid() const { return kIllegalCid; } |
2803 | 2697 |
2804 private: | 2698 private: |
2805 const intptr_t token_pos_; | 2699 const intptr_t token_pos_; |
2806 | 2700 |
2807 DISALLOW_COPY_AND_ASSIGN(CloneContextComp); | 2701 DISALLOW_COPY_AND_ASSIGN(CloneContextInstr); |
2808 }; | 2702 }; |
2809 | 2703 |
2810 | 2704 |
2811 class CatchEntryComp : public TemplateComputation<0> { | 2705 class CatchEntryInstr : public TemplateDefinition<0> { |
2812 public: | 2706 public: |
2813 CatchEntryComp(const LocalVariable& exception_var, | 2707 CatchEntryInstr(const LocalVariable& exception_var, |
2814 const LocalVariable& stacktrace_var) | 2708 const LocalVariable& stacktrace_var) |
2815 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} | 2709 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} |
2816 | 2710 |
2817 const LocalVariable& exception_var() const { return exception_var_; } | 2711 const LocalVariable& exception_var() const { return exception_var_; } |
2818 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } | 2712 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } |
2819 | 2713 |
2820 DECLARE_COMPUTATION(CatchEntry) | 2714 DECLARE_INSTRUCTION(CatchEntry) |
| 2715 virtual RawAbstractType* CompileType() const; |
2821 | 2716 |
2822 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2717 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2823 | 2718 |
2824 virtual bool CanDeoptimize() const { return false; } | 2719 virtual bool CanDeoptimize() const { return false; } |
2825 virtual intptr_t ResultCid() const { return kIllegalCid; } | 2720 virtual intptr_t ResultCid() const { return kIllegalCid; } |
2826 | 2721 |
2827 private: | 2722 private: |
2828 const LocalVariable& exception_var_; | 2723 const LocalVariable& exception_var_; |
2829 const LocalVariable& stacktrace_var_; | 2724 const LocalVariable& stacktrace_var_; |
2830 | 2725 |
2831 DISALLOW_COPY_AND_ASSIGN(CatchEntryComp); | 2726 DISALLOW_COPY_AND_ASSIGN(CatchEntryInstr); |
2832 }; | 2727 }; |
2833 | 2728 |
2834 | 2729 |
2835 class CheckEitherNonSmiComp : public TemplateComputation<2> { | 2730 class CheckEitherNonSmiInstr : public TemplateDefinition<2> { |
2836 public: | 2731 public: |
2837 CheckEitherNonSmiComp(Value* left, | 2732 CheckEitherNonSmiInstr(Value* left, |
2838 Value* right, | 2733 Value* right, |
2839 InstanceCallComp* instance_call) | 2734 InstanceCallInstr* instance_call) { |
2840 : instance_call_(instance_call) { | |
2841 ASSERT(left != NULL); | 2735 ASSERT(left != NULL); |
2842 ASSERT(right != NULL); | 2736 ASSERT(right != NULL); |
2843 inputs_[0] = left; | 2737 inputs_[0] = left; |
2844 inputs_[1] = right; | 2738 inputs_[1] = right; |
| 2739 deopt_id_ = instance_call->deopt_id(); |
2845 } | 2740 } |
2846 | 2741 |
2847 DECLARE_COMPUTATION(CheckEitherNonSmi) | 2742 DECLARE_INSTRUCTION(CheckEitherNonSmi) |
| 2743 virtual RawAbstractType* CompileType() const; |
2848 | 2744 |
2849 virtual bool CanDeoptimize() const { return true; } | 2745 virtual bool CanDeoptimize() const { return true; } |
2850 virtual intptr_t ResultCid() const { return kIllegalCid; } | 2746 virtual intptr_t ResultCid() const { return kIllegalCid; } |
2851 | 2747 |
2852 virtual bool AttributesEqual(Computation* other) const { return true; } | 2748 virtual bool AttributesEqual(Definition* other) const { return true; } |
2853 | 2749 |
2854 virtual bool HasSideEffect() const { return false; } | 2750 virtual bool HasSideEffect() const { return false; } |
2855 | 2751 |
2856 Value* left() const { return inputs_[0]; } | 2752 Value* left() const { return inputs_[0]; } |
2857 | 2753 |
2858 Value* right() const { return inputs_[1]; } | 2754 Value* right() const { return inputs_[1]; } |
2859 | 2755 |
2860 virtual Definition* TryReplace(BindInstr* instr) const; | 2756 virtual Definition* Canonicalize(); |
2861 | 2757 |
2862 private: | 2758 private: |
2863 InstanceCallComp* instance_call_; | 2759 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); |
2864 | |
2865 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiComp); | |
2866 }; | 2760 }; |
2867 | 2761 |
2868 | 2762 |
2869 class BoxDoubleComp : public TemplateComputation<1> { | 2763 class BoxDoubleInstr : public TemplateDefinition<1> { |
2870 public: | 2764 public: |
2871 BoxDoubleComp(Value* value, InstanceCallComp* instance_call) | 2765 BoxDoubleInstr(Value* value, InstanceCallInstr* instance_call) |
2872 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { | 2766 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { |
2873 ASSERT(value != NULL); | 2767 ASSERT(value != NULL); |
2874 inputs_[0] = value; | 2768 inputs_[0] = value; |
2875 } | 2769 } |
2876 | 2770 |
2877 Value* value() const { return inputs_[0]; } | 2771 Value* value() const { return inputs_[0]; } |
2878 | 2772 |
2879 intptr_t token_pos() const { return token_pos_; } | 2773 intptr_t token_pos() const { return token_pos_; } |
2880 | 2774 |
2881 virtual bool CanDeoptimize() const { return false; } | 2775 virtual bool CanDeoptimize() const { return false; } |
2882 virtual bool HasSideEffect() const { return false; } | 2776 virtual bool HasSideEffect() const { return false; } |
2883 virtual bool AttributesEqual(Computation* other) const { return true; } | 2777 virtual bool AttributesEqual(Definition* other) const { return true; } |
2884 | 2778 |
2885 virtual intptr_t ResultCid() const; | 2779 virtual intptr_t ResultCid() const; |
2886 | 2780 |
2887 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2781 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
2888 ASSERT(idx == 0); | 2782 ASSERT(idx == 0); |
2889 return kUnboxedDouble; | 2783 return kUnboxedDouble; |
2890 } | 2784 } |
2891 | 2785 |
2892 DECLARE_COMPUTATION(BoxDouble) | 2786 DECLARE_INSTRUCTION(BoxDouble) |
| 2787 virtual RawAbstractType* CompileType() const; |
2893 | 2788 |
2894 private: | 2789 private: |
2895 const intptr_t token_pos_; | 2790 const intptr_t token_pos_; |
2896 | 2791 |
2897 DISALLOW_COPY_AND_ASSIGN(BoxDoubleComp); | 2792 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); |
2898 }; | 2793 }; |
2899 | 2794 |
2900 | 2795 |
2901 class UnboxDoubleComp : public TemplateComputation<1> { | 2796 class UnboxDoubleInstr : public TemplateDefinition<1> { |
2902 public: | 2797 public: |
2903 UnboxDoubleComp(Value* value, intptr_t deopt_id) | 2798 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { |
2904 : deopt_id_(deopt_id) { | |
2905 ASSERT(value != NULL); | 2799 ASSERT(value != NULL); |
2906 inputs_[0] = value; | 2800 inputs_[0] = value; |
| 2801 deopt_id_ = deopt_id; |
2907 } | 2802 } |
2908 | 2803 |
2909 Value* value() const { return inputs_[0]; } | 2804 Value* value() const { return inputs_[0]; } |
2910 | 2805 |
2911 virtual bool CanDeoptimize() const { | 2806 virtual bool CanDeoptimize() const { |
2912 return value()->ResultCid() != kDoubleCid; | 2807 return value()->ResultCid() != kDoubleCid; |
2913 } | 2808 } |
2914 | 2809 |
2915 // The output is not an instance but when it is boxed it becomes double. | 2810 // The output is not an instance but when it is boxed it becomes double. |
2916 virtual intptr_t ResultCid() const { return kDoubleCid; } | 2811 virtual intptr_t ResultCid() const { return kDoubleCid; } |
2917 | 2812 |
2918 virtual Representation representation() const { | 2813 virtual Representation representation() const { |
2919 return kUnboxedDouble; | 2814 return kUnboxedDouble; |
2920 } | 2815 } |
2921 | 2816 |
2922 virtual bool HasSideEffect() const { return false; } | 2817 virtual bool HasSideEffect() const { return false; } |
2923 virtual bool AttributesEqual(Computation* other) const { return true; } | 2818 virtual bool AttributesEqual(Definition* other) const { return true; } |
2924 | 2819 |
2925 DECLARE_COMPUTATION(UnboxDouble) | 2820 DECLARE_INSTRUCTION(UnboxDouble) |
| 2821 virtual RawAbstractType* CompileType() const; |
2926 | 2822 |
2927 private: | 2823 private: |
2928 const intptr_t deopt_id_; | 2824 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr); |
2929 | |
2930 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleComp); | |
2931 }; | 2825 }; |
2932 | 2826 |
2933 | 2827 |
2934 class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> { | 2828 class UnboxedDoubleBinaryOpInstr : public TemplateDefinition<2> { |
2935 public: | 2829 public: |
2936 UnboxedDoubleBinaryOpComp(Token::Kind op_kind, | 2830 UnboxedDoubleBinaryOpInstr(Token::Kind op_kind, |
2937 Value* left, | 2831 Value* left, |
2938 Value* right, | 2832 Value* right, |
2939 InstanceCallComp* call) | 2833 InstanceCallInstr* instance_call) |
2940 : op_kind_(op_kind), deopt_id_(call->deopt_id()) { | 2834 : op_kind_(op_kind) { |
2941 ASSERT(left != NULL); | 2835 ASSERT(left != NULL); |
2942 ASSERT(right != NULL); | 2836 ASSERT(right != NULL); |
2943 inputs_[0] = left; | 2837 inputs_[0] = left; |
2944 inputs_[1] = right; | 2838 inputs_[1] = right; |
| 2839 deopt_id_ = instance_call->deopt_id(); |
2945 } | 2840 } |
2946 | 2841 |
2947 Value* left() const { return inputs_[0]; } | 2842 Value* left() const { return inputs_[0]; } |
2948 Value* right() const { return inputs_[1]; } | 2843 Value* right() const { return inputs_[1]; } |
2949 | 2844 |
2950 Token::Kind op_kind() const { return op_kind_; } | 2845 Token::Kind op_kind() const { return op_kind_; } |
2951 | 2846 |
2952 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2847 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2953 | 2848 |
2954 virtual bool CanDeoptimize() const { return false; } | 2849 virtual bool CanDeoptimize() const { return false; } |
2955 virtual bool HasSideEffect() const { return false; } | 2850 virtual bool HasSideEffect() const { return false; } |
2956 | 2851 |
2957 virtual bool AttributesEqual(Computation* other) const { | 2852 virtual bool AttributesEqual(Definition* other) const { |
2958 return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind(); | 2853 return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind(); |
2959 } | 2854 } |
2960 | 2855 |
2961 // The output is not an instance but when it is boxed it becomes double. | 2856 // The output is not an instance but when it is boxed it becomes double. |
2962 virtual intptr_t ResultCid() const { return kDoubleCid; } | 2857 virtual intptr_t ResultCid() const { return kDoubleCid; } |
2963 | 2858 |
2964 virtual Representation representation() const { | 2859 virtual Representation representation() const { |
2965 return kUnboxedDouble; | 2860 return kUnboxedDouble; |
2966 } | 2861 } |
2967 | 2862 |
2968 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2863 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
2969 ASSERT((idx == 0) || (idx == 1)); | 2864 ASSERT((idx == 0) || (idx == 1)); |
2970 return kUnboxedDouble; | 2865 return kUnboxedDouble; |
2971 } | 2866 } |
2972 | 2867 |
2973 virtual intptr_t DeoptimizationTarget() const { | 2868 virtual intptr_t DeoptimizationTarget() const { |
2974 return deopt_id_; | 2869 return deopt_id(); |
2975 } | 2870 } |
2976 | 2871 |
2977 DECLARE_COMPUTATION(UnboxedDoubleBinaryOp) | 2872 DECLARE_INSTRUCTION(UnboxedDoubleBinaryOp) |
| 2873 virtual RawAbstractType* CompileType() const; |
2978 | 2874 |
2979 private: | 2875 private: |
2980 const Token::Kind op_kind_; | 2876 const Token::Kind op_kind_; |
2981 const intptr_t deopt_id_; | |
2982 | 2877 |
2983 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpComp); | 2878 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpInstr); |
2984 }; | 2879 }; |
2985 | 2880 |
2986 | 2881 |
2987 class BinarySmiOpComp : public TemplateComputation<2> { | 2882 class BinarySmiOpInstr : public TemplateDefinition<2> { |
2988 public: | 2883 public: |
2989 BinarySmiOpComp(Token::Kind op_kind, | 2884 BinarySmiOpInstr(Token::Kind op_kind, |
2990 InstanceCallComp* instance_call, | 2885 InstanceCallInstr* instance_call, |
2991 Value* left, | 2886 Value* left, |
2992 Value* right) | 2887 Value* right) |
2993 : op_kind_(op_kind), | 2888 : op_kind_(op_kind), |
2994 instance_call_(instance_call) { | 2889 instance_call_(instance_call) { |
2995 ASSERT(left != NULL); | 2890 ASSERT(left != NULL); |
2996 ASSERT(right != NULL); | 2891 ASSERT(right != NULL); |
2997 inputs_[0] = left; | 2892 inputs_[0] = left; |
2998 inputs_[1] = right; | 2893 inputs_[1] = right; |
2999 } | 2894 } |
3000 | 2895 |
3001 Value* left() const { return inputs_[0]; } | 2896 Value* left() const { return inputs_[0]; } |
3002 Value* right() const { return inputs_[1]; } | 2897 Value* right() const { return inputs_[1]; } |
3003 | 2898 |
3004 Token::Kind op_kind() const { return op_kind_; } | 2899 Token::Kind op_kind() const { return op_kind_; } |
3005 | 2900 |
3006 InstanceCallComp* instance_call() const { return instance_call_; } | 2901 InstanceCallInstr* instance_call() const { return instance_call_; } |
3007 | 2902 |
3008 const ICData* ic_data() const { return instance_call()->ic_data(); } | 2903 const ICData* ic_data() const { return instance_call()->ic_data(); } |
3009 | 2904 |
3010 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2905 virtual void PrintOperandsTo(BufferFormatter* f) const; |
3011 | 2906 |
3012 DECLARE_COMPUTATION(BinarySmiOp) | 2907 DECLARE_INSTRUCTION(BinarySmiOp) |
| 2908 virtual RawAbstractType* CompileType() const; |
3013 | 2909 |
3014 virtual bool CanDeoptimize() const; | 2910 virtual bool CanDeoptimize() const; |
3015 | 2911 |
3016 virtual intptr_t ResultCid() const; | 2912 virtual intptr_t ResultCid() const; |
3017 | 2913 |
3018 private: | 2914 private: |
3019 const Token::Kind op_kind_; | 2915 const Token::Kind op_kind_; |
3020 InstanceCallComp* instance_call_; | 2916 InstanceCallInstr* instance_call_; |
3021 | 2917 |
3022 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpComp); | 2918 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); |
3023 }; | 2919 }; |
3024 | 2920 |
3025 | 2921 |
3026 class BinaryMintOpComp : public TemplateComputation<2> { | 2922 class BinaryMintOpInstr : public TemplateDefinition<2> { |
3027 public: | 2923 public: |
3028 BinaryMintOpComp(Token::Kind op_kind, | 2924 BinaryMintOpInstr(Token::Kind op_kind, |
3029 InstanceCallComp* instance_call, | 2925 InstanceCallInstr* instance_call, |
3030 Value* left, | 2926 Value* left, |
3031 Value* right) | 2927 Value* right) |
3032 : op_kind_(op_kind), | 2928 : op_kind_(op_kind), |
3033 instance_call_(instance_call) { | 2929 instance_call_(instance_call) { |
3034 ASSERT(left != NULL); | 2930 ASSERT(left != NULL); |
3035 ASSERT(right != NULL); | 2931 ASSERT(right != NULL); |
3036 inputs_[0] = left; | 2932 inputs_[0] = left; |
3037 inputs_[1] = right; | 2933 inputs_[1] = right; |
3038 } | 2934 } |
3039 | 2935 |
3040 Value* left() const { return inputs_[0]; } | 2936 Value* left() const { return inputs_[0]; } |
3041 Value* right() const { return inputs_[1]; } | 2937 Value* right() const { return inputs_[1]; } |
3042 | 2938 |
3043 Token::Kind op_kind() const { return op_kind_; } | 2939 Token::Kind op_kind() const { return op_kind_; } |
3044 | 2940 |
3045 InstanceCallComp* instance_call() const { return instance_call_; } | 2941 InstanceCallInstr* instance_call() const { return instance_call_; } |
3046 | 2942 |
3047 const ICData* ic_data() const { return instance_call()->ic_data(); } | 2943 const ICData* ic_data() const { return instance_call()->ic_data(); } |
3048 | 2944 |
3049 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2945 virtual void PrintOperandsTo(BufferFormatter* f) const; |
3050 | 2946 |
3051 DECLARE_COMPUTATION(BinaryMintOp) | 2947 DECLARE_INSTRUCTION(BinaryMintOp) |
| 2948 virtual RawAbstractType* CompileType() const; |
3052 | 2949 |
3053 virtual bool CanDeoptimize() const { return true; } | 2950 virtual bool CanDeoptimize() const { return true; } |
3054 virtual intptr_t ResultCid() const; | 2951 virtual intptr_t ResultCid() const; |
3055 | 2952 |
3056 private: | 2953 private: |
3057 const Token::Kind op_kind_; | 2954 const Token::Kind op_kind_; |
3058 InstanceCallComp* instance_call_; | 2955 InstanceCallInstr* instance_call_; |
3059 | 2956 |
3060 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpComp); | 2957 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); |
3061 }; | 2958 }; |
3062 | 2959 |
3063 | 2960 |
3064 // Handles both Smi operations: BIT_OR and NEGATE. | 2961 // Handles both Smi operations: BIT_OR and NEGATE. |
3065 class UnarySmiOpComp : public TemplateComputation<1> { | 2962 class UnarySmiOpInstr : public TemplateDefinition<1> { |
3066 public: | 2963 public: |
3067 UnarySmiOpComp(Token::Kind op_kind, | 2964 UnarySmiOpInstr(Token::Kind op_kind, |
3068 InstanceCallComp* instance_call, | 2965 InstanceCallInstr* instance_call, |
3069 Value* value) | 2966 Value* value) |
3070 : op_kind_(op_kind), instance_call_(instance_call) { | 2967 : op_kind_(op_kind), instance_call_(instance_call) { |
3071 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); | 2968 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); |
3072 ASSERT(value != NULL); | 2969 ASSERT(value != NULL); |
3073 inputs_[0] = value; | 2970 inputs_[0] = value; |
3074 } | 2971 } |
3075 | 2972 |
3076 Value* value() const { return inputs_[0]; } | 2973 Value* value() const { return inputs_[0]; } |
3077 Token::Kind op_kind() const { return op_kind_; } | 2974 Token::Kind op_kind() const { return op_kind_; } |
3078 | 2975 |
3079 InstanceCallComp* instance_call() const { return instance_call_; } | 2976 InstanceCallInstr* instance_call() const { return instance_call_; } |
3080 | 2977 |
3081 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2978 virtual void PrintOperandsTo(BufferFormatter* f) const; |
3082 | 2979 |
3083 DECLARE_COMPUTATION(UnarySmiOp) | 2980 DECLARE_INSTRUCTION(UnarySmiOp) |
| 2981 virtual RawAbstractType* CompileType() const; |
3084 | 2982 |
3085 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } | 2983 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } |
3086 virtual intptr_t ResultCid() const { return kSmiCid; } | 2984 virtual intptr_t ResultCid() const { return kSmiCid; } |
3087 | 2985 |
3088 private: | 2986 private: |
3089 const Token::Kind op_kind_; | 2987 const Token::Kind op_kind_; |
3090 InstanceCallComp* instance_call_; | 2988 InstanceCallInstr* instance_call_; |
3091 | 2989 |
3092 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpComp); | 2990 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); |
3093 }; | 2991 }; |
3094 | 2992 |
3095 | 2993 |
3096 // Handles non-Smi NEGATE operations | 2994 // Handles non-Smi NEGATE operations |
3097 class NumberNegateComp : public TemplateComputation<1> { | 2995 class NumberNegateInstr : public TemplateDefinition<1> { |
3098 public: | 2996 public: |
3099 NumberNegateComp(InstanceCallComp* instance_call, | 2997 NumberNegateInstr(InstanceCallInstr* instance_call, Value* value) |
3100 Value* value) : instance_call_(instance_call) { | 2998 : instance_call_(instance_call) { |
3101 ASSERT(value != NULL); | 2999 ASSERT(value != NULL); |
3102 inputs_[0] = value; | 3000 inputs_[0] = value; |
3103 } | 3001 } |
3104 | 3002 |
3105 Value* value() const { return inputs_[0]; } | 3003 Value* value() const { return inputs_[0]; } |
3106 | 3004 |
3107 InstanceCallComp* instance_call() const { return instance_call_; } | 3005 InstanceCallInstr* instance_call() const { return instance_call_; } |
3108 | 3006 |
3109 const ICData* ic_data() const { return instance_call()->ic_data(); } | 3007 const ICData* ic_data() const { return instance_call()->ic_data(); } |
3110 | 3008 |
3111 DECLARE_COMPUTATION(NumberNegate) | 3009 DECLARE_INSTRUCTION(NumberNegate) |
| 3010 virtual RawAbstractType* CompileType() const; |
3112 | 3011 |
3113 virtual bool CanDeoptimize() const { return true; } | 3012 virtual bool CanDeoptimize() const { return true; } |
3114 virtual intptr_t ResultCid() const { return kDoubleCid; } | 3013 virtual intptr_t ResultCid() const { return kDoubleCid; } |
3115 | 3014 |
3116 private: | 3015 private: |
3117 InstanceCallComp* instance_call_; | 3016 InstanceCallInstr* instance_call_; |
3118 | 3017 |
3119 DISALLOW_COPY_AND_ASSIGN(NumberNegateComp); | 3018 DISALLOW_COPY_AND_ASSIGN(NumberNegateInstr); |
3120 }; | 3019 }; |
3121 | 3020 |
3122 | 3021 |
3123 class CheckStackOverflowComp : public TemplateComputation<0> { | 3022 class CheckStackOverflowInstr : public TemplateDefinition<0> { |
3124 public: | 3023 public: |
3125 explicit CheckStackOverflowComp(intptr_t token_pos) | 3024 explicit CheckStackOverflowInstr(intptr_t token_pos) |
3126 : token_pos_(token_pos) {} | 3025 : token_pos_(token_pos) {} |
3127 | 3026 |
3128 intptr_t token_pos() const { return token_pos_; } | 3027 intptr_t token_pos() const { return token_pos_; } |
3129 | 3028 |
3130 DECLARE_COMPUTATION(CheckStackOverflow) | 3029 DECLARE_INSTRUCTION(CheckStackOverflow) |
| 3030 virtual RawAbstractType* CompileType() const; |
3131 | 3031 |
3132 virtual bool CanDeoptimize() const { return false; } | 3032 virtual bool CanDeoptimize() const { return false; } |
3133 virtual intptr_t ResultCid() const { return kIllegalCid; } | 3033 virtual intptr_t ResultCid() const { return kIllegalCid; } |
3134 | 3034 |
3135 private: | 3035 private: |
3136 const intptr_t token_pos_; | 3036 const intptr_t token_pos_; |
3137 | 3037 |
3138 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowComp); | 3038 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); |
3139 }; | 3039 }; |
3140 | 3040 |
3141 | 3041 |
3142 class DoubleToDoubleComp : public TemplateComputation<1> { | 3042 class DoubleToDoubleInstr : public TemplateDefinition<1> { |
3143 public: | 3043 public: |
3144 DoubleToDoubleComp(Value* value, InstanceCallComp* instance_call) | 3044 DoubleToDoubleInstr(Value* value, InstanceCallInstr* instance_call) |
3145 : instance_call_(instance_call) { | 3045 : instance_call_(instance_call) { |
3146 ASSERT(value != NULL); | 3046 ASSERT(value != NULL); |
3147 inputs_[0] = value; | 3047 inputs_[0] = value; |
3148 } | 3048 } |
3149 | 3049 |
3150 Value* value() const { return inputs_[0]; } | 3050 Value* value() const { return inputs_[0]; } |
3151 | 3051 |
3152 InstanceCallComp* instance_call() const { return instance_call_; } | 3052 InstanceCallInstr* instance_call() const { return instance_call_; } |
3153 | 3053 |
3154 DECLARE_COMPUTATION(DoubleToDouble) | 3054 DECLARE_INSTRUCTION(DoubleToDouble) |
| 3055 virtual RawAbstractType* CompileType() const; |
3155 | 3056 |
3156 virtual bool CanDeoptimize() const { return true; } | 3057 virtual bool CanDeoptimize() const { return true; } |
3157 virtual intptr_t ResultCid() const { return kDoubleCid; } | 3058 virtual intptr_t ResultCid() const { return kDoubleCid; } |
3158 | 3059 |
3159 private: | 3060 private: |
3160 InstanceCallComp* instance_call_; | 3061 InstanceCallInstr* instance_call_; |
3161 | 3062 |
3162 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleComp); | 3063 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr); |
3163 }; | 3064 }; |
3164 | 3065 |
3165 | 3066 |
3166 class SmiToDoubleComp : public TemplateComputation<0> { | 3067 class SmiToDoubleInstr : public TemplateDefinition<0> { |
3167 public: | 3068 public: |
3168 explicit SmiToDoubleComp(InstanceCallComp* instance_call) | 3069 explicit SmiToDoubleInstr(InstanceCallInstr* instance_call) |
3169 : instance_call_(instance_call) { } | 3070 : instance_call_(instance_call) { } |
3170 | 3071 |
3171 InstanceCallComp* instance_call() const { return instance_call_; } | 3072 InstanceCallInstr* instance_call() const { return instance_call_; } |
3172 | 3073 |
3173 DECLARE_CALL_COMPUTATION(SmiToDouble) | 3074 DECLARE_INSTRUCTION(SmiToDouble) |
| 3075 virtual RawAbstractType* CompileType() const; |
3174 | 3076 |
3175 virtual intptr_t ArgumentCount() const { return 1; } | 3077 virtual intptr_t ArgumentCount() const { return 1; } |
3176 | 3078 |
3177 virtual bool CanDeoptimize() const { return true; } | 3079 virtual bool CanDeoptimize() const { return true; } |
3178 virtual intptr_t ResultCid() const { return kDoubleCid; } | 3080 virtual intptr_t ResultCid() const { return kDoubleCid; } |
3179 | 3081 |
3180 private: | 3082 private: |
3181 InstanceCallComp* instance_call_; | 3083 InstanceCallInstr* instance_call_; |
3182 | 3084 |
3183 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); | 3085 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); |
3184 }; | 3086 }; |
3185 | 3087 |
3186 | 3088 |
3187 class CheckClassComp : public TemplateComputation<1> { | 3089 class CheckClassInstr : public TemplateDefinition<1> { |
3188 public: | 3090 public: |
3189 CheckClassComp(Value* value, | 3091 CheckClassInstr(Value* value, |
3190 InstanceCallComp* instance_call, | 3092 InstanceCallInstr* instance_call, |
3191 const ICData& unary_checks) | 3093 const ICData& unary_checks) |
3192 : instance_call_(instance_call), | 3094 : unary_checks_(unary_checks) { |
3193 unary_checks_(unary_checks) { | |
3194 ASSERT(value != NULL); | 3095 ASSERT(value != NULL); |
3195 inputs_[0] = value; | 3096 inputs_[0] = value; |
| 3097 deopt_id_ = instance_call->deopt_id(); |
3196 } | 3098 } |
3197 | 3099 |
3198 DECLARE_COMPUTATION(CheckClass) | 3100 DECLARE_INSTRUCTION(CheckClass) |
| 3101 virtual RawAbstractType* CompileType() const; |
3199 | 3102 |
3200 virtual bool CanDeoptimize() const { return true; } | 3103 virtual bool CanDeoptimize() const { return true; } |
3201 virtual intptr_t ResultCid() const { return kIllegalCid; } | 3104 virtual intptr_t ResultCid() const { return kIllegalCid; } |
3202 | 3105 |
3203 virtual bool AttributesEqual(Computation* other) const; | 3106 virtual bool AttributesEqual(Definition* other) const; |
3204 | 3107 |
3205 virtual bool HasSideEffect() const { return false; } | 3108 virtual bool HasSideEffect() const { return false; } |
3206 | 3109 |
3207 Value* value() const { return inputs_[0]; } | 3110 Value* value() const { return inputs_[0]; } |
3208 | 3111 |
3209 const ICData& unary_checks() const { return unary_checks_; } | 3112 const ICData& unary_checks() const { return unary_checks_; } |
3210 | 3113 |
3211 virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); } | 3114 virtual Definition* Canonicalize(); |
3212 | |
3213 virtual Definition* TryReplace(BindInstr* instr) const; | |
3214 | 3115 |
3215 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3116 virtual void PrintOperandsTo(BufferFormatter* f) const; |
3216 | 3117 |
3217 private: | 3118 private: |
3218 InstanceCallComp* instance_call_; | |
3219 const ICData& unary_checks_; | 3119 const ICData& unary_checks_; |
3220 | 3120 |
3221 DISALLOW_COPY_AND_ASSIGN(CheckClassComp); | 3121 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
3222 }; | 3122 }; |
3223 | 3123 |
3224 | 3124 |
3225 class CheckSmiComp : public TemplateComputation<1> { | 3125 class CheckSmiInstr : public TemplateDefinition<1> { |
3226 public: | 3126 public: |
3227 CheckSmiComp(Value* value, intptr_t original_deopt_id) | 3127 CheckSmiInstr(Value* value, intptr_t original_deopt_id) { |
3228 : original_deopt_id_(original_deopt_id) { | |
3229 ASSERT(value != NULL); | 3128 ASSERT(value != NULL); |
3230 ASSERT(original_deopt_id != Isolate::kNoDeoptId); | 3129 ASSERT(original_deopt_id != Isolate::kNoDeoptId); |
3231 inputs_[0] = value; | 3130 inputs_[0] = value; |
| 3131 deopt_id_ = original_deopt_id; |
3232 } | 3132 } |
3233 | 3133 |
3234 DECLARE_COMPUTATION(CheckSmi) | 3134 DECLARE_INSTRUCTION(CheckSmi) |
| 3135 virtual RawAbstractType* CompileType() const; |
3235 | 3136 |
3236 virtual bool CanDeoptimize() const { return true; } | 3137 virtual bool CanDeoptimize() const { return true; } |
3237 virtual intptr_t ResultCid() const { return kIllegalCid; } | 3138 virtual intptr_t ResultCid() const { return kIllegalCid; } |
3238 | 3139 |
3239 virtual bool AttributesEqual(Computation* other) const { return true; } | 3140 virtual bool AttributesEqual(Definition* other) const { return true; } |
3240 | 3141 |
3241 virtual bool HasSideEffect() const { return false; } | 3142 virtual bool HasSideEffect() const { return false; } |
3242 | 3143 |
3243 virtual Definition* TryReplace(BindInstr* instr) const; | 3144 virtual Definition* Canonicalize(); |
3244 | 3145 |
3245 Value* value() const { return inputs_[0]; } | 3146 Value* value() const { return inputs_[0]; } |
3246 | 3147 |
3247 virtual intptr_t deopt_id() const { return original_deopt_id_; } | |
3248 | |
3249 private: | 3148 private: |
3250 const intptr_t original_deopt_id_; | 3149 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr); |
3251 | |
3252 DISALLOW_COPY_AND_ASSIGN(CheckSmiComp); | |
3253 }; | 3150 }; |
3254 | 3151 |
3255 | 3152 |
3256 class CheckArrayBoundComp : public TemplateComputation<2> { | 3153 class CheckArrayBoundInstr : public TemplateDefinition<2> { |
3257 public: | 3154 public: |
3258 CheckArrayBoundComp(Value* array, | 3155 CheckArrayBoundInstr(Value* array, |
3259 Value* index, | 3156 Value* index, |
3260 intptr_t array_type, | 3157 intptr_t array_type, |
3261 InstanceCallComp* instance_call) | 3158 InstanceCallInstr* instance_call) |
3262 : array_type_(array_type), instance_call_(instance_call) { | 3159 : array_type_(array_type) { |
3263 ASSERT(array != NULL); | 3160 ASSERT(array != NULL); |
3264 ASSERT(index != NULL); | 3161 ASSERT(index != NULL); |
3265 inputs_[0] = array; | 3162 inputs_[0] = array; |
3266 inputs_[1] = index; | 3163 inputs_[1] = index; |
| 3164 deopt_id_ = instance_call->deopt_id(); |
3267 } | 3165 } |
3268 | 3166 |
3269 DECLARE_COMPUTATION(CheckArrayBound) | 3167 DECLARE_INSTRUCTION(CheckArrayBound) |
| 3168 virtual RawAbstractType* CompileType() const; |
3270 | 3169 |
3271 virtual bool CanDeoptimize() const { return true; } | 3170 virtual bool CanDeoptimize() const { return true; } |
3272 virtual intptr_t ResultCid() const { return kIllegalCid; } | 3171 virtual intptr_t ResultCid() const { return kIllegalCid; } |
3273 | 3172 |
3274 virtual bool AttributesEqual(Computation* other) const; | 3173 virtual bool AttributesEqual(Definition* other) const; |
3275 | 3174 |
3276 virtual bool HasSideEffect() const { return false; } | 3175 virtual bool HasSideEffect() const { return false; } |
3277 | 3176 |
3278 Value* array() const { return inputs_[0]; } | 3177 Value* array() const { return inputs_[0]; } |
3279 Value* index() const { return inputs_[1]; } | 3178 Value* index() const { return inputs_[1]; } |
3280 | 3179 |
3281 intptr_t array_type() const { return array_type_; } | 3180 intptr_t array_type() const { return array_type_; } |
3282 | 3181 |
3283 virtual intptr_t deopt_id() const { return instance_call_->deopt_id(); } | |
3284 | |
3285 private: | 3182 private: |
3286 intptr_t array_type_; | 3183 intptr_t array_type_; |
3287 InstanceCallComp* instance_call_; | |
3288 | 3184 |
3289 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundComp); | 3185 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); |
3290 }; | 3186 }; |
3291 | 3187 |
3292 | 3188 |
3293 #undef DECLARE_COMPUTATION | 3189 #undef DECLARE_INSTRUCTION |
3294 | |
3295 | |
3296 // Implementation of type testers and cast functins. | |
3297 #define DEFINE_COMPUTATION_PREDICATE(ShortName, ClassName) \ | |
3298 bool Computation::Is##ShortName() const { \ | |
3299 return computation_kind() == k##ShortName; \ | |
3300 } \ | |
3301 const ClassName* Computation::As##ShortName() const { \ | |
3302 if (!Is##ShortName()) return NULL; \ | |
3303 return static_cast<const ClassName*>(this); \ | |
3304 } \ | |
3305 ClassName* Computation::As##ShortName() { \ | |
3306 if (!Is##ShortName()) return NULL; \ | |
3307 return static_cast<ClassName*>(this); \ | |
3308 } | |
3309 FOR_EACH_COMPUTATION(DEFINE_COMPUTATION_PREDICATE) | |
3310 #undef DEFINE_COMPUTATION_PREDICATE | |
3311 | 3190 |
3312 | 3191 |
3313 class Environment : public ZoneAllocated { | 3192 class Environment : public ZoneAllocated { |
3314 public: | 3193 public: |
3315 // Construct an environment by constructing uses from an array of definitions. | 3194 // Construct an environment by constructing uses from an array of definitions. |
3316 Environment(const GrowableArray<Definition*>& definitions, | 3195 Environment(const GrowableArray<Definition*>& definitions, |
3317 intptr_t fixed_parameter_count); | 3196 intptr_t fixed_parameter_count); |
3318 | 3197 |
3319 void set_locations(Location* locations) { | 3198 void set_locations(Location* locations) { |
3320 ASSERT(locations_ == NULL); | 3199 ASSERT(locations_ == NULL); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3370 virtual ~FlowGraphVisitor() { } | 3249 virtual ~FlowGraphVisitor() { } |
3371 | 3250 |
3372 ForwardInstructionIterator* current_iterator() const { | 3251 ForwardInstructionIterator* current_iterator() const { |
3373 return current_iterator_; | 3252 return current_iterator_; |
3374 } | 3253 } |
3375 | 3254 |
3376 // Visit each block in the block order, and for each block its | 3255 // Visit each block in the block order, and for each block its |
3377 // instructions in order from the block entry to exit. | 3256 // instructions in order from the block entry to exit. |
3378 virtual void VisitBlocks(); | 3257 virtual void VisitBlocks(); |
3379 | 3258 |
3380 // Visit functions for instruction and computation classes, with empty | 3259 // Visit functions for instruction classes, with an empty default |
3381 // default implementations. | 3260 // implementation. |
3382 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ | |
3383 virtual void Visit##ShortName(ClassName* comp, BindInstr* instr) { } | |
3384 | |
3385 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ | 3261 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ |
3386 virtual void Visit##ShortName(ShortName##Instr* instr) { } | 3262 virtual void Visit##ShortName(ShortName##Instr* instr) { } |
3387 | 3263 |
3388 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) | |
3389 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) | 3264 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) |
3390 | 3265 |
3391 #undef DECLARE_VISIT_COMPUTATION | |
3392 #undef DECLARE_VISIT_INSTRUCTION | 3266 #undef DECLARE_VISIT_INSTRUCTION |
3393 | 3267 |
3394 protected: | 3268 protected: |
3395 const GrowableArray<BlockEntryInstr*>& block_order_; | 3269 const GrowableArray<BlockEntryInstr*>& block_order_; |
3396 ForwardInstructionIterator* current_iterator_; | 3270 ForwardInstructionIterator* current_iterator_; |
3397 | 3271 |
3398 private: | 3272 private: |
3399 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3273 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
3400 }; | 3274 }; |
3401 | 3275 |
3402 | 3276 |
3403 } // namespace dart | 3277 } // namespace dart |
3404 | 3278 |
3405 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3279 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |