OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 } | 300 } |
301 | 301 |
302 // Cast accessor. | 302 // Cast accessor. |
303 static TempLocation* cast(Value* value) { | 303 static TempLocation* cast(Value* value) { |
304 ASSERT(value->is_temporary()); | 304 ASSERT(value->is_temporary()); |
305 return reinterpret_cast<TempLocation*>(value); | 305 return reinterpret_cast<TempLocation*>(value); |
306 } | 306 } |
307 | 307 |
308 // Accessors. | 308 // Accessors. |
309 Where where() { return where_; } | 309 Where where() { return where_; } |
310 void set_where(Where where) { where_ = where; } | 310 void set_where(Where where) { |
| 311 ASSERT(where_ == TempLocation::NOT_ALLOCATED); |
| 312 where_ = where; |
| 313 } |
311 | 314 |
312 // Predicates. | 315 // Predicates. |
313 bool is_on_stack() { return where_ == STACK; } | 316 bool is_on_stack() { return where_ == STACK; } |
314 bool is_temporary() { return true; } | 317 bool is_temporary() { return true; } |
315 | 318 |
316 // Support for fast-compilation mode. Assume the temp has been allocated. | 319 // Support for fast-compilation mode. Assume the temp has been allocated. |
317 void Get(MacroAssembler* masm, Register reg); | 320 void Get(MacroAssembler* masm, Register reg); |
318 void Set(MacroAssembler* masm, Register reg); | 321 void Set(MacroAssembler* masm, Register reg); |
319 void Push(MacroAssembler* masm); | 322 void Push(MacroAssembler* masm); |
320 void Move(MacroAssembler* masm, Value* value); | 323 void Move(MacroAssembler* masm, Value* value); |
(...skipping 15 matching lines...) Expand all Loading... |
336 int number_; | 339 int number_; |
337 #endif | 340 #endif |
338 }; | 341 }; |
339 | 342 |
340 | 343 |
341 // Instructions are computations. The represent non-trivial source | 344 // Instructions are computations. The represent non-trivial source |
342 // expressions: typically ones that have side effects and require code to | 345 // expressions: typically ones that have side effects and require code to |
343 // be generated. | 346 // be generated. |
344 class Instruction : public ZoneObject { | 347 class Instruction : public ZoneObject { |
345 public: | 348 public: |
346 // Every instruction has a location where its result is stored (which may | |
347 // be Nowhere, the default). | |
348 Instruction() : location_(CfgGlobals::current()->nowhere()) {} | |
349 | |
350 explicit Instruction(Location* location) : location_(location) {} | |
351 | |
352 virtual ~Instruction() {} | |
353 | |
354 // Accessors. | 349 // Accessors. |
355 Location* location() { return location_; } | 350 Location* location() { return location_; } |
356 void set_location(Location* location) { location_ = location; } | 351 void set_location(Location* location) { location_ = location; } |
357 | 352 |
358 // Support for fast-compilation mode: | 353 // Support for fast-compilation mode: |
359 | 354 |
360 // Emit code to perform the instruction. | 355 // Emit code to perform the instruction. |
361 virtual void Compile(MacroAssembler* masm) = 0; | 356 virtual void Compile(MacroAssembler* masm) = 0; |
362 | 357 |
363 // Allocate a temporary which is the result of the immediate predecessor | 358 // Allocate a temporary which is the result of the immediate predecessor |
364 // instruction. It is allocated to the accumulator register if it is used | 359 // instruction. It is allocated to the accumulator register if it is used |
365 // as an operand to this instruction, otherwise to the stack. | 360 // as an operand to this instruction, otherwise to the stack. |
366 virtual void FastAllocate(TempLocation* temp) = 0; | 361 virtual void FastAllocate(TempLocation* temp) = 0; |
367 | 362 |
368 #ifdef DEBUG | 363 #ifdef DEBUG |
369 virtual void Print() = 0; | 364 virtual void Print() = 0; |
370 #endif | 365 #endif |
371 | 366 |
372 protected: | 367 protected: |
| 368 // Every instruction has a location where its result is stored (which may |
| 369 // be Nowhere). |
| 370 explicit Instruction(Location* location) : location_(location) {} |
| 371 |
| 372 virtual ~Instruction() {} |
| 373 |
373 Location* location_; | 374 Location* location_; |
374 }; | 375 }; |
375 | 376 |
376 | 377 |
| 378 // Base class of instructions that have no input operands. |
| 379 class ZeroOperandInstruction : public Instruction { |
| 380 public: |
| 381 // Support for fast-compilation mode: |
| 382 virtual void Compile(MacroAssembler* masm) = 0; |
| 383 void FastAllocate(TempLocation* temp); |
| 384 |
| 385 #ifdef DEBUG |
| 386 // Printing support: print the operands (nothing). |
| 387 virtual void Print() {} |
| 388 #endif |
| 389 |
| 390 protected: |
| 391 explicit ZeroOperandInstruction(Location* loc) : Instruction(loc) {} |
| 392 }; |
| 393 |
| 394 |
| 395 // Base class of instructions that have a single input operand. |
| 396 class OneOperandInstruction : public Instruction { |
| 397 public: |
| 398 // Support for fast-compilation mode: |
| 399 virtual void Compile(MacroAssembler* masm) = 0; |
| 400 void FastAllocate(TempLocation* temp); |
| 401 |
| 402 #ifdef DEBUG |
| 403 // Printing support: print the operands. |
| 404 virtual void Print(); |
| 405 #endif |
| 406 |
| 407 protected: |
| 408 OneOperandInstruction(Location* loc, Value* value) |
| 409 : Instruction(loc), value_(value) { |
| 410 } |
| 411 |
| 412 Value* value_; |
| 413 }; |
| 414 |
| 415 |
| 416 // Base class of instructions that have two input operands. |
| 417 class TwoOperandInstruction : public Instruction { |
| 418 protected: |
| 419 // Support for fast-compilation mode: |
| 420 virtual void Compile(MacroAssembler* masm) = 0; |
| 421 void FastAllocate(TempLocation* temp); |
| 422 |
| 423 #ifdef DEBUG |
| 424 // Printing support: print the operands. |
| 425 virtual void Print(); |
| 426 #endif |
| 427 |
| 428 protected: |
| 429 TwoOperandInstruction(Location* loc, Value* value0, Value* value1) |
| 430 : Instruction(loc), value0_(value0), value1_(value1) { |
| 431 } |
| 432 |
| 433 Value* value0_; |
| 434 Value* value1_; |
| 435 }; |
| 436 |
| 437 |
377 // A phantom instruction that indicates the start of a statement. It | 438 // A phantom instruction that indicates the start of a statement. It |
378 // causes the statement position to be recorded in the relocation | 439 // causes the statement position to be recorded in the relocation |
379 // information but generates no code. | 440 // information but generates no code. |
380 class PositionInstr : public Instruction { | 441 class PositionInstr : public ZeroOperandInstruction { |
381 public: | 442 public: |
382 explicit PositionInstr(int pos) : pos_(pos) {} | 443 explicit PositionInstr(int pos) |
| 444 : ZeroOperandInstruction(CfgGlobals::current()->nowhere()), pos_(pos) { |
| 445 } |
383 | 446 |
384 // Support for fast-compilation mode. | 447 // Support for fast-compilation mode. |
385 void Compile(MacroAssembler* masm); | 448 void Compile(MacroAssembler* masm); |
386 | 449 |
387 // This should not be called. The last instruction of the previous | 450 // This should not be called. The last instruction of the previous |
388 // statement should not have a temporary as its location. | 451 // statement should not have a temporary as its location. |
389 void FastAllocate(TempLocation* temp) { UNREACHABLE(); } | 452 void FastAllocate(TempLocation* temp) { UNREACHABLE(); } |
390 | 453 |
391 #ifdef DEBUG | 454 #ifdef DEBUG |
392 // Printing support. Print nothing. | 455 // Printing support. Print nothing. |
393 void Print() {} | 456 void Print() {} |
394 #endif | 457 #endif |
395 | 458 |
396 private: | 459 private: |
397 int pos_; | 460 int pos_; |
398 }; | 461 }; |
399 | 462 |
400 | 463 |
401 // Move a value to a location. | 464 // Move a value to a location. |
402 class MoveInstr : public Instruction { | 465 class MoveInstr : public OneOperandInstruction { |
403 public: | 466 public: |
404 MoveInstr(Location* loc, Value* value) : Instruction(loc), value_(value) {} | 467 MoveInstr(Location* loc, Value* value) |
| 468 : OneOperandInstruction(loc, value) { |
| 469 } |
405 | 470 |
406 // Accessors. | 471 // Accessors. |
407 Value* value() { return value_; } | 472 Value* value() { return value_; } |
408 | 473 |
409 // Support for fast-compilation mode. | 474 // Support for fast-compilation mode. |
410 void Compile(MacroAssembler* masm); | 475 void Compile(MacroAssembler* masm); |
411 void FastAllocate(TempLocation* temp); | 476 |
| 477 #ifdef DEBUG |
| 478 // Printing support. |
| 479 void Print(); |
| 480 #endif |
| 481 }; |
| 482 |
| 483 |
| 484 // Load a property from a receiver, leaving the result in a location. |
| 485 class PropLoadInstr : public TwoOperandInstruction { |
| 486 public: |
| 487 PropLoadInstr(Location* loc, Value* object, Value* key) |
| 488 : TwoOperandInstruction(loc, object, key) { |
| 489 } |
| 490 |
| 491 // Accessors. |
| 492 Value* object() { return value0_; } |
| 493 Value* key() { return value1_; } |
| 494 |
| 495 // Support for fast-compilation mode. |
| 496 void Compile(MacroAssembler* masm); |
412 | 497 |
413 #ifdef DEBUG | 498 #ifdef DEBUG |
414 void Print(); | 499 void Print(); |
415 #endif | 500 #endif |
416 | |
417 private: | |
418 Value* value_; | |
419 }; | |
420 | |
421 | |
422 // Load a property from a receiver, leaving the result in a location. | |
423 class PropLoadInstr : public Instruction { | |
424 public: | |
425 PropLoadInstr(Location* loc, Value* object, Value* key) | |
426 : Instruction(loc), object_(object), key_(key) { | |
427 } | |
428 | |
429 // Accessors. | |
430 Value* object() { return object_; } | |
431 Value* key() { return key_; } | |
432 | |
433 // Support for fast-compilation mode. | |
434 void Compile(MacroAssembler* masm); | |
435 void FastAllocate(TempLocation* temp); | |
436 | |
437 #ifdef DEBUG | |
438 void Print(); | |
439 #endif | |
440 | |
441 private: | |
442 Value* object_; | |
443 Value* key_; | |
444 }; | 501 }; |
445 | 502 |
446 | 503 |
447 // Perform a (non-short-circuited) binary operation on a pair of values, | 504 // Perform a (non-short-circuited) binary operation on a pair of values, |
448 // leaving the result in a location. | 505 // leaving the result in a location. |
449 class BinaryOpInstr : public Instruction { | 506 class BinaryOpInstr : public TwoOperandInstruction { |
450 public: | 507 public: |
451 BinaryOpInstr(Location* loc, Token::Value op, Value* left, Value* right) | 508 BinaryOpInstr(Location* loc, Token::Value op, Value* left, Value* right) |
452 : Instruction(loc), op_(op), left_(left), right_(right) { | 509 : TwoOperandInstruction(loc, left, right), op_(op) { |
453 } | 510 } |
454 | 511 |
455 // Accessors. | 512 // Accessors. |
| 513 Value* left() { return value0_; } |
| 514 Value* right() { return value1_; } |
456 Token::Value op() { return op_; } | 515 Token::Value op() { return op_; } |
457 Value* left() { return left_; } | |
458 Value* right() { return right_; } | |
459 | 516 |
460 // Support for fast-compilation mode. | 517 // Support for fast-compilation mode. |
461 void Compile(MacroAssembler* masm); | 518 void Compile(MacroAssembler* masm); |
462 void FastAllocate(TempLocation* temp); | |
463 | 519 |
464 #ifdef DEBUG | 520 #ifdef DEBUG |
465 void Print(); | 521 void Print(); |
466 #endif | 522 #endif |
467 | 523 |
468 private: | 524 private: |
469 Token::Value op_; | 525 Token::Value op_; |
470 Value* left_; | |
471 Value* right_; | |
472 }; | 526 }; |
473 | 527 |
474 | 528 |
475 // Return a value. Has the side effect of moving its value into the return | 529 // Return a value. Has the side effect of moving its value into the return |
476 // value register. Can only occur as the last instruction in an instruction | 530 // value register. Can only occur as the last instruction in an instruction |
477 // block, and implies that the block is closed (cannot have instructions | 531 // block, and implies that the block is closed (cannot have instructions |
478 // appended or graph fragments concatenated to the end) and that the block's | 532 // appended or graph fragments concatenated to the end) and that the block's |
479 // successor is the global exit node for the current function. | 533 // successor is the global exit node for the current function. |
480 class ReturnInstr : public Instruction { | 534 class ReturnInstr : public OneOperandInstruction { |
481 public: | 535 public: |
482 explicit ReturnInstr(Value* value) : value_(value) {} | 536 explicit ReturnInstr(Value* value) |
| 537 : OneOperandInstruction(CfgGlobals::current()->nowhere(), value) { |
| 538 } |
483 | 539 |
484 virtual ~ReturnInstr() {} | 540 virtual ~ReturnInstr() {} |
485 | 541 |
486 // Accessors. | 542 // Accessors. |
487 Value* value() { return value_; } | 543 Value* value() { return value_; } |
488 | 544 |
489 // Support for fast-compilation mode. | 545 // Support for fast-compilation mode. |
490 void Compile(MacroAssembler* masm); | 546 void Compile(MacroAssembler* masm); |
491 void FastAllocate(TempLocation* temp); | |
492 | 547 |
493 #ifdef DEBUG | 548 #ifdef DEBUG |
494 void Print(); | 549 void Print(); |
495 #endif | 550 #endif |
496 | |
497 private: | |
498 Value* value_; | |
499 }; | 551 }; |
500 | 552 |
501 | 553 |
502 // Nodes make up control-flow graphs. | 554 // Nodes make up control-flow graphs. |
503 class CfgNode : public ZoneObject { | 555 class CfgNode : public ZoneObject { |
504 public: | 556 public: |
505 CfgNode() : is_marked_(false) { | 557 CfgNode() : is_marked_(false) { |
506 #ifdef DEBUG | 558 #ifdef DEBUG |
507 number_ = -1; | 559 number_ = -1; |
508 #endif | 560 #endif |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 | 862 |
811 private: | 863 private: |
812 // State for the visitor. Input/output parameter: | 864 // State for the visitor. Input/output parameter: |
813 Cfg* graph_; | 865 Cfg* graph_; |
814 }; | 866 }; |
815 | 867 |
816 | 868 |
817 } } // namespace v8::internal | 869 } } // namespace v8::internal |
818 | 870 |
819 #endif // V8_CFG_H_ | 871 #endif // V8_CFG_H_ |
OLD | NEW |