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