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

Side by Side Diff: src/code-stubs.h

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback; fixed tests Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ast.cc ('k') | src/code-stubs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 virtual void Generate(MacroAssembler* masm); 475 virtual void Generate(MacroAssembler* masm);
476 476
477 private: 477 private:
478 virtual CodeStub::Major MajorKey() { return MathPow; } 478 virtual CodeStub::Major MajorKey() { return MathPow; }
479 virtual int MinorKey() { return exponent_type_; } 479 virtual int MinorKey() { return exponent_type_; }
480 480
481 ExponentType exponent_type_; 481 ExponentType exponent_type_;
482 }; 482 };
483 483
484 484
485 class BinaryOpStub: public CodeStub {
486 public:
487 BinaryOpStub(Token::Value op, OverwriteMode mode)
488 : op_(op),
489 mode_(mode),
490 platform_specific_bit_(false),
491 left_type_(BinaryOpIC::UNINITIALIZED),
492 right_type_(BinaryOpIC::UNINITIALIZED),
493 result_type_(BinaryOpIC::UNINITIALIZED) {
494 Initialize();
495 ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
496 }
497
498 BinaryOpStub(
499 int key,
500 BinaryOpIC::TypeInfo left_type,
501 BinaryOpIC::TypeInfo right_type,
502 BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
503 : op_(OpBits::decode(key)),
504 mode_(ModeBits::decode(key)),
505 platform_specific_bit_(PlatformSpecificBits::decode(key)),
506 left_type_(left_type),
507 right_type_(right_type),
508 result_type_(result_type) { }
509
510 static void decode_types_from_minor_key(int minor_key,
511 BinaryOpIC::TypeInfo* left_type,
512 BinaryOpIC::TypeInfo* right_type,
513 BinaryOpIC::TypeInfo* result_type) {
514 *left_type =
515 static_cast<BinaryOpIC::TypeInfo>(LeftTypeBits::decode(minor_key));
516 *right_type =
517 static_cast<BinaryOpIC::TypeInfo>(RightTypeBits::decode(minor_key));
518 *result_type =
519 static_cast<BinaryOpIC::TypeInfo>(ResultTypeBits::decode(minor_key));
520 }
521
522 static Token::Value decode_op_from_minor_key(int minor_key) {
523 return static_cast<Token::Value>(OpBits::decode(minor_key));
524 }
525
526 enum SmiCodeGenerateHeapNumberResults {
527 ALLOW_HEAPNUMBER_RESULTS,
528 NO_HEAPNUMBER_RESULTS
529 };
530
531 private:
532 Token::Value op_;
533 OverwriteMode mode_;
534 bool platform_specific_bit_; // Indicates SSE3 on IA32, VFP2 on ARM.
535
536 // Operand type information determined at runtime.
537 BinaryOpIC::TypeInfo left_type_;
538 BinaryOpIC::TypeInfo right_type_;
539 BinaryOpIC::TypeInfo result_type_;
540
541 virtual void PrintName(StringStream* stream);
542
543 // Minor key encoding in 19 bits TTTRRRLLLSOOOOOOOMM.
544 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
545 class OpBits: public BitField<Token::Value, 2, 7> {};
546 class PlatformSpecificBits: public BitField<bool, 9, 1> {};
547 class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
548 class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
549 class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
550
551 Major MajorKey() { return BinaryOp; }
552 int MinorKey() {
553 return OpBits::encode(op_)
554 | ModeBits::encode(mode_)
555 | PlatformSpecificBits::encode(platform_specific_bit_)
556 | LeftTypeBits::encode(left_type_)
557 | RightTypeBits::encode(right_type_)
558 | ResultTypeBits::encode(result_type_);
559 }
560
561
562 // Platform-independent implementation.
563 void Generate(MacroAssembler* masm);
564 void GenerateCallRuntime(MacroAssembler* masm);
565
566 // Platform-independent signature, platform-specific implementation.
567 void Initialize();
568 void GenerateAddStrings(MacroAssembler* masm);
569 void GenerateBothStringStub(MacroAssembler* masm);
570 void GenerateGeneric(MacroAssembler* masm);
571 void GenerateGenericStub(MacroAssembler* masm);
572 void GenerateHeapNumberStub(MacroAssembler* masm);
573 void GenerateInt32Stub(MacroAssembler* masm);
574 void GenerateLoadArguments(MacroAssembler* masm);
575 void GenerateOddballStub(MacroAssembler* masm);
576 void GenerateRegisterArgsPush(MacroAssembler* masm);
577 void GenerateReturn(MacroAssembler* masm);
578 void GenerateSmiStub(MacroAssembler* masm);
579 void GenerateStringStub(MacroAssembler* masm);
580 void GenerateTypeTransition(MacroAssembler* masm);
581 void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
582 void GenerateUninitializedStub(MacroAssembler* masm);
583
584 // Entirely platform-specific methods are defined as static helper
585 // functions in the <arch>/code-stubs-<arch>.cc files.
586
587 virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
588
589 virtual InlineCacheState GetICState() {
590 return BinaryOpIC::ToState(Max(left_type_, right_type_));
591 }
592
593 virtual void FinishCode(Handle<Code> code) {
594 code->set_stub_info(MinorKey());
595 }
596
597 friend class CodeGenerator;
598 };
599
600
485 class ICCompareStub: public CodeStub { 601 class ICCompareStub: public CodeStub {
486 public: 602 public:
487 ICCompareStub(Token::Value op, CompareIC::State state) 603 ICCompareStub(Token::Value op,
488 : op_(op), state_(state) { 604 CompareIC::State left,
605 CompareIC::State right,
606 CompareIC::State handler)
607 : op_(op),
608 left_(left),
609 right_(right),
610 state_(handler) {
489 ASSERT(Token::IsCompareOp(op)); 611 ASSERT(Token::IsCompareOp(op));
490 } 612 }
491 613
492 virtual void Generate(MacroAssembler* masm); 614 virtual void Generate(MacroAssembler* masm);
493 615
494 void set_known_map(Handle<Map> map) { known_map_ = map; } 616 void set_known_map(Handle<Map> map) { known_map_ = map; }
495 617
618 static void DecodeMinorKey(int minor_key,
619 CompareIC::State* left_state,
620 CompareIC::State* right_state,
621 CompareIC::State* handler_state,
622 Token::Value* op);
623
624 static CompareIC::State CompareState(int minor_key) {
625 return static_cast<CompareIC::State>(HandlerStateField::decode(minor_key));
626 }
627
496 private: 628 private:
497 class OpField: public BitField<int, 0, 3> { }; 629 class OpField: public BitField<int, 0, 3> { };
498 class StateField: public BitField<int, 3, 5> { }; 630 class LeftStateField: public BitField<int, 3, 3> { };
631 class RightStateField: public BitField<int, 6, 3> { };
632 class HandlerStateField: public BitField<int, 9, 3> { };
499 633
500 virtual void FinishCode(Handle<Code> code) { 634 virtual void FinishCode(Handle<Code> code) {
501 code->set_compare_state(state_); 635 code->set_stub_info(MinorKey());
502 code->set_compare_operation(op_ - Token::EQ);
503 } 636 }
504 637
505 virtual CodeStub::Major MajorKey() { return CompareIC; } 638 virtual CodeStub::Major MajorKey() { return CompareIC; }
506 virtual int MinorKey(); 639 virtual int MinorKey();
507 640
508 virtual int GetCodeKind() { return Code::COMPARE_IC; } 641 virtual int GetCodeKind() { return Code::COMPARE_IC; }
509 642
510 void GenerateSmis(MacroAssembler* masm); 643 void GenerateSmis(MacroAssembler* masm);
511 void GenerateHeapNumbers(MacroAssembler* masm); 644 void GenerateHeapNumbers(MacroAssembler* masm);
512 void GenerateSymbols(MacroAssembler* masm); 645 void GenerateSymbols(MacroAssembler* masm);
513 void GenerateStrings(MacroAssembler* masm); 646 void GenerateStrings(MacroAssembler* masm);
514 void GenerateObjects(MacroAssembler* masm); 647 void GenerateObjects(MacroAssembler* masm);
515 void GenerateMiss(MacroAssembler* masm); 648 void GenerateMiss(MacroAssembler* masm);
516 void GenerateKnownObjects(MacroAssembler* masm); 649 void GenerateKnownObjects(MacroAssembler* masm);
650 void GenerateGeneric(MacroAssembler* masm);
517 651
518 bool strict() const { return op_ == Token::EQ_STRICT; } 652 bool strict() const { return op_ == Token::EQ_STRICT; }
519 Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } 653 Condition GetCondition() const { return CompareIC::ComputeCondition(op_); }
520 654
521 virtual void AddToSpecialCache(Handle<Code> new_object); 655 virtual void AddToSpecialCache(Handle<Code> new_object);
522 virtual bool FindCodeInSpecialCache(Code** code_out); 656 virtual bool FindCodeInSpecialCache(Code** code_out);
523 virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; } 657 virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; }
524 658
525 Token::Value op_; 659 Token::Value op_;
660 CompareIC::State left_;
661 CompareIC::State right_;
526 CompareIC::State state_; 662 CompareIC::State state_;
527 Handle<Map> known_map_; 663 Handle<Map> known_map_;
528 }; 664 };
529 665
530 666
531 // Flags that control the compare stub code generation.
532 enum CompareFlags {
533 NO_COMPARE_FLAGS = 0,
534 NO_SMI_COMPARE_IN_STUB = 1 << 0,
535 NO_NUMBER_COMPARE_IN_STUB = 1 << 1,
536 CANT_BOTH_BE_NAN = 1 << 2
537 };
538
539
540 enum NaNInformation {
541 kBothCouldBeNaN,
542 kCantBothBeNaN
543 };
544
545
546 class CompareStub: public CodeStub {
547 public:
548 CompareStub(Condition cc,
549 bool strict,
550 CompareFlags flags,
551 Register lhs,
552 Register rhs) :
553 cc_(cc),
554 strict_(strict),
555 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0),
556 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
557 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
558 lhs_(lhs),
559 rhs_(rhs) { }
560
561 CompareStub(Condition cc,
562 bool strict,
563 CompareFlags flags) :
564 cc_(cc),
565 strict_(strict),
566 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0),
567 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
568 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
569 lhs_(no_reg),
570 rhs_(no_reg) { }
571
572 void Generate(MacroAssembler* masm);
573
574 private:
575 Condition cc_;
576 bool strict_;
577 // Only used for 'equal' comparisons. Tells the stub that we already know
578 // that at least one side of the comparison is not NaN. This allows the
579 // stub to use object identity in the positive case. We ignore it when
580 // generating the minor key for other comparisons to avoid creating more
581 // stubs.
582 bool never_nan_nan_;
583 // Do generate the number comparison code in the stub. Stubs without number
584 // comparison code is used when the number comparison has been inlined, and
585 // the stub will be called if one of the operands is not a number.
586 bool include_number_compare_;
587
588 // Generate the comparison code for two smi operands in the stub.
589 bool include_smi_compare_;
590
591 // Register holding the left hand side of the comparison if the stub gives
592 // a choice, no_reg otherwise.
593
594 Register lhs_;
595 // Register holding the right hand side of the comparison if the stub gives
596 // a choice, no_reg otherwise.
597 Register rhs_;
598
599 // Encoding of the minor key in 16 bits.
600 class StrictField: public BitField<bool, 0, 1> {};
601 class NeverNanNanField: public BitField<bool, 1, 1> {};
602 class IncludeNumberCompareField: public BitField<bool, 2, 1> {};
603 class IncludeSmiCompareField: public BitField<bool, 3, 1> {};
604 class RegisterField: public BitField<bool, 4, 1> {};
605 class ConditionField: public BitField<int, 5, 11> {};
606
607 Major MajorKey() { return Compare; }
608
609 int MinorKey();
610
611 virtual int GetCodeKind() { return Code::COMPARE_IC; }
612 virtual void FinishCode(Handle<Code> code) {
613 code->set_compare_state(CompareIC::GENERIC);
614 }
615
616 // Branch to the label if the given object isn't a symbol.
617 void BranchIfNonSymbol(MacroAssembler* masm,
618 Label* label,
619 Register object,
620 Register scratch);
621
622 // Unfortunately you have to run without snapshots to see most of these
623 // names in the profile since most compare stubs end up in the snapshot.
624 virtual void PrintName(StringStream* stream);
625 };
626
627
628 class CEntryStub : public CodeStub { 667 class CEntryStub : public CodeStub {
629 public: 668 public:
630 explicit CEntryStub(int result_size, 669 explicit CEntryStub(int result_size,
631 SaveFPRegsMode save_doubles = kDontSaveFPRegs) 670 SaveFPRegsMode save_doubles = kDontSaveFPRegs)
632 : result_size_(result_size), save_doubles_(save_doubles) { } 671 : result_size_(result_size), save_doubles_(save_doubles) { }
633 672
634 void Generate(MacroAssembler* masm); 673 void Generate(MacroAssembler* masm);
635 674
636 // The version of this stub that doesn't save doubles is generated ahead of 675 // The version of this stub that doesn't save doubles is generated ahead of
637 // time, so it's OK to call it from other stubs that can't cope with GC during 676 // time, so it's OK to call it from other stubs that can't cope with GC during
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 // only has room for a single byte to hold a set of these types. :-P 1085 // only has room for a single byte to hold a set of these types. :-P
1047 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); 1086 STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
1048 1087
1049 class Types { 1088 class Types {
1050 public: 1089 public:
1051 Types() {} 1090 Types() {}
1052 explicit Types(byte bits) : set_(bits) {} 1091 explicit Types(byte bits) : set_(bits) {}
1053 1092
1054 bool IsEmpty() const { return set_.IsEmpty(); } 1093 bool IsEmpty() const { return set_.IsEmpty(); }
1055 bool Contains(Type type) const { return set_.Contains(type); } 1094 bool Contains(Type type) const { return set_.Contains(type); }
1095 bool ContainsAnyOf(Types types) const {
1096 return set_.ContainsAnyOf(types.set_);
1097 }
1056 void Add(Type type) { set_.Add(type); } 1098 void Add(Type type) { set_.Add(type); }
1057 byte ToByte() const { return set_.ToIntegral(); } 1099 byte ToByte() const { return set_.ToIntegral(); }
1058 void Print(StringStream* stream) const; 1100 void Print(StringStream* stream) const;
1059 void TraceTransition(Types to) const; 1101 void TraceTransition(Types to) const;
1060 bool Record(Handle<Object> object); 1102 bool Record(Handle<Object> object);
1061 bool NeedsMap() const; 1103 bool NeedsMap() const;
1062 bool CanBeUndetectable() const; 1104 bool CanBeUndetectable() const;
1063 1105
1064 private: 1106 private:
1065 EnumSet<Type, byte> set_; 1107 EnumSet<Type, byte> set_;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1226
1185 // The current function entry hook. 1227 // The current function entry hook.
1186 static FunctionEntryHook entry_hook_; 1228 static FunctionEntryHook entry_hook_;
1187 1229
1188 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); 1230 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
1189 }; 1231 };
1190 1232
1191 } } // namespace v8::internal 1233 } } // namespace v8::internal
1192 1234
1193 #endif // V8_CODE_STUBS_H_ 1235 #endif // V8_CODE_STUBS_H_
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698