OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 174 |
175 // BinaryOpStub needs to override this. | 175 // BinaryOpStub needs to override this. |
176 virtual int GetCodeKind(); | 176 virtual int GetCodeKind(); |
177 | 177 |
178 // BinaryOpStub needs to override this. | 178 // BinaryOpStub needs to override this. |
179 virtual InlineCacheState GetICState() { | 179 virtual InlineCacheState GetICState() { |
180 return UNINITIALIZED; | 180 return UNINITIALIZED; |
181 } | 181 } |
182 | 182 |
183 // Returns a name for logging/debugging purposes. | 183 // Returns a name for logging/debugging purposes. |
184 virtual const char* GetName() { return MajorName(MajorKey(), false); } | 184 SmartPointer<const char> GetName(); |
| 185 virtual void PrintName(StringStream* stream) { |
| 186 stream->Add("%s", MajorName(MajorKey(), false)); |
| 187 } |
185 | 188 |
186 // Returns whether the code generated for this stub needs to be allocated as | 189 // Returns whether the code generated for this stub needs to be allocated as |
187 // a fixed (non-moveable) code object. | 190 // a fixed (non-moveable) code object. |
188 virtual bool NeedsImmovableCode() { return false; } | 191 virtual bool NeedsImmovableCode() { return false; } |
189 | 192 |
190 #ifdef DEBUG | |
191 virtual void Print() { PrintF("%s\n", GetName()); } | |
192 #endif | |
193 | |
194 // Computes the key based on major and minor. | 193 // Computes the key based on major and minor. |
195 uint32_t GetKey() { | 194 uint32_t GetKey() { |
196 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); | 195 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); |
197 return MinorKeyBits::encode(MinorKey()) | | 196 return MinorKeyBits::encode(MinorKey()) | |
198 MajorKeyBits::encode(MajorKey()); | 197 MajorKeyBits::encode(MajorKey()); |
199 } | 198 } |
200 | 199 |
201 // See comment above, where Instanceof is defined. | 200 // See comment above, where Instanceof is defined. |
202 bool AllowsStubCalls() { return MajorKey() <= Instanceof; } | 201 bool AllowsStubCalls() { return MajorKey() <= Instanceof; } |
203 | 202 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 354 |
356 class InstanceofStub: public CodeStub { | 355 class InstanceofStub: public CodeStub { |
357 public: | 356 public: |
358 enum Flags { | 357 enum Flags { |
359 kNoFlags = 0, | 358 kNoFlags = 0, |
360 kArgsInRegisters = 1 << 0, | 359 kArgsInRegisters = 1 << 0, |
361 kCallSiteInlineCheck = 1 << 1, | 360 kCallSiteInlineCheck = 1 << 1, |
362 kReturnTrueFalseObject = 1 << 2 | 361 kReturnTrueFalseObject = 1 << 2 |
363 }; | 362 }; |
364 | 363 |
365 explicit InstanceofStub(Flags flags) : flags_(flags), name_(NULL) { } | 364 explicit InstanceofStub(Flags flags) : flags_(flags) { } |
366 | 365 |
367 static Register left(); | 366 static Register left(); |
368 static Register right(); | 367 static Register right(); |
369 | 368 |
370 void Generate(MacroAssembler* masm); | 369 void Generate(MacroAssembler* masm); |
371 | 370 |
372 private: | 371 private: |
373 Major MajorKey() { return Instanceof; } | 372 Major MajorKey() { return Instanceof; } |
374 int MinorKey() { return static_cast<int>(flags_); } | 373 int MinorKey() { return static_cast<int>(flags_); } |
375 | 374 |
376 bool HasArgsInRegisters() const { | 375 bool HasArgsInRegisters() const { |
377 return (flags_ & kArgsInRegisters) != 0; | 376 return (flags_ & kArgsInRegisters) != 0; |
378 } | 377 } |
379 | 378 |
380 bool HasCallSiteInlineCheck() const { | 379 bool HasCallSiteInlineCheck() const { |
381 return (flags_ & kCallSiteInlineCheck) != 0; | 380 return (flags_ & kCallSiteInlineCheck) != 0; |
382 } | 381 } |
383 | 382 |
384 bool ReturnTrueFalseObject() const { | 383 bool ReturnTrueFalseObject() const { |
385 return (flags_ & kReturnTrueFalseObject) != 0; | 384 return (flags_ & kReturnTrueFalseObject) != 0; |
386 } | 385 } |
387 | 386 |
388 virtual const char* GetName(); | 387 virtual void PrintName(StringStream* stream); |
389 | 388 |
390 Flags flags_; | 389 Flags flags_; |
391 char* name_; | |
392 }; | 390 }; |
393 | 391 |
394 | 392 |
395 class MathPowStub: public CodeStub { | 393 class MathPowStub: public CodeStub { |
396 public: | 394 public: |
397 MathPowStub() {} | 395 MathPowStub() {} |
398 virtual void Generate(MacroAssembler* masm); | 396 virtual void Generate(MacroAssembler* masm); |
399 | 397 |
400 private: | 398 private: |
401 virtual CodeStub::Major MajorKey() { return MathPow; } | 399 virtual CodeStub::Major MajorKey() { return MathPow; } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 bool strict, | 457 bool strict, |
460 CompareFlags flags, | 458 CompareFlags flags, |
461 Register lhs, | 459 Register lhs, |
462 Register rhs) : | 460 Register rhs) : |
463 cc_(cc), | 461 cc_(cc), |
464 strict_(strict), | 462 strict_(strict), |
465 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), | 463 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
466 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), | 464 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
467 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), | 465 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
468 lhs_(lhs), | 466 lhs_(lhs), |
469 rhs_(rhs), | 467 rhs_(rhs) { } |
470 name_(NULL) { } | |
471 | 468 |
472 CompareStub(Condition cc, | 469 CompareStub(Condition cc, |
473 bool strict, | 470 bool strict, |
474 CompareFlags flags) : | 471 CompareFlags flags) : |
475 cc_(cc), | 472 cc_(cc), |
476 strict_(strict), | 473 strict_(strict), |
477 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), | 474 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
478 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), | 475 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
479 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), | 476 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
480 lhs_(no_reg), | 477 lhs_(no_reg), |
481 rhs_(no_reg), | 478 rhs_(no_reg) { } |
482 name_(NULL) { } | |
483 | 479 |
484 void Generate(MacroAssembler* masm); | 480 void Generate(MacroAssembler* masm); |
485 | 481 |
486 private: | 482 private: |
487 Condition cc_; | 483 Condition cc_; |
488 bool strict_; | 484 bool strict_; |
489 // Only used for 'equal' comparisons. Tells the stub that we already know | 485 // Only used for 'equal' comparisons. Tells the stub that we already know |
490 // that at least one side of the comparison is not NaN. This allows the | 486 // that at least one side of the comparison is not NaN. This allows the |
491 // stub to use object identity in the positive case. We ignore it when | 487 // stub to use object identity in the positive case. We ignore it when |
492 // generating the minor key for other comparisons to avoid creating more | 488 // generating the minor key for other comparisons to avoid creating more |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 } | 522 } |
527 | 523 |
528 // Branch to the label if the given object isn't a symbol. | 524 // Branch to the label if the given object isn't a symbol. |
529 void BranchIfNonSymbol(MacroAssembler* masm, | 525 void BranchIfNonSymbol(MacroAssembler* masm, |
530 Label* label, | 526 Label* label, |
531 Register object, | 527 Register object, |
532 Register scratch); | 528 Register scratch); |
533 | 529 |
534 // Unfortunately you have to run without snapshots to see most of these | 530 // Unfortunately you have to run without snapshots to see most of these |
535 // names in the profile since most compare stubs end up in the snapshot. | 531 // names in the profile since most compare stubs end up in the snapshot. |
536 char* name_; | 532 virtual void PrintName(StringStream* stream); |
537 virtual const char* GetName(); | |
538 #ifdef DEBUG | |
539 void Print() { | |
540 PrintF("CompareStub (minor %d) (cc %d), (strict %s), " | |
541 "(never_nan_nan %s), (smi_compare %s) (number_compare %s) ", | |
542 MinorKey(), | |
543 static_cast<int>(cc_), | |
544 strict_ ? "true" : "false", | |
545 never_nan_nan_ ? "true" : "false", | |
546 include_smi_compare_ ? "inluded" : "not included", | |
547 include_number_compare_ ? "included" : "not included"); | |
548 | |
549 if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) { | |
550 PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code()); | |
551 } else { | |
552 PrintF("\n"); | |
553 } | |
554 } | |
555 #endif | |
556 }; | 533 }; |
557 | 534 |
558 | 535 |
559 class CEntryStub : public CodeStub { | 536 class CEntryStub : public CodeStub { |
560 public: | 537 public: |
561 explicit CEntryStub(int result_size) | 538 explicit CEntryStub(int result_size) |
562 : result_size_(result_size), save_doubles_(false) { } | 539 : result_size_(result_size), save_doubles_(false) { } |
563 | 540 |
564 void Generate(MacroAssembler* masm); | 541 void Generate(MacroAssembler* masm); |
565 void SaveDoubles() { save_doubles_ = true; } | 542 void SaveDoubles() { save_doubles_ = true; } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 | 580 |
604 class JSConstructEntryStub : public JSEntryStub { | 581 class JSConstructEntryStub : public JSEntryStub { |
605 public: | 582 public: |
606 JSConstructEntryStub() { } | 583 JSConstructEntryStub() { } |
607 | 584 |
608 void Generate(MacroAssembler* masm) { GenerateBody(masm, true); } | 585 void Generate(MacroAssembler* masm) { GenerateBody(masm, true); } |
609 | 586 |
610 private: | 587 private: |
611 int MinorKey() { return 1; } | 588 int MinorKey() { return 1; } |
612 | 589 |
613 virtual const char* GetName() { return "JSConstructEntryStub"; } | 590 virtual void PrintName(StringStream* stream) { |
| 591 stream->Add("JSConstructEntryStub"); |
| 592 } |
614 }; | 593 }; |
615 | 594 |
616 | 595 |
617 class ArgumentsAccessStub: public CodeStub { | 596 class ArgumentsAccessStub: public CodeStub { |
618 public: | 597 public: |
619 enum Type { | 598 enum Type { |
620 READ_ELEMENT, | 599 READ_ELEMENT, |
621 NEW_NON_STRICT_FAST, | 600 NEW_NON_STRICT_FAST, |
622 NEW_NON_STRICT_SLOW, | 601 NEW_NON_STRICT_SLOW, |
623 NEW_STRICT | 602 NEW_STRICT |
624 }; | 603 }; |
625 | 604 |
626 explicit ArgumentsAccessStub(Type type) : type_(type) { } | 605 explicit ArgumentsAccessStub(Type type) : type_(type) { } |
627 | 606 |
628 private: | 607 private: |
629 Type type_; | 608 Type type_; |
630 | 609 |
631 Major MajorKey() { return ArgumentsAccess; } | 610 Major MajorKey() { return ArgumentsAccess; } |
632 int MinorKey() { return type_; } | 611 int MinorKey() { return type_; } |
633 | 612 |
634 void Generate(MacroAssembler* masm); | 613 void Generate(MacroAssembler* masm); |
635 void GenerateReadElement(MacroAssembler* masm); | 614 void GenerateReadElement(MacroAssembler* masm); |
636 void GenerateNewStrict(MacroAssembler* masm); | 615 void GenerateNewStrict(MacroAssembler* masm); |
637 void GenerateNewNonStrictFast(MacroAssembler* masm); | 616 void GenerateNewNonStrictFast(MacroAssembler* masm); |
638 void GenerateNewNonStrictSlow(MacroAssembler* masm); | 617 void GenerateNewNonStrictSlow(MacroAssembler* masm); |
639 | 618 |
640 #ifdef DEBUG | 619 virtual void PrintName(StringStream* stream); |
641 void Print() { | |
642 PrintF("ArgumentsAccessStub (type %d)\n", type_); | |
643 } | |
644 #endif | |
645 }; | 620 }; |
646 | 621 |
647 | 622 |
648 class RegExpExecStub: public CodeStub { | 623 class RegExpExecStub: public CodeStub { |
649 public: | 624 public: |
650 RegExpExecStub() { } | 625 RegExpExecStub() { } |
651 | 626 |
652 private: | 627 private: |
653 Major MajorKey() { return RegExpExec; } | 628 Major MajorKey() { return RegExpExec; } |
654 int MinorKey() { return 0; } | 629 int MinorKey() { return 0; } |
(...skipping 23 matching lines...) Expand all Loading... |
678 | 653 |
679 static int ExtractArgcFromMinorKey(int minor_key) { | 654 static int ExtractArgcFromMinorKey(int minor_key) { |
680 return ArgcBits::decode(minor_key); | 655 return ArgcBits::decode(minor_key); |
681 } | 656 } |
682 | 657 |
683 private: | 658 private: |
684 int argc_; | 659 int argc_; |
685 InLoopFlag in_loop_; | 660 InLoopFlag in_loop_; |
686 CallFunctionFlags flags_; | 661 CallFunctionFlags flags_; |
687 | 662 |
688 #ifdef DEBUG | 663 virtual void PrintName(StringStream* stream); |
689 void Print() { | |
690 PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n", | |
691 argc_, | |
692 static_cast<int>(in_loop_), | |
693 static_cast<int>(flags_)); | |
694 } | |
695 #endif | |
696 | 664 |
697 // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. | 665 // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. |
698 class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; | 666 class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; |
699 class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; | 667 class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; |
700 class ArgcBits: public BitField<int, 2, 32 - 2> {}; | 668 class ArgcBits: public BitField<int, 2, 32 - 2> {}; |
701 | 669 |
702 Major MajorKey() { return CallFunction; } | 670 Major MajorKey() { return CallFunction; } |
703 int MinorKey() { | 671 int MinorKey() { |
704 // Encode the parameters in a unique 32 bit value. | 672 // Encode the parameters in a unique 32 bit value. |
705 return InLoopBits::encode(in_loop_) | 673 return InLoopBits::encode(in_loop_) |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 | 906 |
939 private: | 907 private: |
940 Register tos_; | 908 Register tos_; |
941 Major MajorKey() { return ToBoolean; } | 909 Major MajorKey() { return ToBoolean; } |
942 int MinorKey() { return tos_.code(); } | 910 int MinorKey() { return tos_.code(); } |
943 }; | 911 }; |
944 | 912 |
945 } } // namespace v8::internal | 913 } } // namespace v8::internal |
946 | 914 |
947 #endif // V8_CODE_STUBS_H_ | 915 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |