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" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 static const int kNoCid = -1; | 72 static const int kNoCid = -1; |
73 | 73 |
74 Computation() : cid_(GetNextCid()) { } | 74 Computation() : cid_(GetNextCid()) { } |
75 | 75 |
76 // Unique computation/instruction id, used for deoptimization. | 76 // Unique computation/instruction id, used for deoptimization. |
77 intptr_t cid() const { return cid_; } | 77 intptr_t cid() const { return cid_; } |
78 | 78 |
79 // Visiting support. | 79 // Visiting support. |
80 virtual void Accept(FlowGraphVisitor* visitor) = 0; | 80 virtual void Accept(FlowGraphVisitor* visitor) = 0; |
81 | 81 |
| 82 virtual intptr_t InputCount() const = 0; |
| 83 |
82 private: | 84 private: |
83 friend class Instruction; | 85 friend class Instruction; |
84 static intptr_t GetNextCid() { | 86 static intptr_t GetNextCid() { |
85 Isolate* isolate = Isolate::Current(); | 87 Isolate* isolate = Isolate::Current(); |
86 intptr_t tmp = isolate->computation_id(); | 88 intptr_t tmp = isolate->computation_id(); |
87 isolate->set_computation_id(tmp + 1); | 89 isolate->set_computation_id(tmp + 1); |
88 return tmp; | 90 return tmp; |
89 } | 91 } |
90 | 92 |
91 const intptr_t cid_; | 93 const intptr_t cid_; |
92 | 94 |
93 DISALLOW_COPY_AND_ASSIGN(Computation); | 95 DISALLOW_COPY_AND_ASSIGN(Computation); |
94 }; | 96 }; |
95 | 97 |
96 | 98 |
97 class Value : public Computation { | 99 // An embedded container with N elements of type T. Used (with partial |
| 100 // specialization for N=0) because embedded arrays cannot have size 0. |
| 101 template<typename T, intptr_t N> |
| 102 class EmbeddedArray { |
| 103 public: |
| 104 EmbeddedArray() : elements_() { } |
| 105 |
| 106 intptr_t length() { return N; } |
| 107 T& operator[](intptr_t i) { |
| 108 ASSERT(i < length()); |
| 109 return elements_[i]; |
| 110 } |
| 111 |
| 112 private: |
| 113 T elements_[N]; |
| 114 }; |
| 115 |
| 116 |
| 117 template<typename T> |
| 118 class EmbeddedArray<T, 0> { |
| 119 public: |
| 120 int length() { return 0; } |
| 121 T& operator[](intptr_t i) { |
| 122 UNREACHABLE(); |
| 123 static T sentinel = 0; |
| 124 return sentinel; |
| 125 } |
| 126 }; |
| 127 |
| 128 |
| 129 class Value; |
| 130 |
| 131 template<intptr_t N> |
| 132 class TemplateComputation : public Computation { |
| 133 public: |
| 134 virtual intptr_t InputCount() const { return N; } |
| 135 |
| 136 protected: |
| 137 EmbeddedArray<Value*, N> inputs_; |
| 138 }; |
| 139 |
| 140 |
| 141 class Value : public TemplateComputation<0> { |
98 public: | 142 public: |
99 Value() { } | 143 Value() { } |
100 | 144 |
101 #define DEFINE_TESTERS(ShortName, ClassName) \ | 145 #define DEFINE_TESTERS(ShortName, ClassName) \ |
102 virtual ClassName* As##ShortName() { return NULL; } \ | 146 virtual ClassName* As##ShortName() { return NULL; } \ |
103 bool Is##ShortName() { return As##ShortName() != NULL; } | 147 bool Is##ShortName() { return As##ShortName() != NULL; } |
104 | 148 |
105 FOR_EACH_VALUE(DEFINE_TESTERS) | 149 FOR_EACH_VALUE(DEFINE_TESTERS) |
106 #undef DEFINE_TESTERS | 150 #undef DEFINE_TESTERS |
107 | 151 |
108 private: | 152 private: |
109 DISALLOW_COPY_AND_ASSIGN(Value); | 153 DISALLOW_COPY_AND_ASSIGN(Value); |
110 }; | 154 }; |
111 | 155 |
112 | 156 |
113 // Functions defined in all concrete computation classes. | 157 // Functions defined in all concrete computation classes. |
114 #define DECLARE_COMPUTATION(ShortName) \ | 158 #define DECLARE_COMPUTATION(ShortName) \ |
115 virtual void Accept(FlowGraphVisitor* visitor); | 159 virtual void Accept(FlowGraphVisitor* visitor); \ |
116 | 160 |
117 // Functions defined in all concrete value classes. | 161 // Functions defined in all concrete value classes. |
118 #define DECLARE_VALUE(ShortName) \ | 162 #define DECLARE_VALUE(ShortName) \ |
119 DECLARE_COMPUTATION(ShortName) \ | 163 DECLARE_COMPUTATION(ShortName) \ |
120 virtual ShortName##Val* As##ShortName() { return this; } | 164 virtual ShortName##Val* As##ShortName() { return this; } |
121 | 165 |
122 | 166 |
123 class TempVal : public Value { | 167 class TempVal : public Value { |
124 public: | 168 public: |
125 explicit TempVal(intptr_t index) : index_(index) { } | 169 explicit TempVal(intptr_t index) : index_(index) { } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 | 239 |
196 intptr_t token_index() const { return token_index_; } | 240 intptr_t token_index() const { return token_index_; } |
197 intptr_t try_index() const { return try_index_; } | 241 intptr_t try_index() const { return try_index_; } |
198 Value* value() const { return value_; } | 242 Value* value() const { return value_; } |
199 Value* instantiator_type_arguments() const { | 243 Value* instantiator_type_arguments() const { |
200 return instantiator_type_arguments_; | 244 return instantiator_type_arguments_; |
201 } | 245 } |
202 const AbstractType& dst_type() const { return dst_type_; } | 246 const AbstractType& dst_type() const { return dst_type_; } |
203 const String& dst_name() const { return dst_name_; } | 247 const String& dst_name() const { return dst_name_; } |
204 | 248 |
| 249 virtual intptr_t InputCount() const; |
| 250 |
205 private: | 251 private: |
206 const intptr_t token_index_; | 252 const intptr_t token_index_; |
207 const intptr_t try_index_; | 253 const intptr_t try_index_; |
208 Value* value_; | 254 Value* value_; |
209 Value* instantiator_type_arguments_; | 255 Value* instantiator_type_arguments_; |
210 const AbstractType& dst_type_; | 256 const AbstractType& dst_type_; |
211 const String& dst_name_; | 257 const String& dst_name_; |
212 | 258 |
213 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); | 259 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); |
214 }; | 260 }; |
215 | 261 |
216 | 262 |
217 class AssertBooleanComp : public Computation { | 263 class AssertBooleanComp : public TemplateComputation<1> { |
218 public: | 264 public: |
219 AssertBooleanComp(intptr_t token_index, | 265 AssertBooleanComp(intptr_t token_index, |
220 intptr_t try_index, | 266 intptr_t try_index, |
221 Value* value) | 267 Value* value) |
222 : token_index_(token_index), | 268 : token_index_(token_index), |
223 try_index_(try_index), | 269 try_index_(try_index) { |
224 value_(value) { | 270 ASSERT(value != NULL); |
225 ASSERT(value_ != NULL); | 271 inputs_[0] = value; |
226 } | 272 } |
227 | 273 |
228 DECLARE_COMPUTATION(AssertBoolean) | 274 DECLARE_COMPUTATION(AssertBoolean) |
229 | 275 |
230 intptr_t token_index() const { return token_index_; } | 276 intptr_t token_index() const { return token_index_; } |
231 intptr_t try_index() const { return try_index_; } | 277 intptr_t try_index() const { return try_index_; } |
232 Value* value() const { return value_; } | 278 Value* value() { return inputs_[0]; } |
233 | 279 |
234 private: | 280 private: |
235 const intptr_t token_index_; | 281 const intptr_t token_index_; |
236 const intptr_t try_index_; | 282 const intptr_t try_index_; |
237 Value* value_; | |
238 | 283 |
239 DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); | 284 DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); |
240 }; | 285 }; |
241 | 286 |
242 | 287 |
243 // Denotes the current context, normally held in a register. This is | 288 // Denotes the current context, normally held in a register. This is |
244 // a computation, not a value, because it's mutable. | 289 // a computation, not a value, because it's mutable. |
245 class CurrentContextComp : public Computation { | 290 class CurrentContextComp : public TemplateComputation<0> { |
246 public: | 291 public: |
247 CurrentContextComp() { } | 292 CurrentContextComp() { } |
248 | 293 |
249 DECLARE_COMPUTATION(CurrentContext) | 294 DECLARE_COMPUTATION(CurrentContext) |
250 | 295 |
251 private: | 296 private: |
252 DISALLOW_COPY_AND_ASSIGN(CurrentContextComp); | 297 DISALLOW_COPY_AND_ASSIGN(CurrentContextComp); |
253 }; | 298 }; |
254 | 299 |
255 | 300 |
256 class StoreContextComp : public Computation { | 301 class StoreContextComp : public TemplateComputation<1> { |
257 public: | 302 public: |
258 explicit StoreContextComp(Value* value) : value_(value) { | 303 explicit StoreContextComp(Value* value) { |
259 ASSERT(value_ != NULL); | 304 ASSERT(value != NULL); |
| 305 inputs_[0] = value; |
260 } | 306 } |
261 | 307 |
262 DECLARE_COMPUTATION(StoreContext); | 308 DECLARE_COMPUTATION(StoreContext); |
263 | 309 |
264 Value* value() const { return value_; } | 310 Value* value() { return inputs_[0]; } |
265 | 311 |
266 private: | 312 private: |
267 Value* value_; | |
268 | |
269 DISALLOW_COPY_AND_ASSIGN(StoreContextComp); | 313 DISALLOW_COPY_AND_ASSIGN(StoreContextComp); |
270 }; | 314 }; |
271 | 315 |
272 | 316 |
273 class ClosureCallComp : public Computation { | 317 class ClosureCallComp : public Computation { |
274 public: | 318 public: |
275 ClosureCallComp(ClosureCallNode* node, | 319 ClosureCallComp(ClosureCallNode* node, |
276 intptr_t try_index, | 320 intptr_t try_index, |
277 Value* context, | 321 Value* context, |
278 ZoneGrowableArray<Value*>* arguments) | 322 ZoneGrowableArray<Value*>* arguments) |
279 : ast_node_(*node), | 323 : ast_node_(*node), |
280 try_index_(try_index), | 324 try_index_(try_index), |
281 context_(context), | 325 context_(context), |
282 arguments_(arguments) { | 326 arguments_(arguments) { |
283 ASSERT(context->IsTemp() || context->IsUse()); | 327 ASSERT(context->IsTemp() || context->IsUse()); |
284 } | 328 } |
285 | 329 |
286 DECLARE_COMPUTATION(ClosureCall) | 330 DECLARE_COMPUTATION(ClosureCall) |
287 | 331 |
288 const Array& argument_names() const { return ast_node_.arguments()->names(); } | 332 const Array& argument_names() const { return ast_node_.arguments()->names(); } |
289 intptr_t token_index() const { return ast_node_.token_index(); } | 333 intptr_t token_index() const { return ast_node_.token_index(); } |
290 intptr_t try_index() const { return try_index_; } | 334 intptr_t try_index() const { return try_index_; } |
291 | 335 |
292 Value* context() const { return context_; } | 336 Value* context() const { return context_; } |
293 intptr_t ArgumentCount() const { return arguments_->length(); } | 337 intptr_t ArgumentCount() const { return arguments_->length(); } |
294 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } | 338 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } |
295 | 339 |
| 340 virtual intptr_t InputCount() const; |
| 341 |
296 private: | 342 private: |
297 const ClosureCallNode& ast_node_; | 343 const ClosureCallNode& ast_node_; |
298 const intptr_t try_index_; | 344 const intptr_t try_index_; |
299 Value* context_; | 345 Value* context_; |
300 ZoneGrowableArray<Value*>* arguments_; | 346 ZoneGrowableArray<Value*>* arguments_; |
301 | 347 |
302 DISALLOW_COPY_AND_ASSIGN(ClosureCallComp); | 348 DISALLOW_COPY_AND_ASSIGN(ClosureCallComp); |
303 }; | 349 }; |
304 | 350 |
305 | 351 |
(...skipping 19 matching lines...) Expand all Loading... |
325 DECLARE_COMPUTATION(InstanceCall) | 371 DECLARE_COMPUTATION(InstanceCall) |
326 | 372 |
327 intptr_t token_index() const { return token_index_; } | 373 intptr_t token_index() const { return token_index_; } |
328 intptr_t try_index() const { return try_index_; } | 374 intptr_t try_index() const { return try_index_; } |
329 const String& function_name() const { return function_name_; } | 375 const String& function_name() const { return function_name_; } |
330 intptr_t ArgumentCount() const { return arguments_->length(); } | 376 intptr_t ArgumentCount() const { return arguments_->length(); } |
331 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } | 377 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } |
332 const Array& argument_names() const { return argument_names_; } | 378 const Array& argument_names() const { return argument_names_; } |
333 intptr_t checked_argument_count() const { return checked_argument_count_; } | 379 intptr_t checked_argument_count() const { return checked_argument_count_; } |
334 | 380 |
| 381 virtual intptr_t InputCount() const; |
| 382 |
335 private: | 383 private: |
336 const intptr_t token_index_; | 384 const intptr_t token_index_; |
337 const intptr_t try_index_; | 385 const intptr_t try_index_; |
338 const String& function_name_; | 386 const String& function_name_; |
339 ZoneGrowableArray<Value*>* const arguments_; | 387 ZoneGrowableArray<Value*>* const arguments_; |
340 const Array& argument_names_; | 388 const Array& argument_names_; |
341 const intptr_t checked_argument_count_; | 389 const intptr_t checked_argument_count_; |
342 | 390 |
343 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); | 391 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); |
344 }; | 392 }; |
345 | 393 |
346 | 394 |
347 class StrictCompareComp : public Computation { | 395 class StrictCompareComp : public TemplateComputation<2> { |
348 public: | 396 public: |
349 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 397 StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
350 : kind_(kind), left_(left), right_(right) { | 398 : kind_(kind) { |
351 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); | 399 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
| 400 inputs_[0] = left; |
| 401 inputs_[1] = right; |
352 } | 402 } |
353 | 403 |
354 DECLARE_COMPUTATION(StrictCompare) | 404 DECLARE_COMPUTATION(StrictCompare) |
355 | 405 |
356 Token::Kind kind() const { return kind_; } | 406 Token::Kind kind() const { return kind_; } |
357 Value* left() const { return left_; } | 407 Value* left() { return inputs_[0]; } |
358 Value* right() const { return right_; } | 408 Value* right() { return inputs_[1]; } |
359 | 409 |
360 private: | 410 private: |
361 const Token::Kind kind_; | 411 const Token::Kind kind_; |
362 Value* left_; | |
363 Value* right_; | |
364 | 412 |
365 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 413 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
366 }; | 414 }; |
367 | 415 |
368 | 416 |
369 class EqualityCompareComp : public Computation { | 417 class EqualityCompareComp : public TemplateComputation<2> { |
370 public: | 418 public: |
371 EqualityCompareComp(intptr_t token_index, | 419 EqualityCompareComp(intptr_t token_index, |
372 intptr_t try_index, | 420 intptr_t try_index, |
373 Value* left, | 421 Value* left, |
374 Value* right) | 422 Value* right) |
375 : token_index_(token_index), | 423 : token_index_(token_index), |
376 try_index_(try_index), | 424 try_index_(try_index) { |
377 left_(left), | 425 ASSERT(left != NULL); |
378 right_(right) { | 426 ASSERT(right != NULL); |
379 ASSERT(left_ != NULL); | 427 inputs_[0] = left; |
380 ASSERT(right_ != NULL); | 428 inputs_[1] = right; |
381 } | 429 } |
382 | 430 |
383 DECLARE_COMPUTATION(EqualityCompareComp) | 431 DECLARE_COMPUTATION(EqualityCompareComp) |
384 | 432 |
385 intptr_t token_index() const { return token_index_; } | 433 intptr_t token_index() const { return token_index_; } |
386 intptr_t try_index() const { return try_index_; } | 434 intptr_t try_index() const { return try_index_; } |
387 Value* left() const { return left_; } | 435 Value* left() { return inputs_[0]; } |
388 Value* right() const { return right_; } | 436 Value* right() { return inputs_[1]; } |
389 | 437 |
390 private: | 438 private: |
391 const intptr_t token_index_; | 439 const intptr_t token_index_; |
392 const intptr_t try_index_; | 440 const intptr_t try_index_; |
393 Value* left_; | |
394 Value* right_; | |
395 | 441 |
396 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 442 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
397 }; | 443 }; |
398 | 444 |
399 | 445 |
400 class StaticCallComp : public Computation { | 446 class StaticCallComp : public Computation { |
401 public: | 447 public: |
402 StaticCallComp(intptr_t token_index, | 448 StaticCallComp(intptr_t token_index, |
403 intptr_t try_index, | 449 intptr_t try_index, |
404 const Function& function, | 450 const Function& function, |
(...skipping 12 matching lines...) Expand all Loading... |
417 | 463 |
418 // Accessors forwarded to the AST node. | 464 // Accessors forwarded to the AST node. |
419 const Function& function() const { return function_; } | 465 const Function& function() const { return function_; } |
420 const Array& argument_names() const { return argument_names_; } | 466 const Array& argument_names() const { return argument_names_; } |
421 intptr_t token_index() const { return token_index_; } | 467 intptr_t token_index() const { return token_index_; } |
422 intptr_t try_index() const { return try_index_; } | 468 intptr_t try_index() const { return try_index_; } |
423 | 469 |
424 intptr_t ArgumentCount() const { return arguments_->length(); } | 470 intptr_t ArgumentCount() const { return arguments_->length(); } |
425 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } | 471 Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } |
426 | 472 |
| 473 virtual intptr_t InputCount() const; |
| 474 |
427 private: | 475 private: |
428 const intptr_t token_index_; | 476 const intptr_t token_index_; |
429 const intptr_t try_index_; | 477 const intptr_t try_index_; |
430 const Function& function_; | 478 const Function& function_; |
431 const Array& argument_names_; | 479 const Array& argument_names_; |
432 ZoneGrowableArray<Value*>* arguments_; | 480 ZoneGrowableArray<Value*>* arguments_; |
433 | 481 |
434 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); | 482 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); |
435 }; | 483 }; |
436 | 484 |
437 | 485 |
438 class LoadLocalComp : public Computation { | 486 class LoadLocalComp : public TemplateComputation<0> { |
439 public: | 487 public: |
440 LoadLocalComp(const LocalVariable& local, intptr_t context_level) | 488 LoadLocalComp(const LocalVariable& local, intptr_t context_level) |
441 : local_(local), context_level_(context_level) { } | 489 : local_(local), context_level_(context_level) { } |
442 | 490 |
443 DECLARE_COMPUTATION(LoadLocal) | 491 DECLARE_COMPUTATION(LoadLocal) |
444 | 492 |
445 const LocalVariable& local() const { return local_; } | 493 const LocalVariable& local() const { return local_; } |
446 intptr_t context_level() const { return context_level_; } | 494 intptr_t context_level() const { return context_level_; } |
447 | 495 |
448 private: | 496 private: |
449 const LocalVariable& local_; | 497 const LocalVariable& local_; |
450 const intptr_t context_level_; | 498 const intptr_t context_level_; |
451 | 499 |
452 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); | 500 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); |
453 }; | 501 }; |
454 | 502 |
455 | 503 |
456 class StoreLocalComp : public Computation { | 504 class StoreLocalComp : public TemplateComputation<1> { |
457 public: | 505 public: |
458 StoreLocalComp(const LocalVariable& local, | 506 StoreLocalComp(const LocalVariable& local, |
459 Value* value, | 507 Value* value, |
460 intptr_t context_level) | 508 intptr_t context_level) |
461 : local_(local), value_(value), context_level_(context_level) { } | 509 : local_(local), context_level_(context_level) { |
| 510 inputs_[0] = value; |
| 511 } |
462 | 512 |
463 DECLARE_COMPUTATION(StoreLocal) | 513 DECLARE_COMPUTATION(StoreLocal) |
464 | 514 |
465 const LocalVariable& local() const { return local_; } | 515 const LocalVariable& local() const { return local_; } |
466 Value* value() const { return value_; } | 516 Value* value() { return inputs_[0]; } |
467 intptr_t context_level() const { return context_level_; } | 517 intptr_t context_level() const { return context_level_; } |
468 | 518 |
469 private: | 519 private: |
470 const LocalVariable& local_; | 520 const LocalVariable& local_; |
471 Value* value_; | |
472 const intptr_t context_level_; | 521 const intptr_t context_level_; |
473 | 522 |
474 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); | 523 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); |
475 }; | 524 }; |
476 | 525 |
477 | 526 |
478 class NativeCallComp : public Computation { | 527 class NativeCallComp : public TemplateComputation<0> { |
479 public: | 528 public: |
480 NativeCallComp(NativeBodyNode* node, intptr_t try_index) | 529 NativeCallComp(NativeBodyNode* node, intptr_t try_index) |
481 : ast_node_(*node), try_index_(try_index) {} | 530 : ast_node_(*node), try_index_(try_index) {} |
482 | 531 |
483 DECLARE_COMPUTATION(NativeCall) | 532 DECLARE_COMPUTATION(NativeCall) |
484 | 533 |
485 intptr_t token_index() const { return ast_node_.token_index(); } | 534 intptr_t token_index() const { return ast_node_.token_index(); } |
486 intptr_t try_index() const { return try_index_; } | 535 intptr_t try_index() const { return try_index_; } |
487 | 536 |
488 const String& native_name() const { | 537 const String& native_name() const { |
(...skipping 11 matching lines...) Expand all Loading... |
500 } | 549 } |
501 | 550 |
502 private: | 551 private: |
503 const NativeBodyNode& ast_node_; | 552 const NativeBodyNode& ast_node_; |
504 const intptr_t try_index_; | 553 const intptr_t try_index_; |
505 | 554 |
506 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); | 555 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); |
507 }; | 556 }; |
508 | 557 |
509 | 558 |
510 class LoadInstanceFieldComp : public Computation { | 559 class LoadInstanceFieldComp : public TemplateComputation<1> { |
511 public: | 560 public: |
512 LoadInstanceFieldComp(LoadInstanceFieldNode* ast_node, Value* instance) | 561 LoadInstanceFieldComp(LoadInstanceFieldNode* ast_node, Value* instance) |
513 : ast_node_(*ast_node), instance_(instance) { | 562 : ast_node_(*ast_node) { |
514 ASSERT(instance_ != NULL); | 563 ASSERT(instance != NULL); |
| 564 inputs_[0] = instance; |
515 } | 565 } |
516 | 566 |
517 DECLARE_COMPUTATION(LoadInstanceField) | 567 DECLARE_COMPUTATION(LoadInstanceField) |
518 | 568 |
519 const Field& field() const { return ast_node_.field(); } | 569 const Field& field() const { return ast_node_.field(); } |
520 | 570 |
521 Value* instance() const { return instance_; } | 571 Value* instance() { return inputs_[0]; } |
522 | 572 |
523 private: | 573 private: |
524 const LoadInstanceFieldNode& ast_node_; | 574 const LoadInstanceFieldNode& ast_node_; |
525 Value* instance_; | |
526 | 575 |
527 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 576 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); |
528 }; | 577 }; |
529 | 578 |
530 | 579 |
531 class StoreInstanceFieldComp : public Computation { | 580 class StoreInstanceFieldComp : public TemplateComputation<2> { |
532 public: | 581 public: |
533 StoreInstanceFieldComp(StoreInstanceFieldNode* ast_node, | 582 StoreInstanceFieldComp(StoreInstanceFieldNode* ast_node, |
534 Value* instance, | 583 Value* instance, |
535 Value* value) | 584 Value* value) |
536 : ast_node_(*ast_node), instance_(instance), value_(value) { | 585 : ast_node_(*ast_node) { |
537 ASSERT(instance_ != NULL); | 586 ASSERT(instance != NULL); |
538 ASSERT(value_ != NULL); | 587 ASSERT(value != NULL); |
| 588 inputs_[0] = instance; |
| 589 inputs_[1] = value; |
539 } | 590 } |
540 | 591 |
541 DECLARE_COMPUTATION(StoreInstanceField) | 592 DECLARE_COMPUTATION(StoreInstanceField) |
542 | 593 |
543 intptr_t token_index() const { return ast_node_.token_index(); } | 594 intptr_t token_index() const { return ast_node_.token_index(); } |
544 const Field& field() const { return ast_node_.field(); } | 595 const Field& field() const { return ast_node_.field(); } |
545 | 596 |
546 Value* instance() const { return instance_; } | 597 Value* instance() { return inputs_[0]; } |
547 Value* value() const { return value_; } | 598 Value* value() { return inputs_[1]; } |
548 | 599 |
549 private: | 600 private: |
550 const StoreInstanceFieldNode& ast_node_; | 601 const StoreInstanceFieldNode& ast_node_; |
551 Value* instance_; | |
552 Value* value_; | |
553 | 602 |
554 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); | 603 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); |
555 }; | 604 }; |
556 | 605 |
557 | 606 |
558 class LoadStaticFieldComp : public Computation { | 607 class LoadStaticFieldComp : public TemplateComputation<0> { |
559 public: | 608 public: |
560 explicit LoadStaticFieldComp(const Field& field) : field_(field) {} | 609 explicit LoadStaticFieldComp(const Field& field) : field_(field) {} |
561 | 610 |
562 DECLARE_COMPUTATION(LoadStaticField); | 611 DECLARE_COMPUTATION(LoadStaticField); |
563 | 612 |
564 const Field& field() const { return field_; } | 613 const Field& field() const { return field_; } |
565 | 614 |
566 private: | 615 private: |
567 const Field& field_; | 616 const Field& field_; |
568 | 617 |
569 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldComp); | 618 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldComp); |
570 }; | 619 }; |
571 | 620 |
572 | 621 |
573 class StoreStaticFieldComp : public Computation { | 622 class StoreStaticFieldComp : public TemplateComputation<1> { |
574 public: | 623 public: |
575 StoreStaticFieldComp(const Field& field, Value* value) | 624 StoreStaticFieldComp(const Field& field, Value* value) |
576 : field_(field), | 625 : field_(field) { |
577 value_(value) { | |
578 ASSERT(field.IsZoneHandle()); | 626 ASSERT(field.IsZoneHandle()); |
579 ASSERT(value != NULL); | 627 ASSERT(value != NULL); |
| 628 inputs_[0] = value; |
580 } | 629 } |
581 | 630 |
582 DECLARE_COMPUTATION(StoreStaticField); | 631 DECLARE_COMPUTATION(StoreStaticField); |
583 | 632 |
584 const Field& field() const { return field_; } | 633 const Field& field() const { return field_; } |
585 Value* value() const { return value_; } | 634 Value* value() { return inputs_[0]; } |
586 | 635 |
587 private: | 636 private: |
588 const Field& field_; | 637 const Field& field_; |
589 Value* const value_; | |
590 | 638 |
591 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); | 639 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); |
592 }; | 640 }; |
593 | 641 |
594 | 642 |
595 // Not simply an InstanceCall because it has somewhat more complicated | 643 // Not simply an InstanceCall because it has somewhat more complicated |
596 // semantics: the value operand is preserved before the call. | 644 // semantics: the value operand is preserved before the call. |
597 class StoreIndexedComp : public Computation { | 645 class StoreIndexedComp : public TemplateComputation<3> { |
598 public: | 646 public: |
599 StoreIndexedComp(intptr_t token_index, | 647 StoreIndexedComp(intptr_t token_index, |
600 intptr_t try_index, | 648 intptr_t try_index, |
601 Value* array, | 649 Value* array, |
602 Value* index, | 650 Value* index, |
603 Value* value) | 651 Value* value) |
604 : token_index_(token_index), | 652 : token_index_(token_index), |
605 try_index_(try_index), | 653 try_index_(try_index) { |
606 array_(array), | 654 inputs_[0] = array; |
607 index_(index), | 655 inputs_[1] = index; |
608 value_(value) { } | 656 inputs_[2] = value; |
| 657 } |
609 | 658 |
610 DECLARE_COMPUTATION(StoreIndexed) | 659 DECLARE_COMPUTATION(StoreIndexed) |
611 | 660 |
612 intptr_t token_index() const { return token_index_; } | 661 intptr_t token_index() const { return token_index_; } |
613 intptr_t try_index() const { return try_index_; } | 662 intptr_t try_index() const { return try_index_; } |
614 Value* array() const { return array_; } | 663 Value* array() { return inputs_[0]; } |
615 Value* index() const { return index_; } | 664 Value* index() { return inputs_[1]; } |
616 Value* value() const { return value_; } | 665 Value* value() { return inputs_[2]; } |
617 | 666 |
618 private: | 667 private: |
619 const intptr_t token_index_; | 668 const intptr_t token_index_; |
620 const intptr_t try_index_; | 669 const intptr_t try_index_; |
621 Value* array_; | |
622 Value* index_; | |
623 Value* value_; | |
624 | 670 |
625 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); | 671 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); |
626 }; | 672 }; |
627 | 673 |
628 | 674 |
629 // Not simply an InstanceCall because it has somewhat more complicated | 675 // Not simply an InstanceCall because it has somewhat more complicated |
630 // semantics: the value operand is preserved before the call. | 676 // semantics: the value operand is preserved before the call. |
631 class InstanceSetterComp : public Computation { | 677 class InstanceSetterComp : public TemplateComputation<2> { |
632 public: | 678 public: |
633 InstanceSetterComp(intptr_t token_index, | 679 InstanceSetterComp(intptr_t token_index, |
634 intptr_t try_index, | 680 intptr_t try_index, |
635 const String& field_name, | 681 const String& field_name, |
636 Value* receiver, | 682 Value* receiver, |
637 Value* value) | 683 Value* value) |
638 : token_index_(token_index), | 684 : token_index_(token_index), |
639 try_index_(try_index), | 685 try_index_(try_index), |
640 field_name_(field_name), | 686 field_name_(field_name) { |
641 receiver_(receiver), | 687 inputs_[0] = receiver; |
642 value_(value) { } | 688 inputs_[1] = value; |
| 689 } |
643 | 690 |
644 DECLARE_COMPUTATION(InstanceSetter) | 691 DECLARE_COMPUTATION(InstanceSetter) |
645 | 692 |
646 intptr_t token_index() const { return token_index_; } | 693 intptr_t token_index() const { return token_index_; } |
647 intptr_t try_index() const { return try_index_; } | 694 intptr_t try_index() const { return try_index_; } |
648 const String& field_name() const { return field_name_; } | 695 const String& field_name() const { return field_name_; } |
649 Value* receiver() const { return receiver_; } | 696 Value* receiver() { return inputs_[0]; } |
650 Value* value() const { return value_; } | 697 Value* value() { return inputs_[1]; } |
651 | 698 |
652 private: | 699 private: |
653 const intptr_t token_index_; | 700 const intptr_t token_index_; |
654 const intptr_t try_index_; | 701 const intptr_t try_index_; |
655 const String& field_name_; | 702 const String& field_name_; |
656 Value* const receiver_; | |
657 Value* const value_; | |
658 | 703 |
659 DISALLOW_COPY_AND_ASSIGN(InstanceSetterComp); | 704 DISALLOW_COPY_AND_ASSIGN(InstanceSetterComp); |
660 }; | 705 }; |
661 | 706 |
662 | 707 |
663 // Not simply a StaticCall because it has somewhat more complicated | 708 // Not simply a StaticCall because it has somewhat more complicated |
664 // semantics: the value operand is preserved before the call. | 709 // semantics: the value operand is preserved before the call. |
665 class StaticSetterComp : public Computation { | 710 class StaticSetterComp : public TemplateComputation<1> { |
666 public: | 711 public: |
667 StaticSetterComp(intptr_t token_index, | 712 StaticSetterComp(intptr_t token_index, |
668 intptr_t try_index, | 713 intptr_t try_index, |
669 const Function& setter_function, | 714 const Function& setter_function, |
670 Value* value) | 715 Value* value) |
671 : token_index_(token_index), | 716 : token_index_(token_index), |
672 try_index_(try_index), | 717 try_index_(try_index), |
673 setter_function_(setter_function), | 718 setter_function_(setter_function) { |
674 value_(value) { } | 719 inputs_[0] = value; |
| 720 } |
675 | 721 |
676 DECLARE_COMPUTATION(StaticSetter) | 722 DECLARE_COMPUTATION(StaticSetter) |
677 | 723 |
678 intptr_t token_index() const { return token_index_; } | 724 intptr_t token_index() const { return token_index_; } |
679 intptr_t try_index() const { return try_index_; } | 725 intptr_t try_index() const { return try_index_; } |
680 const Function& setter_function() const { return setter_function_; } | 726 const Function& setter_function() const { return setter_function_; } |
681 Value* value() const { return value_; } | 727 Value* value() { return inputs_[0]; } |
682 | 728 |
683 private: | 729 private: |
684 const intptr_t token_index_; | 730 const intptr_t token_index_; |
685 const intptr_t try_index_; | 731 const intptr_t try_index_; |
686 const Function& setter_function_; | 732 const Function& setter_function_; |
687 Value* const value_; | |
688 | 733 |
689 DISALLOW_COPY_AND_ASSIGN(StaticSetterComp); | 734 DISALLOW_COPY_AND_ASSIGN(StaticSetterComp); |
690 }; | 735 }; |
691 | 736 |
692 | 737 |
693 // Note overrideable, built-in: value? false : true. | 738 // Note overrideable, built-in: value? false : true. |
694 class BooleanNegateComp : public Computation { | 739 class BooleanNegateComp : public TemplateComputation<1> { |
695 public: | 740 public: |
696 explicit BooleanNegateComp(Value* value) : value_(value) {} | 741 explicit BooleanNegateComp(Value* value) { |
| 742 inputs_[0] = value; |
| 743 } |
697 | 744 |
698 DECLARE_COMPUTATION(BooleanNegate) | 745 DECLARE_COMPUTATION(BooleanNegate) |
699 | 746 |
700 Value* value() const { return value_; } | 747 Value* value() { return inputs_[0]; } |
701 | 748 |
702 private: | 749 private: |
703 Value* value_; | |
704 | |
705 DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); | 750 DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); |
706 }; | 751 }; |
707 | 752 |
708 | 753 |
709 class InstanceOfComp : public Computation { | 754 class InstanceOfComp : public Computation { |
710 public: | 755 public: |
711 InstanceOfComp(intptr_t token_index, | 756 InstanceOfComp(intptr_t token_index, |
712 intptr_t try_index, | 757 intptr_t try_index, |
713 Value* value, | 758 Value* value, |
714 Value* type_arguments, // Can be NULL. | 759 Value* type_arguments, // Can be NULL. |
(...skipping 11 matching lines...) Expand all Loading... |
726 | 771 |
727 DECLARE_COMPUTATION(InstanceOf) | 772 DECLARE_COMPUTATION(InstanceOf) |
728 | 773 |
729 Value* value() const { return value_; } | 774 Value* value() const { return value_; } |
730 Value* type_arguments() const { return type_arguments_; } | 775 Value* type_arguments() const { return type_arguments_; } |
731 bool negate_result() const { return negate_result_; } | 776 bool negate_result() const { return negate_result_; } |
732 const AbstractType& type() const { return type_; } | 777 const AbstractType& type() const { return type_; } |
733 intptr_t token_index() const { return token_index_; } | 778 intptr_t token_index() const { return token_index_; } |
734 intptr_t try_index() const { return try_index_; } | 779 intptr_t try_index() const { return try_index_; } |
735 | 780 |
| 781 virtual intptr_t InputCount() const; |
| 782 |
736 private: | 783 private: |
737 const intptr_t token_index_; | 784 const intptr_t token_index_; |
738 const intptr_t try_index_; | 785 const intptr_t try_index_; |
739 Value* value_; | 786 Value* value_; |
740 Value* type_arguments_; | 787 Value* type_arguments_; |
741 const AbstractType& type_; | 788 const AbstractType& type_; |
742 const bool negate_result_; | 789 const bool negate_result_; |
743 | 790 |
744 DISALLOW_COPY_AND_ASSIGN(InstanceOfComp); | 791 DISALLOW_COPY_AND_ASSIGN(InstanceOfComp); |
745 }; | 792 }; |
746 | 793 |
747 | 794 |
748 class AllocateObjectComp : public Computation { | 795 class AllocateObjectComp : public Computation { |
749 public: | 796 public: |
750 AllocateObjectComp(ConstructorCallNode* node, | 797 AllocateObjectComp(ConstructorCallNode* node, |
751 intptr_t try_index, | 798 intptr_t try_index, |
752 ZoneGrowableArray<Value*>* arguments) | 799 ZoneGrowableArray<Value*>* arguments) |
753 : ast_node_(*node), try_index_(try_index), arguments_(arguments) { | 800 : ast_node_(*node), try_index_(try_index), arguments_(arguments) { |
754 // Either no arguments or one type-argument and one instantiator. | 801 // Either no arguments or one type-argument and one instantiator. |
755 ASSERT(arguments->is_empty() || (arguments->length() == 2)); | 802 ASSERT(arguments->is_empty() || (arguments->length() == 2)); |
756 } | 803 } |
757 | 804 |
758 DECLARE_COMPUTATION(AllocateObject) | 805 DECLARE_COMPUTATION(AllocateObject) |
759 | 806 |
760 const Function& constructor() const { return ast_node_.constructor(); } | 807 const Function& constructor() const { return ast_node_.constructor(); } |
761 intptr_t token_index() const { return ast_node_.token_index(); } | 808 intptr_t token_index() const { return ast_node_.token_index(); } |
762 intptr_t try_index() const { return try_index_; } | 809 intptr_t try_index() const { return try_index_; } |
763 const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } | 810 const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } |
764 | 811 |
| 812 virtual intptr_t InputCount() const; |
| 813 |
765 private: | 814 private: |
766 const ConstructorCallNode& ast_node_; | 815 const ConstructorCallNode& ast_node_; |
767 const intptr_t try_index_; | 816 const intptr_t try_index_; |
768 ZoneGrowableArray<Value*>* const arguments_; | 817 ZoneGrowableArray<Value*>* const arguments_; |
769 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); | 818 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); |
770 }; | 819 }; |
771 | 820 |
772 | 821 |
773 class AllocateObjectWithBoundsCheckComp : public Computation { | 822 class AllocateObjectWithBoundsCheckComp : public Computation { |
774 public: | 823 public: |
775 AllocateObjectWithBoundsCheckComp(ConstructorCallNode* node, | 824 AllocateObjectWithBoundsCheckComp(ConstructorCallNode* node, |
776 intptr_t try_index, | 825 intptr_t try_index, |
777 ZoneGrowableArray<Value*>* arguments) | 826 ZoneGrowableArray<Value*>* arguments) |
778 : ast_node_(*node), try_index_(try_index), arguments_(arguments) { | 827 : ast_node_(*node), try_index_(try_index), arguments_(arguments) { |
779 // One type-argument and one instantiator. | 828 // One type-argument and one instantiator. |
780 ASSERT(arguments->length() == 2); | 829 ASSERT(arguments->length() == 2); |
781 } | 830 } |
782 | 831 |
783 DECLARE_COMPUTATION(AllocateObjectWithBoundsCheck) | 832 DECLARE_COMPUTATION(AllocateObjectWithBoundsCheck) |
784 | 833 |
785 const Function& constructor() const { return ast_node_.constructor(); } | 834 const Function& constructor() const { return ast_node_.constructor(); } |
786 intptr_t token_index() const { return ast_node_.token_index(); } | 835 intptr_t token_index() const { return ast_node_.token_index(); } |
787 intptr_t try_index() const { return try_index_; } | 836 intptr_t try_index() const { return try_index_; } |
788 const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } | 837 const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } |
789 | 838 |
| 839 virtual intptr_t InputCount() const; |
| 840 |
790 private: | 841 private: |
791 const ConstructorCallNode& ast_node_; | 842 const ConstructorCallNode& ast_node_; |
792 const intptr_t try_index_; | 843 const intptr_t try_index_; |
793 ZoneGrowableArray<Value*>* const arguments_; | 844 ZoneGrowableArray<Value*>* const arguments_; |
794 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); | 845 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); |
795 }; | 846 }; |
796 | 847 |
797 | 848 |
798 class CreateArrayComp : public Computation { | 849 class CreateArrayComp : public Computation { |
799 public: | 850 public: |
(...skipping 11 matching lines...) Expand all Loading... |
811 DECLARE_COMPUTATION(CreateArray) | 862 DECLARE_COMPUTATION(CreateArray) |
812 | 863 |
813 intptr_t token_index() const { return ast_node_.token_index(); } | 864 intptr_t token_index() const { return ast_node_.token_index(); } |
814 intptr_t try_index() const { return try_index_; } | 865 intptr_t try_index() const { return try_index_; } |
815 const AbstractTypeArguments& type_arguments() const { | 866 const AbstractTypeArguments& type_arguments() const { |
816 return ast_node_.type_arguments(); | 867 return ast_node_.type_arguments(); |
817 } | 868 } |
818 intptr_t ElementCount() const { return elements_->length(); } | 869 intptr_t ElementCount() const { return elements_->length(); } |
819 Value* ElementAt(intptr_t i) const { return (*elements_)[i]; } | 870 Value* ElementAt(intptr_t i) const { return (*elements_)[i]; } |
820 | 871 |
| 872 virtual intptr_t InputCount() const; |
| 873 |
821 private: | 874 private: |
822 const ArrayNode& ast_node_; | 875 const ArrayNode& ast_node_; |
823 const intptr_t try_index_; | 876 const intptr_t try_index_; |
824 ZoneGrowableArray<Value*>* const elements_; | 877 ZoneGrowableArray<Value*>* const elements_; |
825 | 878 |
826 DISALLOW_COPY_AND_ASSIGN(CreateArrayComp); | 879 DISALLOW_COPY_AND_ASSIGN(CreateArrayComp); |
827 }; | 880 }; |
828 | 881 |
829 | 882 |
830 class CreateClosureComp : public Computation { | 883 class CreateClosureComp : public Computation { |
831 public: | 884 public: |
832 // 'type_arguments' is null if function() does not require type arguments. | 885 // 'type_arguments' is null if function() does not require type arguments. |
833 CreateClosureComp(ClosureNode* node, | 886 CreateClosureComp(ClosureNode* node, |
834 intptr_t try_index, | 887 intptr_t try_index, |
835 Value* type_arguments) | 888 Value* type_arguments) |
836 : ast_node_(*node), | 889 : ast_node_(*node), |
837 try_index_(try_index), | 890 try_index_(try_index), |
838 type_arguments_(type_arguments) {} | 891 type_arguments_(type_arguments) {} |
839 | 892 |
840 DECLARE_COMPUTATION(CreateClosure) | 893 DECLARE_COMPUTATION(CreateClosure) |
841 | 894 |
842 intptr_t token_index() const { return ast_node_.token_index(); } | 895 intptr_t token_index() const { return ast_node_.token_index(); } |
843 intptr_t try_index() const { return try_index_; } | 896 intptr_t try_index() const { return try_index_; } |
844 const Function& function() const { return ast_node_.function(); } | 897 const Function& function() const { return ast_node_.function(); } |
845 Value* type_arguments() const { return type_arguments_; } | 898 Value* type_arguments() const { return type_arguments_; } |
846 | 899 |
| 900 virtual intptr_t InputCount() const; |
| 901 |
847 private: | 902 private: |
848 const ClosureNode& ast_node_; | 903 const ClosureNode& ast_node_; |
849 const intptr_t try_index_; | 904 const intptr_t try_index_; |
850 Value* type_arguments_; | 905 Value* type_arguments_; |
851 | 906 |
852 DISALLOW_COPY_AND_ASSIGN(CreateClosureComp); | 907 DISALLOW_COPY_AND_ASSIGN(CreateClosureComp); |
853 }; | 908 }; |
854 | 909 |
855 | 910 |
856 class NativeLoadFieldComp : public Computation { | 911 class NativeLoadFieldComp : public TemplateComputation<1> { |
857 public: | 912 public: |
858 NativeLoadFieldComp(Value* value, intptr_t offset_in_bytes) | 913 NativeLoadFieldComp(Value* value, intptr_t offset_in_bytes) |
859 : value_(value), offset_in_bytes_(offset_in_bytes) { | 914 : offset_in_bytes_(offset_in_bytes) { |
860 ASSERT(value != NULL); | 915 ASSERT(value != NULL); |
| 916 inputs_[0] = value; |
861 } | 917 } |
862 | 918 |
863 DECLARE_COMPUTATION(NativeLoadField) | 919 DECLARE_COMPUTATION(NativeLoadField) |
864 | 920 |
865 Value* value() const { return value_; } | 921 Value* value() { return inputs_[0]; } |
866 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 922 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
867 | 923 |
868 private: | 924 private: |
869 Value* value_; | |
870 intptr_t offset_in_bytes_; | 925 intptr_t offset_in_bytes_; |
871 | 926 |
872 DISALLOW_COPY_AND_ASSIGN(NativeLoadFieldComp); | 927 DISALLOW_COPY_AND_ASSIGN(NativeLoadFieldComp); |
873 }; | 928 }; |
874 | 929 |
875 | 930 |
876 class ExtractFactoryTypeArgumentsComp : public Computation { | 931 class ExtractFactoryTypeArgumentsComp : public TemplateComputation<1> { |
877 public: | 932 public: |
878 ExtractFactoryTypeArgumentsComp(ConstructorCallNode* ast_node, | 933 ExtractFactoryTypeArgumentsComp(ConstructorCallNode* ast_node, |
879 intptr_t try_index, | 934 intptr_t try_index, |
880 Value* instantiator) | 935 Value* instantiator) |
881 : ast_node_(*ast_node), | 936 : ast_node_(*ast_node), |
882 try_index_(try_index), | 937 try_index_(try_index) { |
883 instantiator_(instantiator) { | 938 ASSERT(instantiator != NULL); |
884 ASSERT(instantiator_ != NULL); | 939 inputs_[0] = instantiator; |
885 } | 940 } |
886 | 941 |
887 DECLARE_COMPUTATION(ExtractFactoryTypeArguments) | 942 DECLARE_COMPUTATION(ExtractFactoryTypeArguments) |
888 | 943 |
889 Value* instantiator() const { return instantiator_; } | 944 Value* instantiator() { return inputs_[0]; } |
890 const AbstractTypeArguments& type_arguments() const { | 945 const AbstractTypeArguments& type_arguments() const { |
891 return ast_node_.type_arguments(); | 946 return ast_node_.type_arguments(); |
892 } | 947 } |
893 const Function& factory() const { return ast_node_.constructor(); } | 948 const Function& factory() const { return ast_node_.constructor(); } |
894 intptr_t token_index() const { return ast_node_.token_index(); } | 949 intptr_t token_index() const { return ast_node_.token_index(); } |
895 intptr_t try_index() const { return try_index_; } | 950 intptr_t try_index() const { return try_index_; } |
896 | 951 |
897 private: | 952 private: |
898 const ConstructorCallNode& ast_node_; | 953 const ConstructorCallNode& ast_node_; |
899 const intptr_t try_index_; | 954 const intptr_t try_index_; |
900 Value* instantiator_; | |
901 | 955 |
902 DISALLOW_COPY_AND_ASSIGN(ExtractFactoryTypeArgumentsComp); | 956 DISALLOW_COPY_AND_ASSIGN(ExtractFactoryTypeArgumentsComp); |
903 }; | 957 }; |
904 | 958 |
905 | 959 |
906 class ExtractConstructorTypeArgumentsComp : public Computation { | 960 class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { |
907 public: | 961 public: |
908 ExtractConstructorTypeArgumentsComp(ConstructorCallNode* ast_node, | 962 ExtractConstructorTypeArgumentsComp(ConstructorCallNode* ast_node, |
909 Value* instantiator) | 963 Value* instantiator) |
910 : ast_node_(*ast_node), instantiator_(instantiator) { | 964 : ast_node_(*ast_node) { |
911 ASSERT(instantiator_ != NULL); | 965 ASSERT(instantiator != NULL); |
| 966 inputs_[0] = instantiator; |
912 } | 967 } |
913 | 968 |
914 DECLARE_COMPUTATION(ExtractConstructorTypeArguments) | 969 DECLARE_COMPUTATION(ExtractConstructorTypeArguments) |
915 | 970 |
916 Value* instantiator() const { return instantiator_; } | 971 Value* instantiator() { return inputs_[0]; } |
917 const AbstractTypeArguments& type_arguments() const { | 972 const AbstractTypeArguments& type_arguments() const { |
918 return ast_node_.type_arguments(); | 973 return ast_node_.type_arguments(); |
919 } | 974 } |
920 const Function& constructor() const { return ast_node_.constructor(); } | 975 const Function& constructor() const { return ast_node_.constructor(); } |
921 intptr_t token_index() const { return ast_node_.token_index(); } | 976 intptr_t token_index() const { return ast_node_.token_index(); } |
922 | 977 |
923 private: | 978 private: |
924 const ConstructorCallNode& ast_node_; | 979 const ConstructorCallNode& ast_node_; |
925 Value* instantiator_; | |
926 | 980 |
927 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); | 981 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); |
928 }; | 982 }; |
929 | 983 |
930 | 984 |
931 class ExtractConstructorInstantiatorComp : public Computation { | 985 class ExtractConstructorInstantiatorComp : public TemplateComputation<2> { |
932 public: | 986 public: |
933 ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, | 987 ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, |
934 Value* instantiator, | 988 Value* instantiator, |
935 Value* discard_value) | 989 Value* discard_value) |
936 : ast_node_(*ast_node), | 990 : ast_node_(*ast_node) { |
937 instantiator_(instantiator), | 991 ASSERT(instantiator != NULL); |
938 discard_value_(discard_value) { | 992 inputs_[0] = instantiator; |
939 ASSERT(instantiator_ != NULL); | 993 inputs_[1] = discard_value; |
940 } | 994 } |
941 | 995 |
942 DECLARE_COMPUTATION(ExtractConstructorInstantiator) | 996 DECLARE_COMPUTATION(ExtractConstructorInstantiator) |
943 | 997 |
944 Value* instantiator() const { return instantiator_; } | 998 Value* instantiator() { return inputs_[0]; } |
945 Value* discard_value() const { return discard_value_; } | 999 Value* discard_value() { return inputs_[1]; } |
946 const AbstractTypeArguments& type_arguments() const { | 1000 const AbstractTypeArguments& type_arguments() const { |
947 return ast_node_.type_arguments(); | 1001 return ast_node_.type_arguments(); |
948 } | 1002 } |
949 const Function& constructor() const { return ast_node_.constructor(); } | 1003 const Function& constructor() const { return ast_node_.constructor(); } |
950 intptr_t token_index() const { return ast_node_.token_index(); } | 1004 intptr_t token_index() const { return ast_node_.token_index(); } |
951 | 1005 |
952 private: | 1006 private: |
953 const ConstructorCallNode& ast_node_; | 1007 const ConstructorCallNode& ast_node_; |
954 Value* instantiator_; | |
955 Value* discard_value_; | |
956 | 1008 |
957 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); | 1009 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); |
958 }; | 1010 }; |
959 | 1011 |
960 | 1012 |
961 class AllocateContextComp : public Computation { | 1013 class AllocateContextComp : public TemplateComputation<0> { |
962 public: | 1014 public: |
963 AllocateContextComp(intptr_t token_index, | 1015 AllocateContextComp(intptr_t token_index, |
964 intptr_t try_index, | 1016 intptr_t try_index, |
965 intptr_t num_context_variables) | 1017 intptr_t num_context_variables) |
966 : token_index_(token_index), | 1018 : token_index_(token_index), |
967 try_index_(try_index), | 1019 try_index_(try_index), |
968 num_context_variables_(num_context_variables) {} | 1020 num_context_variables_(num_context_variables) {} |
969 | 1021 |
970 DECLARE_COMPUTATION(AllocateContext); | 1022 DECLARE_COMPUTATION(AllocateContext); |
971 | 1023 |
972 intptr_t token_index() const { return token_index_; } | 1024 intptr_t token_index() const { return token_index_; } |
973 intptr_t try_index() const { return try_index_; } | 1025 intptr_t try_index() const { return try_index_; } |
974 intptr_t num_context_variables() const { return num_context_variables_; } | 1026 intptr_t num_context_variables() const { return num_context_variables_; } |
975 | 1027 |
976 private: | 1028 private: |
977 const intptr_t token_index_; | 1029 const intptr_t token_index_; |
978 const intptr_t try_index_; | 1030 const intptr_t try_index_; |
979 const intptr_t num_context_variables_; | 1031 const intptr_t num_context_variables_; |
980 | 1032 |
981 DISALLOW_COPY_AND_ASSIGN(AllocateContextComp); | 1033 DISALLOW_COPY_AND_ASSIGN(AllocateContextComp); |
982 }; | 1034 }; |
983 | 1035 |
984 | 1036 |
985 class ChainContextComp : public Computation { | 1037 class ChainContextComp : public TemplateComputation<1> { |
986 public: | 1038 public: |
987 explicit ChainContextComp(Value* context_value) | 1039 explicit ChainContextComp(Value* context_value) { |
988 : context_value_(context_value) { | 1040 ASSERT(context_value != NULL); |
989 ASSERT(context_value_ != NULL); | 1041 inputs_[0] = context_value; |
990 } | 1042 } |
991 | 1043 |
992 DECLARE_COMPUTATION(ChainContext) | 1044 DECLARE_COMPUTATION(ChainContext) |
993 | 1045 |
994 Value* context_value() const { return context_value_; } | 1046 Value* context_value() { return inputs_[0]; } |
995 | 1047 |
996 private: | 1048 private: |
997 Value* context_value_; | |
998 | |
999 DISALLOW_COPY_AND_ASSIGN(ChainContextComp); | 1049 DISALLOW_COPY_AND_ASSIGN(ChainContextComp); |
1000 }; | 1050 }; |
1001 | 1051 |
1002 | 1052 |
1003 class CloneContextComp : public Computation { | 1053 class CloneContextComp : public TemplateComputation<1> { |
1004 public: | 1054 public: |
1005 CloneContextComp(intptr_t token_index, | 1055 CloneContextComp(intptr_t token_index, |
1006 intptr_t try_index, | 1056 intptr_t try_index, |
1007 Value* context_value) | 1057 Value* context_value) |
1008 : token_index_(token_index), | 1058 : token_index_(token_index), |
1009 try_index_(try_index), | 1059 try_index_(try_index) { |
1010 context_value_(context_value) { | 1060 ASSERT(context_value != NULL); |
1011 ASSERT(context_value_ != NULL); | 1061 inputs_[0] = context_value; |
1012 } | 1062 } |
1013 | 1063 |
1014 intptr_t token_index() const { return token_index_; } | 1064 intptr_t token_index() const { return token_index_; } |
1015 intptr_t try_index() const { return try_index_; } | 1065 intptr_t try_index() const { return try_index_; } |
1016 Value* context_value() const { return context_value_; } | 1066 Value* context_value() { return inputs_[0]; } |
1017 | 1067 |
1018 DECLARE_COMPUTATION(CloneContext) | 1068 DECLARE_COMPUTATION(CloneContext) |
1019 | 1069 |
1020 private: | 1070 private: |
1021 const intptr_t token_index_; | 1071 const intptr_t token_index_; |
1022 const intptr_t try_index_; | 1072 const intptr_t try_index_; |
1023 Value* context_value_; | |
1024 | 1073 |
1025 DISALLOW_COPY_AND_ASSIGN(CloneContextComp); | 1074 DISALLOW_COPY_AND_ASSIGN(CloneContextComp); |
1026 }; | 1075 }; |
1027 | 1076 |
1028 | 1077 |
1029 class CatchEntryComp : public Computation { | 1078 class CatchEntryComp : public TemplateComputation<0> { |
1030 public: | 1079 public: |
1031 CatchEntryComp(const LocalVariable& exception_var, | 1080 CatchEntryComp(const LocalVariable& exception_var, |
1032 const LocalVariable& stacktrace_var) | 1081 const LocalVariable& stacktrace_var) |
1033 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} | 1082 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} |
1034 | 1083 |
1035 const LocalVariable& exception_var() const { return exception_var_; } | 1084 const LocalVariable& exception_var() const { return exception_var_; } |
1036 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } | 1085 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } |
1037 | 1086 |
1038 DECLARE_COMPUTATION(CatchEntry) | 1087 DECLARE_COMPUTATION(CatchEntry) |
1039 | 1088 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 #define FORWARD_DECLARATION(type) class type##Instr; | 1129 #define FORWARD_DECLARATION(type) class type##Instr; |
1081 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 1130 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
1082 #undef FORWARD_DECLARATION | 1131 #undef FORWARD_DECLARATION |
1083 | 1132 |
1084 | 1133 |
1085 // Functions required in all concrete instruction classes. | 1134 // Functions required in all concrete instruction classes. |
1086 #define DECLARE_INSTRUCTION(type) \ | 1135 #define DECLARE_INSTRUCTION(type) \ |
1087 virtual Instruction* Accept(FlowGraphVisitor* visitor); \ | 1136 virtual Instruction* Accept(FlowGraphVisitor* visitor); \ |
1088 virtual bool Is##type() const { return true; } \ | 1137 virtual bool Is##type() const { return true; } \ |
1089 virtual type##Instr* As##type() { return this; } \ | 1138 virtual type##Instr* As##type() { return this; } \ |
| 1139 virtual intptr_t InputCount() const; \ |
1090 | 1140 |
1091 | 1141 |
1092 class Instruction : public ZoneAllocated { | 1142 class Instruction : public ZoneAllocated { |
1093 public: | 1143 public: |
1094 Instruction() : cid_(Computation::GetNextCid()) { } | 1144 Instruction() : cid_(Computation::GetNextCid()) { } |
1095 | 1145 |
1096 // Unique computation/instruction id, used for deoptimization, e.g. for | 1146 // Unique computation/instruction id, used for deoptimization, e.g. for |
1097 // ReturnInstr, ThrowInstr and ReThrowInstr. | 1147 // ReturnInstr, ThrowInstr and ReThrowInstr. |
1098 intptr_t cid() const { return cid_; } | 1148 intptr_t cid() const { return cid_; } |
1099 | 1149 |
1100 virtual bool IsBlockEntry() const { return false; } | 1150 virtual bool IsBlockEntry() const { return false; } |
1101 BlockEntryInstr* AsBlockEntry() { | 1151 BlockEntryInstr* AsBlockEntry() { |
1102 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; | 1152 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; |
1103 } | 1153 } |
| 1154 virtual bool IsDefinition() const { return false; } |
| 1155 Definition* AsDefinition() { |
| 1156 return IsDefinition() ? reinterpret_cast<Definition*>(this) : NULL; |
| 1157 } |
| 1158 |
| 1159 virtual intptr_t InputCount() const = 0; |
1104 | 1160 |
1105 // Visiting support. | 1161 // Visiting support. |
1106 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; | 1162 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; |
1107 | 1163 |
1108 virtual Instruction* StraightLineSuccessor() const = 0; | 1164 virtual Instruction* StraightLineSuccessor() const = 0; |
1109 virtual void SetSuccessor(Instruction* instr) = 0; | 1165 virtual void SetSuccessor(Instruction* instr) = 0; |
1110 | 1166 |
1111 // Discover basic-block structure by performing a recursive depth first | 1167 // Discover basic-block structure by performing a recursive depth first |
1112 // traversal of the instruction graph reachable from this instruction. As | 1168 // traversal of the instruction graph reachable from this instruction. As |
1113 // a side effect, the block entry instructions in the graph are assigned | 1169 // a side effect, the block entry instructions in the graph are assigned |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 private: | 1349 private: |
1294 Computation* computation_; | 1350 Computation* computation_; |
1295 Instruction* successor_; | 1351 Instruction* successor_; |
1296 | 1352 |
1297 DISALLOW_COPY_AND_ASSIGN(DoInstr); | 1353 DISALLOW_COPY_AND_ASSIGN(DoInstr); |
1298 }; | 1354 }; |
1299 | 1355 |
1300 | 1356 |
1301 class Definition : public Instruction { | 1357 class Definition : public Instruction { |
1302 public: | 1358 public: |
1303 explicit Definition(intptr_t temp_index) : temp_index_(temp_index) { } | 1359 Definition() : temp_index_(-1) { } |
| 1360 |
| 1361 virtual bool IsDefinition() const { return true; } |
1304 | 1362 |
1305 intptr_t temp_index() const { return temp_index_; } | 1363 intptr_t temp_index() const { return temp_index_; } |
| 1364 void set_temp_index(intptr_t index) { temp_index_ = index; } |
1306 | 1365 |
1307 private: | 1366 private: |
1308 const intptr_t temp_index_; | 1367 intptr_t temp_index_; |
1309 | 1368 |
1310 DISALLOW_COPY_AND_ASSIGN(Definition); | 1369 DISALLOW_COPY_AND_ASSIGN(Definition); |
1311 }; | 1370 }; |
1312 | 1371 |
1313 | 1372 |
1314 class BindInstr : public Definition { | 1373 class BindInstr : public Definition { |
1315 public: | 1374 public: |
1316 BindInstr(intptr_t temp_index, Computation* computation) | 1375 explicit BindInstr(Computation* computation) |
1317 : Definition(temp_index), computation_(computation), successor_(NULL) { } | 1376 : Definition(), computation_(computation), successor_(NULL) { } |
1318 | 1377 |
1319 DECLARE_INSTRUCTION(Bind) | 1378 DECLARE_INSTRUCTION(Bind) |
1320 | 1379 |
1321 Computation* computation() const { return computation_; } | 1380 Computation* computation() const { return computation_; } |
1322 | 1381 |
1323 virtual Instruction* StraightLineSuccessor() const { | 1382 virtual Instruction* StraightLineSuccessor() const { |
1324 return successor_; | 1383 return successor_; |
1325 } | 1384 } |
1326 virtual void SetSuccessor(Instruction* instr) { | 1385 virtual void SetSuccessor(Instruction* instr) { |
1327 ASSERT(successor_ == NULL); | 1386 ASSERT(successor_ == NULL); |
(...skipping 10 matching lines...) Expand all Loading... |
1338 | 1397 |
1339 // The non-optimizing compiler assumes that there is exactly one use of | 1398 // The non-optimizing compiler assumes that there is exactly one use of |
1340 // every temporary so they can be deallocated at their use. Some AST nodes, | 1399 // every temporary so they can be deallocated at their use. Some AST nodes, |
1341 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each | 1400 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each |
1342 // of the values expr0 and expr1). | 1401 // of the values expr0 and expr1). |
1343 // | 1402 // |
1344 // PickTemp is used to name (with 'destination') a copy of a live temporary | 1403 // PickTemp is used to name (with 'destination') a copy of a live temporary |
1345 // (named 'source') without counting as the use of the source. | 1404 // (named 'source') without counting as the use of the source. |
1346 class PickTempInstr : public Definition { | 1405 class PickTempInstr : public Definition { |
1347 public: | 1406 public: |
1348 PickTempInstr(intptr_t temp_index, intptr_t source) | 1407 explicit PickTempInstr(intptr_t source) |
1349 : Definition(temp_index), source_(source), successor_(NULL) { } | 1408 : Definition(), source_(source), successor_(NULL) { } |
1350 | 1409 |
1351 DECLARE_INSTRUCTION(PickTemp) | 1410 DECLARE_INSTRUCTION(PickTemp) |
1352 | 1411 |
1353 intptr_t source() const { return source_; } | 1412 intptr_t source() const { return source_; } |
1354 | 1413 |
1355 virtual Instruction* StraightLineSuccessor() const { | 1414 virtual Instruction* StraightLineSuccessor() const { |
1356 return successor_; | 1415 return successor_; |
1357 } | 1416 } |
1358 virtual void SetSuccessor(Instruction* instr) { | 1417 virtual void SetSuccessor(Instruction* instr) { |
1359 ASSERT(successor_ == NULL && instr != NULL); | 1418 ASSERT(successor_ == NULL && instr != NULL); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1579 const GrowableArray<BlockEntryInstr*>& block_order_; | 1638 const GrowableArray<BlockEntryInstr*>& block_order_; |
1580 | 1639 |
1581 private: | 1640 private: |
1582 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 1641 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
1583 }; | 1642 }; |
1584 | 1643 |
1585 | 1644 |
1586 } // namespace dart | 1645 } // namespace dart |
1587 | 1646 |
1588 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 1647 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |