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 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 Token::Value op_; | 1027 Token::Value op_; |
1028 CompareIC::State left_; | 1028 CompareIC::State left_; |
1029 CompareIC::State right_; | 1029 CompareIC::State right_; |
1030 CompareIC::State state_; | 1030 CompareIC::State state_; |
1031 Handle<Map> known_map_; | 1031 Handle<Map> known_map_; |
1032 }; | 1032 }; |
1033 | 1033 |
1034 | 1034 |
1035 class CompareNilICStub : public HydrogenCodeStub { | 1035 class CompareNilICStub : public HydrogenCodeStub { |
1036 public: | 1036 public: |
1037 enum Types { | 1037 enum Type { |
1038 kCompareAgainstNull = 1 << 0, | 1038 UNDEFINED, |
1039 kCompareAgainstUndefined = 1 << 1, | 1039 NULL_TYPE, |
1040 kCompareAgainstMonomorphicMap = 1 << 2, | 1040 MONOMORPHIC_MAP, |
1041 kCompareAgainstUndetectable = 1 << 3, | 1041 UNDETECTABLE, |
1042 kFullCompare = kCompareAgainstNull | kCompareAgainstUndefined | | 1042 NUMBER_OF_TYPES |
1043 kCompareAgainstUndetectable | |
1044 }; | 1043 }; |
1045 | 1044 |
1045 class Types { | |
Sven Panne
2013/05/13 14:24:50
Instead of inventing tons of ad-hoc helper functio
oliv
2013/05/13 18:03:58
Good point -> Done
| |
1046 public: | |
1047 Types() : set_(0) { } | |
1048 Types(const Types& state) : set_(state.set_) { } | |
1049 explicit Types(byte bits) : set_(bits) { } | |
1050 | |
1051 static Types FullCompare() { | |
1052 Types full(full_compare_types().ToIntegral()); | |
1053 return full; | |
1054 } | |
1055 | |
1056 bool IsEmpty() const { return set_.ToIntegral() == 0; } | |
1057 bool IsMonomorphic() const { return set_.Contains(MONOMORPHIC_MAP); } | |
1058 bool Contains(Type type) const { return set_.Contains(type); } | |
1059 bool IsFullCompare() const { | |
1060 return set_.ToIntegral() == full_compare_types().ToIntegral(); | |
1061 } | |
1062 | |
1063 void Add(Type type); | |
1064 void SetTo(Type type); | |
1065 void BeFullCompare() { set_ = full_compare_types(); } | |
1066 void Clear() { set_ = EnumSet<Type, byte>(0); } | |
1067 | |
1068 byte ToByte() const { return set_.ToIntegral(); } | |
1069 | |
1070 void Print(StringStream* stream) const; | |
1071 | |
1072 private: | |
1073 static const EnumSet<Type, byte> full_compare_types() { | |
1074 EnumSet<Type, byte> set; | |
1075 set.Add(UNDEFINED); | |
1076 set.Add(NULL_TYPE); | |
1077 set.Add(UNDETECTABLE); | |
1078 return set; | |
1079 } | |
1080 | |
1081 EnumSet<Type, byte> set_; | |
1082 }; | |
1083 | |
1084 // At most 6 different types can be distinguished, because the Code object | |
1085 // only has room for a single byte to hold a set and there are two more | |
1086 // boolean flags we need to store. :-P | |
1087 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); | |
1088 | |
1046 CompareNilICStub(EqualityKind kind, NilValue nil, Types types) | 1089 CompareNilICStub(EqualityKind kind, NilValue nil, Types types) |
1047 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), bit_field_(0) { | 1090 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), types_(types) { |
1048 bit_field_ = EqualityKindField::encode(kind) | | 1091 equality_kind_ = kind; |
1049 NilValueField::encode(nil) | | 1092 nil_value_ = nil; |
1050 TypesField::encode(types); | |
1051 } | 1093 } |
1052 | 1094 |
1053 virtual InlineCacheState GetICState() { | 1095 explicit CompareNilICStub(Code::ExtraICState ic_state) |
1054 Types types = GetTypes(); | 1096 : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS) { |
1055 if (types == kFullCompare) { | 1097 equality_kind_ = EqualityKindField::decode(ic_state); |
1056 return MEGAMORPHIC; | 1098 nil_value_ = NilValueField::decode(ic_state); |
1057 } else if ((types & kCompareAgainstMonomorphicMap) != 0) { | 1099 types_ = Types(ExtractTypesFromExtraICState(ic_state)); |
1058 return MONOMORPHIC; | |
1059 } else { | |
1060 return PREMONOMORPHIC; | |
1061 } | |
1062 } | 1100 } |
1063 | 1101 |
1064 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } | |
1065 | |
1066 Handle<Code> GenerateCode(); | |
1067 | |
1068 static Handle<Code> GetUninitialized(Isolate* isolate, | 1102 static Handle<Code> GetUninitialized(Isolate* isolate, |
1069 EqualityKind kind, | 1103 EqualityKind kind, |
1070 NilValue nil) { | 1104 NilValue nil) { |
1071 return CompareNilICStub(kind, nil).GetCode(isolate); | 1105 return CompareNilICStub(kind, nil, CODE_STUB_IS_MISS).GetCode(isolate); |
1072 } | 1106 } |
1073 | 1107 |
1074 virtual void InitializeInterfaceDescriptor( | 1108 virtual void InitializeInterfaceDescriptor( |
1075 Isolate* isolate, | 1109 Isolate* isolate, |
1076 CodeStubInterfaceDescriptor* descriptor); | 1110 CodeStubInterfaceDescriptor* descriptor); |
1077 | 1111 |
1078 static void InitializeForIsolate(Isolate* isolate) { | 1112 static void InitializeForIsolate(Isolate* isolate) { |
1079 CompareNilICStub compare_stub(kStrictEquality, kNullValue); | 1113 CompareNilICStub compare_stub(kStrictEquality, kNullValue, |
1114 CODE_STUB_IS_MISS); | |
1080 compare_stub.InitializeInterfaceDescriptor( | 1115 compare_stub.InitializeInterfaceDescriptor( |
1081 isolate, | 1116 isolate, |
1082 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); | 1117 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); |
1083 } | 1118 } |
1084 | 1119 |
1085 virtual Code::ExtraICState GetExtraICState() { | 1120 virtual InlineCacheState GetICState() { |
1086 return bit_field_; | 1121 if (types_.IsFullCompare()) { |
1122 return MEGAMORPHIC; | |
1123 } else if (types_.Contains(MONOMORPHIC_MAP)) { | |
1124 return MONOMORPHIC; | |
1125 } else { | |
1126 return PREMONOMORPHIC; | |
1127 } | |
1087 } | 1128 } |
1088 | 1129 |
1089 EqualityKind GetKind() { return EqualityKindField::decode(bit_field_); } | 1130 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
1090 NilValue GetNilValue() { return NilValueField::decode(bit_field_); } | |
1091 Types GetTypes() { return TypesField::decode(bit_field_); } | |
1092 | 1131 |
1093 static Types TypesFromExtraICState( | 1132 Handle<Code> GenerateCode(); |
1133 | |
1134 // extra ic state = nil_value | equality_kind | type_n-1 | ... | type_0 | |
1135 virtual Code::ExtraICState GetExtraICState() { | |
Sven Panne
2013/05/13 14:24:50
Use the BitField template instead of doing the bit
oliv
2013/05/13 18:03:58
They are BitFields, except for the types, since th
| |
1136 return NilValueField::encode(nil_value_) | | |
1137 EqualityKindField::encode(equality_kind_) | | |
1138 types_.ToByte(); | |
1139 } | |
1140 static byte ExtractTypesFromExtraICState( | |
1094 Code::ExtraICState state) { | 1141 Code::ExtraICState state) { |
1095 return TypesField::decode(state); | 1142 return state & ((1<<NUMBER_OF_TYPES)-1); |
1096 } | |
1097 static EqualityKind EqualityKindFromExtraICState( | |
1098 Code::ExtraICState state) { | |
1099 return EqualityKindField::decode(state); | |
1100 } | |
1101 static NilValue NilValueFromExtraICState(Code::ExtraICState state) { | |
1102 return NilValueField::decode(state); | |
1103 } | 1143 } |
1104 | 1144 |
1105 static Types GetPatchedICFlags(Code::ExtraICState extra_ic_state, | 1145 void Record(Handle<Object> object); |
1106 Handle<Object> object, | 1146 |
Sven Panne
2013/05/13 14:24:50
Do we really need all those tiny helper functions
oliv
2013/05/13 18:03:58
i mostly introduced them to make the callees code
| |
1107 bool* already_monomorphic); | 1147 bool IsMonomorphic() const { return types_.Contains(MONOMORPHIC_MAP); } |
1148 bool IsStrictEquality() const { return equality_kind_ == kStrictEquality; } | |
1149 bool IsNullValue() const { return nil_value_ == kNullValue; } | |
1150 EqualityKind GetKind() const { return equality_kind_; } | |
1151 NilValue GetNilValue() const { return nil_value_; } | |
1152 const Types GetTypes() const { return types_; } | |
Sven Panne
2013/05/13 14:24:50
Why 2 consts?
oliv
2013/05/13 18:03:58
1. the returned types shall be const
2. the method
| |
1153 void ClearTypes() { types_.Clear(); } | |
1154 void SetKind(EqualityKind kind) { equality_kind_ = kind; } | |
1155 | |
1156 virtual void PrintName(StringStream* stream); | |
1108 | 1157 |
1109 private: | 1158 private: |
1110 friend class CompareNilIC; | 1159 friend class CompareNilIC; |
1111 | 1160 |
1112 class EqualityKindField : public BitField<EqualityKind, 0, 1> {}; | 1161 CompareNilICStub(EqualityKind kind, NilValue nil, |
1113 class NilValueField : public BitField<NilValue, 1, 1> {}; | 1162 InitializationState init_state) |
1114 class TypesField : public BitField<Types, 3, 4> {}; | 1163 : HydrogenCodeStub(init_state), types_(0) { |
1115 | 1164 equality_kind_ = kind; |
1116 CompareNilICStub(EqualityKind kind, NilValue nil) | 1165 nil_value_ = nil; |
1117 : HydrogenCodeStub(CODE_STUB_IS_MISS), bit_field_(0) { | |
1118 bit_field_ = EqualityKindField::encode(kind) | | |
1119 NilValueField::encode(nil); | |
1120 } | 1166 } |
1121 | 1167 |
1168 CompareNilICStub(Code::ExtraICState ic_state, InitializationState init_state) | |
1169 : HydrogenCodeStub(init_state) { | |
1170 equality_kind_ = EqualityKindField::decode(ic_state); | |
1171 nil_value_ = NilValueField::decode(ic_state); | |
1172 types_ = Types(ExtractTypesFromExtraICState(ic_state)); | |
1173 } | |
1174 | |
1175 class EqualityKindField : public BitField<EqualityKind, NUMBER_OF_TYPES, 1> { | |
1176 }; | |
1177 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES+1, 1> {}; | |
1178 | |
1122 virtual CodeStub::Major MajorKey() { return CompareNilIC; } | 1179 virtual CodeStub::Major MajorKey() { return CompareNilIC; } |
1123 virtual int NotMissMinorKey() { return bit_field_; } | 1180 virtual int NotMissMinorKey() { return GetExtraICState(); } |
1124 | 1181 |
1125 int bit_field_; | 1182 EqualityKind equality_kind_; |
1183 NilValue nil_value_; | |
1184 Types types_; | |
1126 | 1185 |
1127 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); | 1186 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); |
1128 }; | 1187 }; |
1129 | 1188 |
1130 | 1189 |
1131 class CEntryStub : public PlatformCodeStub { | 1190 class CEntryStub : public PlatformCodeStub { |
1132 public: | 1191 public: |
1133 explicit CEntryStub(int result_size, | 1192 explicit CEntryStub(int result_size, |
1134 SaveFPRegsMode save_doubles = kDontSaveFPRegs) | 1193 SaveFPRegsMode save_doubles = kDontSaveFPRegs) |
1135 : result_size_(result_size), save_doubles_(save_doubles) { } | 1194 : result_size_(result_size), save_doubles_(save_doubles) { } |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1951 | 2010 |
1952 // The current function entry hook. | 2011 // The current function entry hook. |
1953 static FunctionEntryHook entry_hook_; | 2012 static FunctionEntryHook entry_hook_; |
1954 | 2013 |
1955 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2014 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
1956 }; | 2015 }; |
1957 | 2016 |
1958 } } // namespace v8::internal | 2017 } } // namespace v8::internal |
1959 | 2018 |
1960 #endif // V8_CODE_STUBS_H_ | 2019 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |