OLD | NEW |
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 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 Handle<Object> key, | 811 Handle<Object> key, |
812 Handle<Object> value); | 812 Handle<Object> value); |
813 | 813 |
814 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, | 814 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, |
815 KeyedAccessStoreMode store_mode); | 815 KeyedAccessStoreMode store_mode); |
816 | 816 |
817 friend class IC; | 817 friend class IC; |
818 }; | 818 }; |
819 | 819 |
820 | 820 |
| 821 // Mode to overwrite BinaryExpression values. |
| 822 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; |
| 823 |
821 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. | 824 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. |
822 class BinaryOpIC: public IC { | 825 class BinaryOpIC: public IC { |
823 public: | 826 public: |
824 enum TypeInfo { | 827 class State V8_FINAL BASE_EMBEDDED { |
825 UNINITIALIZED, | 828 public: |
826 SMI, | 829 explicit State(ExtraICState extra_ic_state); |
827 INT32, | 830 |
828 NUMBER, | 831 State(Token::Value op, OverwriteMode mode) |
829 ODDBALL, | 832 : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE), |
830 STRING, // Only used for addition operation. | 833 result_kind_(NONE) { |
831 GENERIC | 834 ASSERT_LE(FIRST_TOKEN, op); |
| 835 ASSERT_LE(op, LAST_TOKEN); |
| 836 } |
| 837 |
| 838 InlineCacheState GetICState() const { |
| 839 if (Max(left_kind_, right_kind_) == NONE) { |
| 840 return ::v8::internal::UNINITIALIZED; |
| 841 } |
| 842 if (Max(left_kind_, right_kind_) == GENERIC) { |
| 843 return ::v8::internal::MEGAMORPHIC; |
| 844 } |
| 845 if (Min(left_kind_, right_kind_) == GENERIC) { |
| 846 return ::v8::internal::GENERIC; |
| 847 } |
| 848 return ::v8::internal::MONOMORPHIC; |
| 849 } |
| 850 |
| 851 ExtraICState GetExtraICState() const; |
| 852 |
| 853 static void GenerateAheadOfTime( |
| 854 Isolate*, void (*Generate)(Isolate*, const State&)); |
| 855 |
| 856 bool CanReuseDoubleBox() const { |
| 857 return (result_kind_ > SMI && result_kind_ <= NUMBER) && |
| 858 ((mode_ == OVERWRITE_LEFT && |
| 859 left_kind_ > SMI && left_kind_ <= NUMBER) || |
| 860 (mode_ == OVERWRITE_RIGHT && |
| 861 right_kind_ > SMI && right_kind_ <= NUMBER)); |
| 862 } |
| 863 |
| 864 bool HasSideEffects() const { |
| 865 return Max(left_kind_, right_kind_) == GENERIC; |
| 866 } |
| 867 |
| 868 bool UseInlinedSmiCode() const { |
| 869 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_); |
| 870 } |
| 871 |
| 872 static const int FIRST_TOKEN = Token::BIT_OR; |
| 873 static const int LAST_TOKEN = Token::MOD; |
| 874 |
| 875 Token::Value op() const { return op_; } |
| 876 OverwriteMode mode() const { return mode_; } |
| 877 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } |
| 878 |
| 879 Handle<Type> GetLeftType(Isolate* isolate) const { |
| 880 return KindToType(left_kind_, isolate); |
| 881 } |
| 882 Handle<Type> GetRightType(Isolate* isolate) const { |
| 883 return KindToType(right_kind_, isolate); |
| 884 } |
| 885 Handle<Type> GetResultType(Isolate* isolate) const; |
| 886 |
| 887 void Print(StringStream* stream) const; |
| 888 |
| 889 void Update(Handle<Object> left, |
| 890 Handle<Object> right, |
| 891 Handle<Object> result); |
| 892 |
| 893 private: |
| 894 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; |
| 895 |
| 896 Kind UpdateKind(Handle<Object> object, Kind kind) const; |
| 897 |
| 898 static const char* KindToString(Kind kind); |
| 899 static Handle<Type> KindToType(Kind kind, Isolate* isolate); |
| 900 static bool KindMaybeSmi(Kind kind) { |
| 901 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC; |
| 902 } |
| 903 |
| 904 // We truncate the last bit of the token. |
| 905 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4)); |
| 906 class OpField: public BitField<int, 0, 4> {}; |
| 907 class OverwriteModeField: public BitField<OverwriteMode, 4, 2> {}; |
| 908 class SSE2Field: public BitField<bool, 6, 1> {}; |
| 909 class ResultKindField: public BitField<Kind, 7, 3> {}; |
| 910 class LeftKindField: public BitField<Kind, 10, 3> {}; |
| 911 // When fixed right arg is set, we don't need to store the right kind. |
| 912 // Thus the two fields can overlap. |
| 913 class HasFixedRightArgField: public BitField<bool, 13, 1> {}; |
| 914 class FixedRightArgValueField: public BitField<int, 14, 4> {}; |
| 915 class RightKindField: public BitField<Kind, 14, 3> {}; |
| 916 |
| 917 Token::Value op_; |
| 918 OverwriteMode mode_; |
| 919 Kind left_kind_; |
| 920 Kind right_kind_; |
| 921 Kind result_kind_; |
| 922 Maybe<int> fixed_right_arg_; |
832 }; | 923 }; |
833 | 924 |
834 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } | 925 explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } |
835 | 926 |
836 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); | 927 static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); |
837 | 928 |
838 static const char* GetName(TypeInfo type_info); | |
839 | |
840 MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left, | 929 MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left, |
841 Handle<Object> right); | 930 Handle<Object> right); |
842 }; | 931 }; |
843 | 932 |
844 | 933 |
845 class CompareIC: public IC { | 934 class CompareIC: public IC { |
846 public: | 935 public: |
847 // The type/state lattice is defined by the following inequations: | 936 // The type/state lattice is defined by the following inequations: |
848 // UNINITIALIZED < ... | 937 // UNINITIALIZED < ... |
849 // ... < GENERIC | 938 // ... < GENERIC |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure); | 1036 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure); |
948 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); | 1037 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); |
949 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); | 1038 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); |
950 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); | 1039 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); |
951 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); | 1040 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); |
952 | 1041 |
953 | 1042 |
954 } } // namespace v8::internal | 1043 } } // namespace v8::internal |
955 | 1044 |
956 #endif // V8_IC_H_ | 1045 #endif // V8_IC_H_ |
OLD | NEW |