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 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 Token::Value op_; | 1040 Token::Value op_; |
1041 CompareIC::State left_; | 1041 CompareIC::State left_; |
1042 CompareIC::State right_; | 1042 CompareIC::State right_; |
1043 CompareIC::State state_; | 1043 CompareIC::State state_; |
1044 Handle<Map> known_map_; | 1044 Handle<Map> known_map_; |
1045 }; | 1045 }; |
1046 | 1046 |
1047 | 1047 |
1048 class CompareNilICStub : public HydrogenCodeStub { | 1048 class CompareNilICStub : public HydrogenCodeStub { |
1049 public: | 1049 public: |
1050 enum Types { | 1050 enum Type { |
1051 kCompareAgainstNull = 1 << 0, | 1051 UNDEFINED, |
1052 kCompareAgainstUndefined = 1 << 1, | 1052 NULL_TYPE, |
1053 kCompareAgainstMonomorphicMap = 1 << 2, | 1053 MONOMORPHIC_MAP, |
1054 kCompareAgainstUndetectable = 1 << 3, | 1054 UNDETECTABLE, |
1055 kFullCompare = kCompareAgainstNull | kCompareAgainstUndefined | | 1055 NUMBER_OF_TYPES |
1056 kCompareAgainstUndetectable | |
1057 }; | 1056 }; |
1058 | 1057 |
| 1058 class Types : public EnumSet<Type, byte> { |
| 1059 public: |
| 1060 Types() : EnumSet<Type, byte>(0) { } |
| 1061 explicit Types(byte bits) : EnumSet<Type, byte>(bits) { } |
| 1062 |
| 1063 static Types FullCompare() { |
| 1064 Types set; |
| 1065 set.Add(UNDEFINED); |
| 1066 set.Add(NULL_TYPE); |
| 1067 set.Add(UNDETECTABLE); |
| 1068 return set; |
| 1069 } |
| 1070 |
| 1071 void Print(StringStream* stream) const; |
| 1072 }; |
| 1073 |
| 1074 // At most 6 different types can be distinguished, because the Code object |
| 1075 // only has room for a single byte to hold a set and there are two more |
| 1076 // boolean flags we need to store. :-P |
| 1077 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); |
| 1078 |
1059 CompareNilICStub(EqualityKind kind, NilValue nil, Types types) | 1079 CompareNilICStub(EqualityKind kind, NilValue nil, Types types) |
1060 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), bit_field_(0) { | 1080 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), types_(types) { |
1061 bit_field_ = EqualityKindField::encode(kind) | | 1081 equality_kind_ = kind; |
1062 NilValueField::encode(nil) | | 1082 nil_value_ = nil; |
1063 TypesField::encode(types); | |
1064 } | 1083 } |
1065 | 1084 |
1066 virtual InlineCacheState GetICState() { | 1085 explicit CompareNilICStub(Code::ExtraICState ic_state) |
1067 Types types = GetTypes(); | 1086 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS) { |
1068 if (types == kFullCompare) { | 1087 equality_kind_ = EqualityKindField::decode(ic_state); |
1069 return MEGAMORPHIC; | 1088 nil_value_ = NilValueField::decode(ic_state); |
1070 } else if ((types & kCompareAgainstMonomorphicMap) != 0) { | 1089 types_ = Types(ExtractTypesFromExtraICState(ic_state)); |
1071 return MONOMORPHIC; | |
1072 } else { | |
1073 return PREMONOMORPHIC; | |
1074 } | |
1075 } | 1090 } |
1076 | 1091 |
1077 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } | |
1078 | |
1079 Handle<Code> GenerateCode(); | |
1080 | |
1081 static Handle<Code> GetUninitialized(Isolate* isolate, | 1092 static Handle<Code> GetUninitialized(Isolate* isolate, |
1082 EqualityKind kind, | 1093 EqualityKind kind, |
1083 NilValue nil) { | 1094 NilValue nil) { |
1084 return CompareNilICStub(kind, nil).GetCode(isolate); | 1095 return CompareNilICStub(kind, nil, CODE_STUB_IS_MISS).GetCode(isolate); |
1085 } | 1096 } |
1086 | 1097 |
1087 virtual void InitializeInterfaceDescriptor( | 1098 virtual void InitializeInterfaceDescriptor( |
1088 Isolate* isolate, | 1099 Isolate* isolate, |
1089 CodeStubInterfaceDescriptor* descriptor); | 1100 CodeStubInterfaceDescriptor* descriptor); |
1090 | 1101 |
1091 static void InitializeForIsolate(Isolate* isolate) { | 1102 static void InitializeForIsolate(Isolate* isolate) { |
1092 CompareNilICStub compare_stub(kStrictEquality, kNullValue); | 1103 CompareNilICStub compare_stub(kStrictEquality, kNullValue, |
| 1104 CODE_STUB_IS_MISS); |
1093 compare_stub.InitializeInterfaceDescriptor( | 1105 compare_stub.InitializeInterfaceDescriptor( |
1094 isolate, | 1106 isolate, |
1095 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); | 1107 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); |
1096 } | 1108 } |
1097 | 1109 |
1098 virtual Code::ExtraICState GetExtraICState() { | 1110 virtual InlineCacheState GetICState() { |
1099 return bit_field_; | 1111 if (types_ == Types::FullCompare()) { |
| 1112 return MEGAMORPHIC; |
| 1113 } else if (types_.Contains(MONOMORPHIC_MAP)) { |
| 1114 return MONOMORPHIC; |
| 1115 } else { |
| 1116 return PREMONOMORPHIC; |
| 1117 } |
1100 } | 1118 } |
1101 | 1119 |
1102 EqualityKind GetKind() { return EqualityKindField::decode(bit_field_); } | 1120 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
1103 NilValue GetNilValue() { return NilValueField::decode(bit_field_); } | |
1104 Types GetTypes() { return TypesField::decode(bit_field_); } | |
1105 | 1121 |
1106 static Types TypesFromExtraICState( | 1122 Handle<Code> GenerateCode(); |
| 1123 |
| 1124 // extra ic state = nil_value | equality_kind | type_n-1 | ... | type_0 |
| 1125 virtual Code::ExtraICState GetExtraICState() { |
| 1126 return NilValueField::encode(nil_value_) | |
| 1127 EqualityKindField::encode(equality_kind_) | |
| 1128 types_.ToIntegral(); |
| 1129 } |
| 1130 static byte ExtractTypesFromExtraICState( |
1107 Code::ExtraICState state) { | 1131 Code::ExtraICState state) { |
1108 return TypesField::decode(state); | 1132 return state & ((1<<NUMBER_OF_TYPES)-1); |
1109 } | |
1110 static EqualityKind EqualityKindFromExtraICState( | |
1111 Code::ExtraICState state) { | |
1112 return EqualityKindField::decode(state); | |
1113 } | |
1114 static NilValue NilValueFromExtraICState(Code::ExtraICState state) { | |
1115 return NilValueField::decode(state); | |
1116 } | 1133 } |
1117 | 1134 |
1118 static Types GetPatchedICFlags(Code::ExtraICState extra_ic_state, | 1135 void Record(Handle<Object> object); |
1119 Handle<Object> object, | 1136 |
1120 bool* already_monomorphic); | 1137 bool IsMonomorphic() const { return types_.Contains(MONOMORPHIC_MAP); } |
| 1138 EqualityKind GetKind() const { return equality_kind_; } |
| 1139 NilValue GetNilValue() const { return nil_value_; } |
| 1140 Types GetTypes() const { return types_; } |
| 1141 void ClearTypes() { types_.RemoveAll(); } |
| 1142 void SetKind(EqualityKind kind) { equality_kind_ = kind; } |
| 1143 |
| 1144 virtual void PrintName(StringStream* stream); |
1121 | 1145 |
1122 private: | 1146 private: |
1123 friend class CompareNilIC; | 1147 friend class CompareNilIC; |
1124 | 1148 |
1125 class EqualityKindField : public BitField<EqualityKind, 0, 1> {}; | 1149 CompareNilICStub(EqualityKind kind, NilValue nil, |
1126 class NilValueField : public BitField<NilValue, 1, 1> {}; | 1150 InitializationState init_state) |
1127 class TypesField : public BitField<Types, 3, 4> {}; | 1151 : HydrogenCodeStub(init_state), types_(0) { |
1128 | 1152 equality_kind_ = kind; |
1129 CompareNilICStub(EqualityKind kind, NilValue nil) | 1153 nil_value_ = nil; |
1130 : HydrogenCodeStub(CODE_STUB_IS_MISS), bit_field_(0) { | |
1131 bit_field_ = EqualityKindField::encode(kind) | | |
1132 NilValueField::encode(nil); | |
1133 } | 1154 } |
1134 | 1155 |
| 1156 CompareNilICStub(Code::ExtraICState ic_state, InitializationState init_state) |
| 1157 : HydrogenCodeStub(init_state) { |
| 1158 equality_kind_ = EqualityKindField::decode(ic_state); |
| 1159 nil_value_ = NilValueField::decode(ic_state); |
| 1160 types_ = Types(ExtractTypesFromExtraICState(ic_state)); |
| 1161 } |
| 1162 |
| 1163 class EqualityKindField : public BitField<EqualityKind, NUMBER_OF_TYPES, 1> { |
| 1164 }; |
| 1165 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES+1, 1> {}; |
| 1166 |
1135 virtual CodeStub::Major MajorKey() { return CompareNilIC; } | 1167 virtual CodeStub::Major MajorKey() { return CompareNilIC; } |
1136 virtual int NotMissMinorKey() { return bit_field_; } | 1168 virtual int NotMissMinorKey() { return GetExtraICState(); } |
1137 | 1169 |
1138 int bit_field_; | 1170 EqualityKind equality_kind_; |
| 1171 NilValue nil_value_; |
| 1172 Types types_; |
1139 | 1173 |
1140 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); | 1174 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); |
1141 }; | 1175 }; |
1142 | 1176 |
1143 | 1177 |
1144 class CEntryStub : public PlatformCodeStub { | 1178 class CEntryStub : public PlatformCodeStub { |
1145 public: | 1179 public: |
1146 explicit CEntryStub(int result_size, | 1180 explicit CEntryStub(int result_size, |
1147 SaveFPRegsMode save_doubles = kDontSaveFPRegs) | 1181 SaveFPRegsMode save_doubles = kDontSaveFPRegs) |
1148 : result_size_(result_size), save_doubles_(save_doubles) { } | 1182 : result_size_(result_size), save_doubles_(save_doubles) { } |
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 STRING, | 1822 STRING, |
1789 SYMBOL, | 1823 SYMBOL, |
1790 HEAP_NUMBER, | 1824 HEAP_NUMBER, |
1791 NUMBER_OF_TYPES | 1825 NUMBER_OF_TYPES |
1792 }; | 1826 }; |
1793 | 1827 |
1794 // At most 8 different types can be distinguished, because the Code object | 1828 // At most 8 different types can be distinguished, because the Code object |
1795 // only has room for a single byte to hold a set of these types. :-P | 1829 // only has room for a single byte to hold a set of these types. :-P |
1796 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); | 1830 STATIC_ASSERT(NUMBER_OF_TYPES <= 8); |
1797 | 1831 |
1798 class Types { | 1832 class Types : public EnumSet<Type, byte> { |
1799 public: | 1833 public: |
1800 Types() {} | 1834 Types() {} |
1801 explicit Types(byte bits) : set_(bits) {} | 1835 explicit Types(byte bits) : EnumSet<Type, byte>(bits) {} |
1802 | 1836 |
1803 bool IsEmpty() const { return set_.IsEmpty(); } | 1837 byte ToByte() const { return ToIntegral(); } |
1804 bool Contains(Type type) const { return set_.Contains(type); } | |
1805 bool ContainsAnyOf(Types types) const { | |
1806 return set_.ContainsAnyOf(types.set_); | |
1807 } | |
1808 void Add(Type type) { set_.Add(type); } | |
1809 byte ToByte() const { return set_.ToIntegral(); } | |
1810 void Print(StringStream* stream) const; | 1838 void Print(StringStream* stream) const; |
1811 void TraceTransition(Types to) const; | 1839 void TraceTransition(Types to) const; |
1812 bool Record(Handle<Object> object); | 1840 bool Record(Handle<Object> object); |
1813 bool NeedsMap() const; | 1841 bool NeedsMap() const; |
1814 bool CanBeUndetectable() const; | 1842 bool CanBeUndetectable() const; |
1815 | |
1816 private: | |
1817 EnumSet<Type, byte> set_; | |
1818 }; | 1843 }; |
1819 | 1844 |
1820 static Types no_types() { return Types(); } | 1845 static Types no_types() { return Types(); } |
1821 static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); } | 1846 static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); } |
1822 | 1847 |
1823 explicit ToBooleanStub(Register tos, Types types = Types()) | 1848 explicit ToBooleanStub(Register tos, Types types = Types()) |
1824 : tos_(tos), types_(types) { } | 1849 : tos_(tos), types_(types) { } |
1825 | 1850 |
1826 void Generate(MacroAssembler* masm); | 1851 void Generate(MacroAssembler* masm); |
1827 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } | 1852 virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } |
1828 virtual void PrintName(StringStream* stream); | 1853 virtual void PrintName(StringStream* stream); |
1829 | 1854 |
1830 virtual bool SometimesSetsUpAFrame() { return false; } | 1855 virtual bool SometimesSetsUpAFrame() { return false; } |
1831 | 1856 |
1832 private: | 1857 private: |
1833 Major MajorKey() { return ToBoolean; } | 1858 Major MajorKey() { return ToBoolean; } |
1834 int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); } | 1859 int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | |
| 1860 types_.ToByte(); } |
1835 | 1861 |
1836 virtual void FinishCode(Handle<Code> code) { | 1862 virtual void FinishCode(Handle<Code> code) { |
1837 code->set_to_boolean_state(types_.ToByte()); | 1863 code->set_to_boolean_state(types_.ToByte()); |
1838 } | 1864 } |
1839 | 1865 |
1840 void CheckOddball(MacroAssembler* masm, | 1866 void CheckOddball(MacroAssembler* masm, |
1841 Type type, | 1867 Type type, |
1842 Heap::RootListIndex value, | 1868 Heap::RootListIndex value, |
1843 bool result); | 1869 bool result); |
1844 void GenerateTypeTransition(MacroAssembler* masm); | 1870 void GenerateTypeTransition(MacroAssembler* masm); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 | 1990 |
1965 // The current function entry hook. | 1991 // The current function entry hook. |
1966 static FunctionEntryHook entry_hook_; | 1992 static FunctionEntryHook entry_hook_; |
1967 | 1993 |
1968 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 1994 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
1969 }; | 1995 }; |
1970 | 1996 |
1971 } } // namespace v8::internal | 1997 } } // namespace v8::internal |
1972 | 1998 |
1973 #endif // V8_CODE_STUBS_H_ | 1999 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |