| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 V(FastNewContext) \ | 65 V(FastNewContext) \ |
| 66 V(FastNewBlockContext) \ | 66 V(FastNewBlockContext) \ |
| 67 V(FastCloneShallowArray) \ | 67 V(FastCloneShallowArray) \ |
| 68 V(FastCloneShallowObject) \ | 68 V(FastCloneShallowObject) \ |
| 69 V(CreateAllocationSite) \ | 69 V(CreateAllocationSite) \ |
| 70 V(ToBoolean) \ | 70 V(ToBoolean) \ |
| 71 V(ToNumber) \ | 71 V(ToNumber) \ |
| 72 V(ArgumentsAccess) \ | 72 V(ArgumentsAccess) \ |
| 73 V(RegExpConstructResult) \ | 73 V(RegExpConstructResult) \ |
| 74 V(NumberToString) \ | 74 V(NumberToString) \ |
| 75 V(DoubleToI) \ |
| 75 V(CEntry) \ | 76 V(CEntry) \ |
| 76 V(JSEntry) \ | 77 V(JSEntry) \ |
| 77 V(KeyedLoadElement) \ | 78 V(KeyedLoadElement) \ |
| 78 V(ArrayNoArgumentConstructor) \ | 79 V(ArrayNoArgumentConstructor) \ |
| 79 V(ArraySingleArgumentConstructor) \ | 80 V(ArraySingleArgumentConstructor) \ |
| 80 V(ArrayNArgumentsConstructor) \ | 81 V(ArrayNArgumentsConstructor) \ |
| 81 V(InternalArrayNoArgumentConstructor) \ | 82 V(InternalArrayNoArgumentConstructor) \ |
| 82 V(InternalArraySingleArgumentConstructor) \ | 83 V(InternalArraySingleArgumentConstructor) \ |
| 83 V(InternalArrayNArgumentsConstructor) \ | 84 V(InternalArrayNArgumentsConstructor) \ |
| 84 V(KeyedStoreElement) \ | 85 V(KeyedStoreElement) \ |
| (...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 Token::Value op_; | 1262 Token::Value op_; |
| 1262 CompareIC::State left_; | 1263 CompareIC::State left_; |
| 1263 CompareIC::State right_; | 1264 CompareIC::State right_; |
| 1264 CompareIC::State state_; | 1265 CompareIC::State state_; |
| 1265 Handle<Map> known_map_; | 1266 Handle<Map> known_map_; |
| 1266 }; | 1267 }; |
| 1267 | 1268 |
| 1268 | 1269 |
| 1269 class CompareNilICStub : public HydrogenCodeStub { | 1270 class CompareNilICStub : public HydrogenCodeStub { |
| 1270 public: | 1271 public: |
| 1271 enum CompareNilType { | 1272 Handle<Type> GetType(Isolate* isolate, Handle<Map> map = Handle<Map>()); |
| 1272 UNDEFINED, | 1273 Handle<Type> GetInputType(Isolate* isolate, Handle<Map> map); |
| 1273 NULL_TYPE, | |
| 1274 MONOMORPHIC_MAP, | |
| 1275 UNDETECTABLE, | |
| 1276 GENERIC, | |
| 1277 NUMBER_OF_TYPES | |
| 1278 }; | |
| 1279 | 1274 |
| 1280 class State : public EnumSet<CompareNilType, byte> { | 1275 explicit CompareNilICStub(NilValue nil) : nil_value_(nil) { } |
| 1281 public: | |
| 1282 State() : EnumSet<CompareNilType, byte>(0) { } | |
| 1283 explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { } | |
| 1284 | |
| 1285 static State Generic() { | |
| 1286 State set; | |
| 1287 set.Add(UNDEFINED); | |
| 1288 set.Add(NULL_TYPE); | |
| 1289 set.Add(UNDETECTABLE); | |
| 1290 set.Add(GENERIC); | |
| 1291 return set; | |
| 1292 } | |
| 1293 | |
| 1294 void Print(StringStream* stream) const; | |
| 1295 }; | |
| 1296 | |
| 1297 static Handle<Type> StateToType( | |
| 1298 Isolate* isolate, State state, Handle<Map> map = Handle<Map>()); | |
| 1299 | |
| 1300 // At most 6 different types can be distinguished, because the Code object | |
| 1301 // only has room for a single byte to hold a set and there are two more | |
| 1302 // boolean flags we need to store. :-P | |
| 1303 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); | |
| 1304 | |
| 1305 CompareNilICStub(NilValue nil, State state = State()) | |
| 1306 : nil_value_(nil), state_(state) { | |
| 1307 } | |
| 1308 | 1276 |
| 1309 CompareNilICStub(Code::ExtraICState ic_state, | 1277 CompareNilICStub(Code::ExtraICState ic_state, |
| 1310 InitializationState init_state = INITIALIZED) | 1278 InitializationState init_state = INITIALIZED) |
| 1311 : HydrogenCodeStub(init_state) { | 1279 : HydrogenCodeStub(init_state), |
| 1312 nil_value_ = NilValueField::decode(ic_state); | 1280 nil_value_(NilValueField::decode(ic_state)), |
| 1313 state_ = State(ExtractTypesFromExtraICState(ic_state)); | 1281 state_(State(TypesField::decode(ic_state))) { |
| 1314 } | 1282 } |
| 1315 | 1283 |
| 1316 static Handle<Code> GetUninitialized(Isolate* isolate, | 1284 static Handle<Code> GetUninitialized(Isolate* isolate, |
| 1317 NilValue nil) { | 1285 NilValue nil) { |
| 1318 return CompareNilICStub(nil, UNINITIALIZED).GetCode(isolate); | 1286 return CompareNilICStub(nil, UNINITIALIZED).GetCode(isolate); |
| 1319 } | 1287 } |
| 1320 | 1288 |
| 1321 virtual void InitializeInterfaceDescriptor( | 1289 virtual void InitializeInterfaceDescriptor( |
| 1322 Isolate* isolate, | 1290 Isolate* isolate, |
| 1323 CodeStubInterfaceDescriptor* descriptor); | 1291 CodeStubInterfaceDescriptor* descriptor); |
| 1324 | 1292 |
| 1325 static void InitializeForIsolate(Isolate* isolate) { | 1293 static void InitializeForIsolate(Isolate* isolate) { |
| 1326 CompareNilICStub compare_stub(kNullValue, UNINITIALIZED); | 1294 CompareNilICStub compare_stub(kNullValue, UNINITIALIZED); |
| 1327 compare_stub.InitializeInterfaceDescriptor( | 1295 compare_stub.InitializeInterfaceDescriptor( |
| 1328 isolate, | 1296 isolate, |
| 1329 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); | 1297 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); |
| 1330 } | 1298 } |
| 1331 | 1299 |
| 1332 virtual InlineCacheState GetICState() { | 1300 virtual InlineCacheState GetICState() { |
| 1333 if (state_ == State::Generic()) { | 1301 if (state_.Contains(GENERIC)) { |
| 1334 return MEGAMORPHIC; | 1302 return MEGAMORPHIC; |
| 1335 } else if (state_.Contains(MONOMORPHIC_MAP)) { | 1303 } else if (state_.Contains(MONOMORPHIC_MAP)) { |
| 1336 return MONOMORPHIC; | 1304 return MONOMORPHIC; |
| 1337 } else { | 1305 } else { |
| 1338 return PREMONOMORPHIC; | 1306 return PREMONOMORPHIC; |
| 1339 } | 1307 } |
| 1340 } | 1308 } |
| 1341 | 1309 |
| 1342 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } | 1310 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
| 1343 | 1311 |
| 1344 Handle<Code> GenerateCode(); | 1312 Handle<Code> GenerateCode(); |
| 1345 | 1313 |
| 1346 // extra ic state = nil_value | type_n-1 | ... | type_0 | |
| 1347 virtual Code::ExtraICState GetExtraICState() { | 1314 virtual Code::ExtraICState GetExtraICState() { |
| 1348 return NilValueField::encode(nil_value_) | state_.ToIntegral(); | 1315 return NilValueField::encode(nil_value_) | |
| 1349 } | 1316 TypesField::encode(state_.ToIntegral()); |
| 1350 static byte ExtractTypesFromExtraICState(Code::ExtraICState state) { | |
| 1351 return state & ((1 << NUMBER_OF_TYPES) - 1); | |
| 1352 } | |
| 1353 static NilValue ExtractNilValueFromExtraICState(Code::ExtraICState state) { | |
| 1354 return NilValueField::decode(state); | |
| 1355 } | 1317 } |
| 1356 | 1318 |
| 1357 void UpdateStatus(Handle<Object> object); | 1319 void UpdateStatus(Handle<Object> object); |
| 1358 | 1320 |
| 1359 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } | 1321 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } |
| 1360 NilValue GetNilValue() const { return nil_value_; } | 1322 NilValue GetNilValue() const { return nil_value_; } |
| 1361 State GetState() const { return state_; } | |
| 1362 void ClearState() { state_.RemoveAll(); } | 1323 void ClearState() { state_.RemoveAll(); } |
| 1363 | 1324 |
| 1364 virtual void PrintState(StringStream* stream); | 1325 virtual void PrintState(StringStream* stream); |
| 1365 virtual void PrintBaseName(StringStream* stream); | 1326 virtual void PrintBaseName(StringStream* stream); |
| 1366 | 1327 |
| 1367 private: | 1328 private: |
| 1368 friend class CompareNilIC; | 1329 friend class CompareNilIC; |
| 1369 | 1330 |
| 1331 enum CompareNilType { |
| 1332 UNDEFINED, |
| 1333 NULL_TYPE, |
| 1334 MONOMORPHIC_MAP, |
| 1335 GENERIC, |
| 1336 NUMBER_OF_TYPES |
| 1337 }; |
| 1338 |
| 1339 // At most 6 different types can be distinguished, because the Code object |
| 1340 // only has room for a single byte to hold a set and there are two more |
| 1341 // boolean flags we need to store. :-P |
| 1342 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); |
| 1343 |
| 1344 class State : public EnumSet<CompareNilType, byte> { |
| 1345 public: |
| 1346 State() : EnumSet<CompareNilType, byte>(0) { } |
| 1347 explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { } |
| 1348 |
| 1349 void Print(StringStream* stream) const; |
| 1350 }; |
| 1351 |
| 1370 CompareNilICStub(NilValue nil, InitializationState init_state) | 1352 CompareNilICStub(NilValue nil, InitializationState init_state) |
| 1371 : HydrogenCodeStub(init_state) { | 1353 : HydrogenCodeStub(init_state), nil_value_(nil) { } |
| 1372 nil_value_ = nil; | |
| 1373 } | |
| 1374 | 1354 |
| 1375 class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES, 1> {}; | 1355 class NilValueField : public BitField<NilValue, 0, 1> {}; |
| 1356 class TypesField : public BitField<byte, 1, NUMBER_OF_TYPES> {}; |
| 1376 | 1357 |
| 1377 virtual CodeStub::Major MajorKey() { return CompareNilIC; } | 1358 virtual CodeStub::Major MajorKey() { return CompareNilIC; } |
| 1378 virtual int NotMissMinorKey() { return GetExtraICState(); } | 1359 virtual int NotMissMinorKey() { return GetExtraICState(); } |
| 1379 | 1360 |
| 1380 NilValue nil_value_; | 1361 NilValue nil_value_; |
| 1381 State state_; | 1362 State state_; |
| 1382 | 1363 |
| 1383 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); | 1364 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); |
| 1384 }; | 1365 }; |
| 1385 | 1366 |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 void Generate(MacroAssembler* masm); | 1748 void Generate(MacroAssembler* masm); |
| 1768 | 1749 |
| 1769 private: | 1750 private: |
| 1770 Major MajorKey() { return KeyedLoadElement; } | 1751 Major MajorKey() { return KeyedLoadElement; } |
| 1771 int MinorKey() { return DICTIONARY_ELEMENTS; } | 1752 int MinorKey() { return DICTIONARY_ELEMENTS; } |
| 1772 | 1753 |
| 1773 DISALLOW_COPY_AND_ASSIGN(KeyedLoadDictionaryElementStub); | 1754 DISALLOW_COPY_AND_ASSIGN(KeyedLoadDictionaryElementStub); |
| 1774 }; | 1755 }; |
| 1775 | 1756 |
| 1776 | 1757 |
| 1758 class DoubleToIStub : public PlatformCodeStub { |
| 1759 public: |
| 1760 DoubleToIStub(Register source, |
| 1761 Register destination, |
| 1762 int offset, |
| 1763 bool is_truncating) : bit_field_(0) { |
| 1764 #if V8_TARGET_ARCH_A64 |
| 1765 // TODO(jbramley): Make A64's Register type compatible with the normal code, |
| 1766 // so we don't need this special case. |
| 1767 bit_field_ = SourceRegisterBits::encode(source.code()) | |
| 1768 DestinationRegisterBits::encode(destination.code()) | |
| 1769 OffsetBits::encode(offset) | |
| 1770 IsTruncatingBits::encode(is_truncating); |
| 1771 #else |
| 1772 bit_field_ = SourceRegisterBits::encode(source.code_) | |
| 1773 DestinationRegisterBits::encode(destination.code_) | |
| 1774 OffsetBits::encode(offset) | |
| 1775 IsTruncatingBits::encode(is_truncating); |
| 1776 #endif |
| 1777 } |
| 1778 |
| 1779 Register source() { |
| 1780 #if V8_TARGET_ARCH_A64 |
| 1781 // TODO(jbramley): Make A64's Register type compatible with the normal code, |
| 1782 // so we don't need this special case. |
| 1783 return Register::XRegFromCode(SourceRegisterBits::decode(bit_field_)); |
| 1784 #else |
| 1785 Register result = { SourceRegisterBits::decode(bit_field_) }; |
| 1786 return result; |
| 1787 #endif |
| 1788 } |
| 1789 |
| 1790 Register destination() { |
| 1791 #if V8_TARGET_ARCH_A64 |
| 1792 // TODO(jbramley): Make A64's Register type compatible with the normal code, |
| 1793 // so we don't need this special case. |
| 1794 return Register::XRegFromCode(DestinationRegisterBits::decode(bit_field_)); |
| 1795 #else |
| 1796 Register result = { DestinationRegisterBits::decode(bit_field_) }; |
| 1797 return result; |
| 1798 #endif |
| 1799 } |
| 1800 |
| 1801 bool is_truncating() { |
| 1802 return IsTruncatingBits::decode(bit_field_); |
| 1803 } |
| 1804 |
| 1805 int offset() { |
| 1806 return OffsetBits::decode(bit_field_); |
| 1807 } |
| 1808 |
| 1809 void Generate(MacroAssembler* masm); |
| 1810 |
| 1811 private: |
| 1812 static const int kBitsPerRegisterNumber = 6; |
| 1813 STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters); |
| 1814 class SourceRegisterBits: |
| 1815 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT |
| 1816 class DestinationRegisterBits: |
| 1817 public BitField<int, kBitsPerRegisterNumber, |
| 1818 kBitsPerRegisterNumber> {}; // NOLINT |
| 1819 class IsTruncatingBits: |
| 1820 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT |
| 1821 class OffsetBits: |
| 1822 public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT |
| 1823 |
| 1824 Major MajorKey() { return DoubleToI; } |
| 1825 int MinorKey() { return bit_field_; } |
| 1826 |
| 1827 int bit_field_; |
| 1828 |
| 1829 DISALLOW_COPY_AND_ASSIGN(DoubleToIStub); |
| 1830 }; |
| 1831 |
| 1832 |
| 1777 class KeyedLoadFastElementStub : public HydrogenCodeStub { | 1833 class KeyedLoadFastElementStub : public HydrogenCodeStub { |
| 1778 public: | 1834 public: |
| 1779 KeyedLoadFastElementStub(bool is_js_array, ElementsKind elements_kind) { | 1835 KeyedLoadFastElementStub(bool is_js_array, ElementsKind elements_kind) { |
| 1780 bit_field_ = ElementsKindBits::encode(elements_kind) | | 1836 bit_field_ = ElementsKindBits::encode(elements_kind) | |
| 1781 IsJSArrayBits::encode(is_js_array); | 1837 IsJSArrayBits::encode(is_js_array); |
| 1782 } | 1838 } |
| 1783 | 1839 |
| 1784 bool is_js_array() const { | 1840 bool is_js_array() const { |
| 1785 return IsJSArrayBits::decode(bit_field_); | 1841 return IsJSArrayBits::decode(bit_field_); |
| 1786 } | 1842 } |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 int MinorKey() { return 0; } | 2380 int MinorKey() { return 0; } |
| 2325 | 2381 |
| 2326 void Generate(MacroAssembler* masm); | 2382 void Generate(MacroAssembler* masm); |
| 2327 | 2383 |
| 2328 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2384 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
| 2329 }; | 2385 }; |
| 2330 | 2386 |
| 2331 } } // namespace v8::internal | 2387 } } // namespace v8::internal |
| 2332 | 2388 |
| 2333 #endif // V8_CODE_STUBS_H_ | 2389 #endif // V8_CODE_STUBS_H_ |
| OLD | NEW |