Changeset 276039 in webkit
- Timestamp:
- Apr 15, 2021, 12:18:50 PM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 4 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r275797 r276039 918 918 runtime/GlobalExecutable.h 919 919 runtime/HashMapImpl.h 920 runtime/HashMapImplInlines.h 920 921 runtime/Identifier.h 921 922 runtime/IdentifierInlines.h … … 975 976 runtime/JSLock.h 976 977 runtime/JSMap.h 978 runtime/JSMapInlines.h 977 979 runtime/JSMapIterator.h 978 980 runtime/JSModuleLoader.h … … 992 994 runtime/JSSegmentedVariableObject.h 993 995 runtime/JSSet.h 996 runtime/JSSetInlines.h 994 997 runtime/JSSetIterator.h 995 998 runtime/JSSourceCode.h … … 1000 1003 runtime/JSTypeInfo.h 1001 1004 runtime/JSTypedArrays.h 1005 runtime/JSWeakMap.h 1006 runtime/JSWeakMapInlines.h 1002 1007 runtime/JSWithScope.h 1003 1008 runtime/JSWrapperObject.h -
trunk/Source/JavaScriptCore/ChangeLog
r276005 r276039 1 2021-04-15 Mark Lam <mark.lam@apple.com> 2 3 Refactor inline functions out of HashMapImpl.h into HashMapImplInlines.h. 4 https://bugs.webkit.org/show_bug.cgi?id=224616 5 rdar://76713709 6 7 Reviewed by Yusuke Suzuki. 8 9 Also do the same for clients of HashMapImpl that require similar refactoring. 10 This fixes the #include of JSCJSValueInlines.h in HashMapImpl.h, as well as makes 11 it easier to use other inline functions from other classes in the implementation 12 of HashMapImpl's inline functions in the future. 13 14 This patch only moves inline functions out to their respective *Inlines.h. 15 There are no behavior changes. 16 17 * CMakeLists.txt: 18 * JavaScriptCore.xcodeproj/project.pbxproj: 19 * dfg/DFGAbstractInterpreterInlines.h: 20 * dfg/DFGOperations.cpp: 21 * runtime/AbstractModuleRecord.cpp: 22 * runtime/HashMapImpl.cpp: 23 * runtime/HashMapImpl.h: 24 (JSC::areKeysEqual): Deleted. 25 (JSC::normalizeMapKey): Deleted. 26 (JSC::wangsInt64Hash): Deleted. 27 (JSC::jsMapHash): Deleted. 28 (JSC::concurrentJSMapHash): Deleted. 29 (JSC::shouldShrink): Deleted. 30 (JSC::shouldRehashAfterAdd): Deleted. 31 (JSC::nextCapacity): Deleted. 32 (JSC::HashMapImpl::finishCreation): Deleted. 33 (JSC::HashMapImpl::findBucket): Deleted. 34 (JSC::HashMapImpl::get): Deleted. 35 (JSC::HashMapImpl::has): Deleted. 36 (JSC::HashMapImpl::add): Deleted. 37 (JSC::HashMapImpl::addNormalized): Deleted. 38 (JSC::HashMapImpl::remove): Deleted. 39 (JSC::HashMapImpl::clear): Deleted. 40 (JSC::HashMapImpl::setUpHeadAndTail): Deleted. 41 (JSC::HashMapImpl::addNormalizedNonExistingForCloning): Deleted. 42 (JSC::HashMapImpl::addNormalizedInternal): Deleted. 43 (JSC::HashMapImpl::findBucketAlreadyHashedAndNormalized): Deleted. 44 (JSC::HashMapImpl::rehash): Deleted. 45 (JSC::HashMapImpl::checkConsistency const): Deleted. 46 (JSC::HashMapImpl::makeAndSetNewBuffer): Deleted. 47 (JSC::HashMapImpl::assertBufferIsEmpty const): Deleted. 48 * runtime/HashMapImplInlines.h: Added. 49 (JSC::areKeysEqual): 50 (JSC::normalizeMapKey): 51 (JSC::wangsInt64Hash): 52 (JSC::jsMapHash): 53 (JSC::concurrentJSMapHash): 54 (JSC::shouldShrink): 55 (JSC::shouldRehashAfterAdd): 56 (JSC::nextCapacity): 57 (JSC::HashMapImpl<HashMapBucketType>::finishCreation): 58 (JSC::HashMapImpl<HashMapBucketType>::findBucket): 59 (JSC::HashMapImpl<HashMapBucketType>::get): 60 (JSC::HashMapImpl<HashMapBucketType>::has): 61 (JSC::HashMapImpl<HashMapBucketType>::add): 62 (JSC::HashMapImpl<HashMapBucketType>::addNormalized): 63 (JSC::HashMapImpl<HashMapBucketType>::remove): 64 (JSC::HashMapImpl<HashMapBucketType>::clear): 65 (JSC::HashMapImpl<HashMapBucketType>::setUpHeadAndTail): 66 (JSC::HashMapImpl<HashMapBucketType>::addNormalizedNonExistingForCloning): 67 (JSC::HashMapImpl<HashMapBucketType>::addNormalizedInternal): 68 (JSC::HashMapImpl<HashMapBucketType>::findBucketAlreadyHashedAndNormalized): 69 (JSC::HashMapImpl<HashMapBucketType>::rehash): 70 (JSC::HashMapImpl<HashMapBucketType>::checkConsistency const): 71 (JSC::HashMapImpl<HashMapBucketType>::makeAndSetNewBuffer): 72 (JSC::HashMapImpl<HashMapBucketType>::assertBufferIsEmpty const): 73 * runtime/JSMap.h: 74 * runtime/JSMapInlines.h: Added. 75 (JSC::JSMap::set): 76 * runtime/JSSetInlines.h: Added. 77 * runtime/JSWeakMap.h: 78 * runtime/JSWeakMapInlines.h: Added. 79 (JSC::JSWeakMap::set): 80 * runtime/MapConstructor.cpp: 81 * runtime/MapPrototype.cpp: 82 * runtime/SetConstructor.cpp: 83 * runtime/WeakMapConstructor.cpp: 84 * runtime/WeakMapImpl.h: 85 (JSC::jsWeakMapHash): Deleted. 86 (JSC::nextCapacityAfterBatchRemoval): Deleted. 87 (JSC::WeakMapImpl::add): Deleted. 88 (JSC::WeakMapImpl::shouldRehashAfterAdd const): Deleted. 89 (JSC::WeakMapImpl::rehash): Deleted. 90 * runtime/WeakMapImplInlines.h: 91 (JSC::jsWeakMapHash): 92 (JSC::nextCapacityAfterBatchRemoval): 93 (JSC::WeakMapImpl<WeakMapBucket>::add): 94 (JSC::WeakMapImpl<WeakMapBucket>::rehash): 95 (JSC::WeakMapImpl<WeakMapBucket>::shouldRehashAfterAdd const): 96 * runtime/WeakMapPrototype.cpp: 97 1 98 2021-04-15 Yusuke Suzuki <ysuzuki@apple.com> 2 99 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r275920 r276039 2012 2012 FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; }; 2013 2013 FEF49AAB1EB9484B00653BDB /* MultithreadedMultiVMExecutionTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF49AA91EB947FE00653BDB /* MultithreadedMultiVMExecutionTest.cpp */; }; 2014 FEF5B4232628A0EE0016E776 /* HashMapImplInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF5B4222628A0EE0016E776 /* HashMapImplInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2015 FEF5B4252628A8500016E776 /* JSMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF5B4242628A8500016E776 /* JSMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2016 FEF5B4272628ABD90016E776 /* JSWeakMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF5B4262628ABD90016E776 /* JSWeakMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2017 FEF5B4292628B5240016E776 /* JSSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF5B4282628B5240016E776 /* JSSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2014 2018 FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2015 2019 /* End PBXBuildFile section */ … … 5418 5422 FEF49AA91EB947FE00653BDB /* MultithreadedMultiVMExecutionTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MultithreadedMultiVMExecutionTest.cpp; path = API/tests/MultithreadedMultiVMExecutionTest.cpp; sourceTree = "<group>"; }; 5419 5423 FEF49AAA1EB947FE00653BDB /* MultithreadedMultiVMExecutionTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultithreadedMultiVMExecutionTest.h; path = API/tests/MultithreadedMultiVMExecutionTest.h; sourceTree = "<group>"; }; 5424 FEF5B4222628A0EE0016E776 /* HashMapImplInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMapImplInlines.h; sourceTree = "<group>"; }; 5425 FEF5B4242628A8500016E776 /* JSMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMapInlines.h; sourceTree = "<group>"; }; 5426 FEF5B4262628ABD90016E776 /* JSWeakMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakMapInlines.h; sourceTree = "<group>"; }; 5427 FEF5B4282628B5240016E776 /* JSSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSetInlines.h; sourceTree = "<group>"; }; 5420 5428 FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; }; 5421 5429 /* End PBXFileReference section */ … … 7393 7401 79A0907D1D768465008B889B /* HashMapImpl.cpp */, 7394 7402 79A0907E1D768465008B889B /* HashMapImpl.h */, 7403 FEF5B4222628A0EE0016E776 /* HashMapImplInlines.h */, 7395 7404 79DFCBDA1D88C59600527D03 /* HasOwnPropertyCache.h */, 7396 7405 933A349D038AE80F008635CE /* Identifier.cpp */, … … 7590 7599 A700873F17CBE8EB00C3E643 /* JSMap.cpp */, 7591 7600 A700874017CBE8EB00C3E643 /* JSMap.h */, 7601 FEF5B4242628A8500016E776 /* JSMapInlines.h */, 7592 7602 A74DEF8F182D991400522C22 /* JSMapIterator.cpp */, 7593 7603 A74DEF90182D991400522C22 /* JSMapIterator.h */, … … 7631 7641 A7299D9B17D12837005F5FF9 /* JSSet.cpp */, 7632 7642 A7299D9C17D12837005F5FF9 /* JSSet.h */, 7643 FEF5B4282628B5240016E776 /* JSSetInlines.h */, 7633 7644 A790DD69182F499700588807 /* JSSetIterator.cpp */, 7634 7645 A790DD6A182F499700588807 /* JSSetIterator.h */, … … 7665 7676 A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */, 7666 7677 A7CA3AE217DA41AE006538AF /* JSWeakMap.h */, 7678 FEF5B4262628ABD90016E776 /* JSWeakMapInlines.h */, 7667 7679 539BFBB122AD3D8C0023F4C0 /* JSWeakObjectRef.cpp */, 7668 7680 539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */, … … 9436 9448 A7C1EAF017987AB600299DB2 /* CLoopStackInlines.h in Headers */, 9437 9449 969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */, 9450 FEF5B4292628B5240016E776 /* JSSetInlines.h in Headers */, 9438 9451 0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */, 9439 9452 0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */, … … 9634 9647 0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */, 9635 9648 0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */, 9649 FEF5B4272628ABD90016E776 /* JSWeakMapInlines.h in Headers */, 9636 9650 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */, 9637 9651 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */, … … 9764 9778 0F9D4C0D1C3E1C11006CD984 /* FTLExceptionTarget.h in Headers */, 9765 9779 0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */, 9780 FEF5B4232628A0EE0016E776 /* HashMapImplInlines.h in Headers */, 9766 9781 0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */, 9767 9782 0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */, … … 10541 10556 7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */, 10542 10557 7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */, 10558 FEF5B4252628A8500016E776 /* JSMapInlines.h in Headers */, 10543 10559 2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */, 10544 10560 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */, -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r274037 r276039 1 1 /* 2 * Copyright (C) 2013-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 #include "GetByStatus.h" 39 39 #include "GetterSetter.h" 40 #include "HashMapImpl .h"40 #include "HashMapImplInlines.h" 41 41 #include "JITOperations.h" 42 42 #include "JSAsyncGenerator.h" -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r275995 r276039 61 61 #include "JSSet.h" 62 62 #include "JSSetIterator.h" 63 #include "JSWeakMap .h"63 #include "JSWeakMapInlines.h" 64 64 #include "JSWeakSet.h" 65 65 #include "NumberConstructor.h" -
trunk/Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp
r273225 r276039 30 30 #include "JSCInlines.h" 31 31 #include "JSInternalFieldObjectImplInlines.h" 32 #include "JSMap .h"32 #include "JSMapInlines.h" 33 33 #include "JSModuleEnvironment.h" 34 34 #include "JSModuleNamespaceObject.h" -
trunk/Source/JavaScriptCore/runtime/HashMapImpl.cpp
r273138 r276039 27 27 #include "HashMapImpl.h" 28 28 29 #include "HashMapImplInlines.h" 29 30 #include "JSCInlines.h" 30 31 -
trunk/Source/JavaScriptCore/runtime/HashMapImpl.h
r275969 r276039 27 27 28 28 #include "ExceptionHelpers.h" 29 #include "JSCJSValue Inlines.h"29 #include "JSCJSValue.h" 30 30 #include "JSObject.h" 31 31 … … 231 231 }; 232 232 233 ALWAYS_INLINE static bool areKeysEqual(JSGlobalObject* globalObject, JSValue a, JSValue b) 234 { 235 // We want +0 and -0 to be compared to true here. sameValue() itself doesn't 236 // guarantee that, however, we normalize all keys before comparing and storing 237 // them in the map. The normalization will convert -0.0 and 0.0 to the integer 238 // representation for 0. 239 return sameValue(globalObject, a, b); 240 } 233 ALWAYS_INLINE static bool areKeysEqual(JSGlobalObject*, JSValue, JSValue); 241 234 242 235 // Note that normalization is inlined in DFG's NormalizeMapKey. 243 236 // Keep in sync with the implementation of DFG and FTL normalization. 244 ALWAYS_INLINE JSValue normalizeMapKey(JSValue key) 245 { 246 if (!key.isNumber()) { 247 if (key.isHeapBigInt()) 248 return tryConvertToBigInt32(key.asHeapBigInt()); 249 return key; 250 } 251 252 if (key.isInt32()) 253 return key; 254 255 double d = key.asDouble(); 256 if (std::isnan(d)) 257 return jsNaN(); 258 259 int i = static_cast<int>(d); 260 if (i == d) { 261 // When a key is -0, we convert it to positive zero. 262 // When a key is the double representation for an integer, we convert it to an integer. 263 return jsNumber(i); 264 } 265 // This means key is definitely not negative zero, and it's definitely not a double representation of an integer. 266 return key; 267 } 268 269 static ALWAYS_INLINE uint32_t wangsInt64Hash(uint64_t key) 270 { 271 key += ~(key << 32); 272 key ^= (key >> 22); 273 key += ~(key << 13); 274 key ^= (key >> 8); 275 key += (key << 3); 276 key ^= (key >> 15); 277 key += ~(key << 27); 278 key ^= (key >> 31); 279 return static_cast<unsigned>(key); 280 } 281 282 ALWAYS_INLINE uint32_t jsMapHash(JSBigInt* bigInt) 283 { 284 return bigInt->hash(); 285 } 286 287 ALWAYS_INLINE uint32_t jsMapHash(JSGlobalObject* globalObject, VM& vm, JSValue value) 288 { 289 ASSERT_WITH_MESSAGE(normalizeMapKey(value) == value, "We expect normalized values flowing into this function."); 290 291 if (value.isString()) { 292 auto scope = DECLARE_THROW_SCOPE(vm); 293 const String& wtfString = asString(value)->value(globalObject); 294 RETURN_IF_EXCEPTION(scope, UINT_MAX); 295 return wtfString.impl()->hash(); 296 } 297 298 if (value.isHeapBigInt()) 299 return jsMapHash(value.asHeapBigInt()); 300 301 return wangsInt64Hash(JSValue::encode(value)); 302 } 303 304 ALWAYS_INLINE Optional<uint32_t> concurrentJSMapHash(JSValue key) 305 { 306 key = normalizeMapKey(key); 307 if (key.isString()) { 308 JSString* string = asString(key); 309 if (string->length() > 10 * 1024) 310 return WTF::nullopt; 311 const StringImpl* impl = string->tryGetValueImpl(); 312 if (!impl) 313 return WTF::nullopt; 314 return impl->concurrentHash(); 315 } 316 317 if (key.isHeapBigInt()) 318 return key.asHeapBigInt()->concurrentHash(); 319 320 uint64_t rawValue = JSValue::encode(key); 321 return wangsInt64Hash(rawValue); 322 } 323 324 ALWAYS_INLINE uint32_t shouldShrink(uint32_t capacity, uint32_t keyCount) 325 { 326 return 8 * keyCount <= capacity && capacity > 4; 327 } 328 329 ALWAYS_INLINE uint32_t shouldRehashAfterAdd(uint32_t capacity, uint32_t keyCount, uint32_t deleteCount) 330 { 331 return 2 * (keyCount + deleteCount) >= capacity; 332 } 333 334 ALWAYS_INLINE uint32_t nextCapacity(uint32_t capacity, uint32_t keyCount) 335 { 336 if (shouldShrink(capacity, keyCount)) { 337 ASSERT((capacity / 2) >= 4); 338 return capacity / 2; 339 } 340 341 if (3 * keyCount <= capacity && capacity > 64) { 342 // We stay at the same size if rehashing would cause us to be no more than 343 // 1/3rd full. This comes up for programs like this: 344 // Say the hash table grew to a key count of 64, causing it to grow to a capacity of 256. 345 // Then, the table added 63 items. The load is now 127. Then, 63 items are deleted. 346 // The load is still 127. Then, another item is added. The load is now 128, and we 347 // decide that we need to rehash. The key count is 65, almost exactly what it was 348 // when we grew to a capacity of 256. We don't really need to grow to a capacity 349 // of 512 in this situation. Instead, we choose to rehash at the same size. This 350 // will bring the load down to 65. We rehash into the same size when we determine 351 // that the new load ratio will be under 1/3rd. (We also pick a minumum capacity 352 // at which this rule kicks in because otherwise we will be too sensitive to rehashing 353 // at the same capacity). 354 return capacity; 355 } 356 return (Checked<uint32_t>(capacity) * 2).unsafeGet(); 357 } 237 ALWAYS_INLINE JSValue normalizeMapKey(JSValue key); 238 static ALWAYS_INLINE uint32_t wangsInt64Hash(uint64_t key); 239 ALWAYS_INLINE uint32_t jsMapHash(JSBigInt*); 240 ALWAYS_INLINE uint32_t jsMapHash(JSGlobalObject*, VM&, JSValue); 241 ALWAYS_INLINE uint32_t shouldShrink(uint32_t capacity, uint32_t keyCount); 242 ALWAYS_INLINE uint32_t shouldRehashAfterAdd(uint32_t capacity, uint32_t keyCount, uint32_t deleteCount); 243 ALWAYS_INLINE uint32_t nextCapacity(uint32_t capacity, uint32_t keyCount); 358 244 359 245 template <typename HashMapBucketType> … … 392 278 } 393 279 394 void finishCreation(JSGlobalObject* globalObject, VM& vm) 395 { 396 ASSERT_WITH_MESSAGE(HashMapBucket<HashMapBucketDataKey>::offsetOfKey() == HashMapBucket<HashMapBucketDataKeyValue>::offsetOfKey(), "We assume this to be true in the DFG and FTL JIT."); 397 398 auto scope = DECLARE_THROW_SCOPE(vm); 399 Base::finishCreation(vm); 400 401 makeAndSetNewBuffer(globalObject, vm); 402 RETURN_IF_EXCEPTION(scope, void()); 403 404 setUpHeadAndTail(globalObject, vm); 405 } 406 407 void finishCreation(JSGlobalObject* globalObject, VM& vm, HashMapImpl* base) 408 { 409 auto scope = DECLARE_THROW_SCOPE(vm); 410 Base::finishCreation(vm); 411 412 // This size should be the same to the case when you clone the map by calling add() repeatedly. 413 uint32_t capacity = ((Checked<uint32_t>(base->m_keyCount) * 2) + 1).unsafeGet(); 414 RELEASE_ASSERT(capacity <= (1U << 31)); 415 capacity = std::max<uint32_t>(WTF::roundUpToPowerOfTwo(capacity), 4U); 416 m_capacity = capacity; 417 makeAndSetNewBuffer(globalObject, vm); 418 RETURN_IF_EXCEPTION(scope, void()); 419 420 setUpHeadAndTail(globalObject, vm); 421 422 HashMapBucketType* bucket = base->m_head.get()->next(); 423 while (bucket) { 424 if (!bucket->deleted()) { 425 addNormalizedNonExistingForCloning(globalObject, bucket->key(), HashMapBucketType::extractValue(*bucket)); 426 RETURN_IF_EXCEPTION(scope, void()); 427 } 428 bucket = bucket->next(); 429 } 430 checkConsistency(); 431 } 280 void finishCreation(JSGlobalObject*, VM&); 281 void finishCreation(JSGlobalObject*, VM&, HashMapImpl* base); 432 282 433 283 static HashMapBucketType* emptyValue() … … 451 301 } 452 302 453 ALWAYS_INLINE HashMapBucketType** findBucket(JSGlobalObject* globalObject, JSValue key) 454 { 455 VM& vm = getVM(globalObject); 456 auto scope = DECLARE_THROW_SCOPE(vm); 457 key = normalizeMapKey(key); 458 uint32_t hash = jsMapHash(globalObject, vm, key); 459 RETURN_IF_EXCEPTION(scope, nullptr); 460 return findBucket(globalObject, key, hash); 461 } 462 463 ALWAYS_INLINE HashMapBucketType** findBucket(JSGlobalObject* globalObject, JSValue key, uint32_t hash) 464 { 465 ASSERT_WITH_MESSAGE(normalizeMapKey(key) == key, "We expect normalized values flowing into this function."); 466 return findBucketAlreadyHashedAndNormalized(globalObject, key, hash); 467 } 303 ALWAYS_INLINE HashMapBucketType** findBucket(JSGlobalObject*, JSValue key); 304 305 ALWAYS_INLINE HashMapBucketType** findBucket(JSGlobalObject*, JSValue key, uint32_t hash); 468 306 469 307 template <typename T = HashMapBucketType> 470 ALWAYS_INLINE typename std::enable_if<std::is_same<T, HashMapBucket<HashMapBucketDataKeyValue>>::value, JSValue>::type get(JSGlobalObject* globalObject, JSValue key) 471 { 472 if (HashMapBucketType** bucket = findBucket(globalObject, key)) 473 return (*bucket)->value(); 474 return jsUndefined(); 475 } 476 477 ALWAYS_INLINE bool has(JSGlobalObject* globalObject, JSValue key) 478 { 479 return !!findBucket(globalObject, key); 480 } 481 482 ALWAYS_INLINE void add(JSGlobalObject* globalObject, JSValue key, JSValue value = JSValue()) 483 { 484 VM& vm = getVM(globalObject); 485 auto scope = DECLARE_THROW_SCOPE(vm); 486 487 key = normalizeMapKey(key); 488 addNormalizedInternal(globalObject, key, value, [&] (HashMapBucketType* bucket) { 489 return !isDeleted(bucket) && areKeysEqual(globalObject, key, bucket->key()); 490 }); 491 RETURN_IF_EXCEPTION(scope, void()); 492 scope.release(); 493 if (shouldRehashAfterAdd()) 494 rehash(globalObject); 495 } 496 497 ALWAYS_INLINE HashMapBucketType* addNormalized(JSGlobalObject* globalObject, JSValue key, JSValue value, uint32_t hash) 498 { 499 VM& vm = getVM(globalObject); 500 ASSERT_WITH_MESSAGE(normalizeMapKey(key) == key, "We expect normalized values flowing into this function."); 501 DEFER_TERMINATION_AND_ASSERT_WITH_MESSAGE(vm, jsMapHash(globalObject, getVM(globalObject), key) == hash, "We expect hash value is what we expect."); 502 503 auto* bucket = addNormalizedInternal(vm, key, value, hash, [&] (HashMapBucketType* bucket) { 504 return !isDeleted(bucket) && areKeysEqual(globalObject, key, bucket->key()); 505 }); 506 if (shouldRehashAfterAdd()) 507 rehash(globalObject); 508 return bucket; 509 } 510 511 ALWAYS_INLINE bool remove(JSGlobalObject* globalObject, JSValue key) 512 { 513 HashMapBucketType** bucket = findBucket(globalObject, key); 514 if (!bucket) 515 return false; 516 517 VM& vm = getVM(globalObject); 518 HashMapBucketType* impl = *bucket; 519 impl->next()->setPrev(vm, impl->prev()); 520 impl->prev()->setNext(vm, impl->next()); 521 impl->makeDeleted(vm); 522 523 *bucket = deletedValue(); 524 525 ++m_deleteCount; 526 ASSERT(m_keyCount > 0); 527 --m_keyCount; 528 529 if (shouldShrink()) 530 rehash(globalObject); 531 532 return true; 533 } 308 ALWAYS_INLINE typename std::enable_if<std::is_same<T, HashMapBucket<HashMapBucketDataKeyValue>>::value, JSValue>::type get(JSGlobalObject*, JSValue key); 309 310 ALWAYS_INLINE bool has(JSGlobalObject*, JSValue key); 311 312 ALWAYS_INLINE void add(JSGlobalObject*, JSValue key, JSValue = JSValue()); 313 314 ALWAYS_INLINE HashMapBucketType* addNormalized(JSGlobalObject*, JSValue key, JSValue, uint32_t hash); 315 316 ALWAYS_INLINE bool remove(JSGlobalObject*, JSValue key); 534 317 535 318 ALWAYS_INLINE uint32_t size() const … … 538 321 } 539 322 540 ALWAYS_INLINE void clear(JSGlobalObject* globalObject) 541 { 542 VM& vm = getVM(globalObject); 543 m_keyCount = 0; 544 m_deleteCount = 0; 545 HashMapBucketType* head = m_head.get(); 546 HashMapBucketType* bucket = m_head->next(); 547 HashMapBucketType* tail = m_tail.get(); 548 while (bucket != tail) { 549 HashMapBucketType* next = bucket->next(); 550 // We restart each iterator by pointing it to the head of the list. 551 bucket->setNext(vm, head); 552 bucket->makeDeleted(vm); 553 bucket = next; 554 } 555 m_head->setNext(vm, m_tail.get()); 556 m_tail->setPrev(vm, m_head.get()); 557 m_capacity = 4; 558 makeAndSetNewBuffer(globalObject, vm); 559 checkConsistency(); 560 } 323 ALWAYS_INLINE void clear(JSGlobalObject*); 561 324 562 325 ALWAYS_INLINE size_t bufferSizeInBytes() const … … 603 366 } 604 367 605 ALWAYS_INLINE void setUpHeadAndTail(JSGlobalObject*, VM& vm) 606 { 607 m_head.set(vm, this, HashMapBucketType::create(vm)); 608 m_tail.set(vm, this, HashMapBucketType::create(vm)); 609 610 m_head->setNext(vm, m_tail.get()); 611 m_tail->setPrev(vm, m_head.get()); 612 ASSERT(m_head->deleted()); 613 ASSERT(m_tail->deleted()); 614 } 615 616 ALWAYS_INLINE void addNormalizedNonExistingForCloning(JSGlobalObject* globalObject, JSValue key, JSValue value = JSValue()) 617 { 618 addNormalizedInternal(globalObject, key, value, [&] (HashMapBucketType*) { 619 return false; 620 }); 621 } 368 ALWAYS_INLINE void setUpHeadAndTail(JSGlobalObject*, VM&); 369 370 ALWAYS_INLINE void addNormalizedNonExistingForCloning(JSGlobalObject*, JSValue key, JSValue = JSValue()); 622 371 623 372 template<typename CanUseBucket> 624 ALWAYS_INLINE void addNormalizedInternal(JSGlobalObject* globalObject, JSValue key, JSValue value, const CanUseBucket& canUseBucket) 625 { 626 VM& vm = getVM(globalObject); 627 auto scope = DECLARE_THROW_SCOPE(vm); 628 629 uint32_t hash = jsMapHash(globalObject, vm, key); 630 RETURN_IF_EXCEPTION(scope, void()); 631 scope.release(); 632 addNormalizedInternal(vm, key, value, hash, canUseBucket); 633 } 373 ALWAYS_INLINE void addNormalizedInternal(JSGlobalObject*, JSValue key, JSValue, const CanUseBucket&); 634 374 635 375 template<typename CanUseBucket> 636 ALWAYS_INLINE HashMapBucketType* addNormalizedInternal(VM& vm, JSValue key, JSValue value, uint32_t hash, const CanUseBucket& canUseBucket) 637 { 638 ASSERT_WITH_MESSAGE(normalizeMapKey(key) == key, "We expect normalized values flowing into this function."); 639 640 const uint32_t mask = m_capacity - 1; 641 uint32_t index = hash & mask; 642 HashMapBucketType** buffer = this->buffer(); 643 HashMapBucketType* bucket = buffer[index]; 644 while (!isEmpty(bucket)) { 645 if (canUseBucket(bucket)) { 646 bucket->setValue(vm, value); 647 return bucket; 648 } 649 index = (index + 1) & mask; 650 bucket = buffer[index]; 651 } 652 653 HashMapBucketType* newEntry = m_tail.get(); 654 buffer[index] = newEntry; 655 newEntry->setKey(vm, key); 656 newEntry->setValue(vm, value); 657 ASSERT(!newEntry->deleted()); 658 HashMapBucketType* newTail = HashMapBucketType::create(vm); 659 m_tail.set(vm, this, newTail); 660 newTail->setPrev(vm, newEntry); 661 ASSERT(newTail->deleted()); 662 newEntry->setNext(vm, newTail); 663 664 ++m_keyCount; 665 return newEntry; 666 } 667 668 ALWAYS_INLINE HashMapBucketType** findBucketAlreadyHashedAndNormalized(JSGlobalObject* globalObject, JSValue key, uint32_t hash) 669 { 670 const uint32_t mask = m_capacity - 1; 671 uint32_t index = hash & mask; 672 HashMapBucketType** buffer = this->buffer(); 673 HashMapBucketType* bucket = buffer[index]; 674 675 while (!isEmpty(bucket)) { 676 if (!isDeleted(bucket) && areKeysEqual(globalObject, key, bucket->key())) 677 return buffer + index; 678 index = (index + 1) & mask; 679 bucket = buffer[index]; 680 } 681 return nullptr; 682 } 683 684 void rehash(JSGlobalObject* globalObject) 685 { 686 VM& vm = getVM(globalObject); 687 auto scope = DECLARE_THROW_SCOPE(vm); 688 689 uint32_t oldCapacity = m_capacity; 690 m_capacity = nextCapacity(m_capacity, m_keyCount); 691 692 if (m_capacity != oldCapacity) { 693 makeAndSetNewBuffer(globalObject, vm); 694 RETURN_IF_EXCEPTION(scope, void()); 695 } else { 696 m_buffer->reset(m_capacity); 697 assertBufferIsEmpty(); 698 } 699 700 HashMapBucketType* iter = m_head->next(); 701 HashMapBucketType* end = m_tail.get(); 702 const uint32_t mask = m_capacity - 1; 703 RELEASE_ASSERT(!(m_capacity & (m_capacity - 1))); 704 HashMapBucketType** buffer = this->buffer(); 705 while (iter != end) { 706 uint32_t index = jsMapHash(globalObject, vm, iter->key()) & mask; 707 EXCEPTION_ASSERT_WITH_MESSAGE(!scope.exception(), "All keys should already be hashed before, so this should not throw because it won't resolve ropes."); 708 { 709 HashMapBucketType* bucket = buffer[index]; 710 while (!isEmpty(bucket)) { 711 index = (index + 1) & mask; 712 bucket = buffer[index]; 713 } 714 } 715 buffer[index] = iter; 716 iter = iter->next(); 717 } 718 719 m_deleteCount = 0; 720 721 checkConsistency(); 722 } 723 724 ALWAYS_INLINE void checkConsistency() const 725 { 726 if (ASSERT_ENABLED) { 727 HashMapBucketType* iter = m_head->next(); 728 HashMapBucketType* end = m_tail.get(); 729 uint32_t size = 0; 730 while (iter != end) { 731 ++size; 732 iter = iter->next(); 733 } 734 ASSERT(size == m_keyCount); 735 } 736 } 737 738 void makeAndSetNewBuffer(JSGlobalObject* globalObject, VM& vm) 739 { 740 ASSERT(!(m_capacity & (m_capacity - 1))); 741 742 HashMapBufferType* buffer = HashMapBufferType::create(globalObject, vm, this, m_capacity); 743 if (UNLIKELY(!buffer)) 744 return; 745 746 m_buffer.set(vm, this, buffer); 747 assertBufferIsEmpty(); 748 } 749 750 ALWAYS_INLINE void assertBufferIsEmpty() const 751 { 752 if (ASSERT_ENABLED) { 753 for (unsigned i = 0; i < m_capacity; i++) 754 ASSERT(isEmpty(buffer()[i])); 755 } 756 } 376 ALWAYS_INLINE HashMapBucketType* addNormalizedInternal(VM&, JSValue key, JSValue, uint32_t hash, const CanUseBucket&); 377 378 ALWAYS_INLINE HashMapBucketType** findBucketAlreadyHashedAndNormalized(JSGlobalObject*, JSValue key, uint32_t hash); 379 380 void rehash(JSGlobalObject*); 381 382 ALWAYS_INLINE void checkConsistency() const; 383 384 void makeAndSetNewBuffer(JSGlobalObject*, VM&); 385 386 ALWAYS_INLINE void assertBufferIsEmpty() const; 757 387 758 388 WriteBarrier<HashMapBucketType> m_head; -
trunk/Source/JavaScriptCore/runtime/JSMap.h
r275271 r276039 1 1 /* 2 * Copyright (C) 2013 , 2016Apple Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 55 55 } 56 56 57 ALWAYS_INLINE void set(JSGlobalObject* globalObject, JSValue key, JSValue value) 58 { 59 add(globalObject, key, value); 60 } 57 ALWAYS_INLINE void set(JSGlobalObject*, JSValue key, JSValue); 61 58 62 59 static bool isSetFastAndNonObservable(Structure*); -
trunk/Source/JavaScriptCore/runtime/JSWeakMap.h
r261159 r276039 1 1 /* 2 * Copyright (C) 2013 Apple, Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 49 49 } 50 50 51 ALWAYS_INLINE void set(VM& vm, JSObject* key, JSValue value) 52 { 53 add(vm, key, value); 54 } 51 ALWAYS_INLINE void set(VM&, JSObject* key, JSValue); 55 52 56 53 private: -
trunk/Source/JavaScriptCore/runtime/MapConstructor.cpp
r275271 r276039 1 1 /* 2 * Copyright (C) 2013-20 17Apple Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "IteratorOperations.h" 30 30 #include "JSCInlines.h" 31 #include "JSMap .h"31 #include "JSMapInlines.h" 32 32 #include "MapPrototype.h" 33 33 -
trunk/Source/JavaScriptCore/runtime/MapPrototype.cpp
r267594 r276039 1 1 /* 2 * Copyright (C) 2013-20 19Apple Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "BuiltinNames.h" 30 30 #include "JSCInlines.h" 31 #include "JSMap .h"31 #include "JSMapInlines.h" 32 32 #include "JSMapIterator.h" 33 33 -
trunk/Source/JavaScriptCore/runtime/SetConstructor.cpp
r275271 r276039 1 1 /* 2 * Copyright (C) 2013-20 17Apple Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "IteratorOperations.h" 30 30 #include "JSCInlines.h" 31 #include "JSSet .h"31 #include "JSSetInlines.h" 32 32 #include "SetPrototype.h" 33 33 -
trunk/Source/JavaScriptCore/runtime/WeakMapConstructor.cpp
r275271 r276039 1 1 /* 2 * Copyright (C) 2013-20 17Apple, Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "IteratorOperations.h" 30 30 #include "JSCInlines.h" 31 #include "JSWeakMap .h"31 #include "JSWeakMapInlines.h" 32 32 #include "WeakMapPrototype.h" 33 33 -
trunk/Source/JavaScriptCore/runtime/WeakMapImpl.h
r273138 r276039 51 51 static_assert(sizeof(WeakMapBucketDataKeyValue) == 16, ""); 52 52 53 ALWAYS_INLINE uint32_t jsWeakMapHash(JSObject* key) 54 { 55 return wangsInt64Hash(JSValue::encode(key)); 56 } 57 58 ALWAYS_INLINE uint32_t nextCapacityAfterBatchRemoval(uint32_t capacity, uint32_t keyCount) 59 { 60 while (shouldShrink(capacity, keyCount)) 61 capacity = nextCapacity(capacity, keyCount); 62 return capacity; 63 } 53 ALWAYS_INLINE uint32_t jsWeakMapHash(JSObject* key); 54 ALWAYS_INLINE uint32_t nextCapacityAfterBatchRemoval(uint32_t capacity, uint32_t keyCount); 64 55 65 56 template <typename Data> … … 242 233 } 243 234 244 ALWAYS_INLINE void add(VM& vm, JSObject* key, JSValue value = JSValue()) 245 { 246 DisallowGC disallowGC; 247 add(vm, key, value, jsWeakMapHash(key)); 248 } 249 250 ALWAYS_INLINE void add(VM& vm, JSObject* key, JSValue value, uint32_t hash) 251 { 252 DisallowGC disallowGC; 253 ASSERT_WITH_MESSAGE(jsWeakMapHash(key) == hash, "We expect hash value is what we expect."); 254 255 addInternal(vm, key, value, hash); 256 if (shouldRehashAfterAdd()) 257 rehash(); 258 } 235 ALWAYS_INLINE void add(VM&, JSObject* key, JSValue = JSValue()); 236 ALWAYS_INLINE void add(VM&, JSObject* key, JSValue, uint32_t hash); 259 237 260 238 ALWAYS_INLINE bool remove(JSObject* key) … … 348 326 } 349 327 350 ALWAYS_INLINE uint32_t shouldRehashAfterAdd() const 351 { 352 return JSC::shouldRehashAfterAdd(m_capacity, m_keyCount, m_deleteCount); 353 } 328 ALWAYS_INLINE uint32_t shouldRehashAfterAdd() const; 354 329 355 330 ALWAYS_INLINE uint32_t shouldShrink() const … … 404 379 405 380 enum class RehashMode { Normal, RemoveBatching }; 406 void rehash(RehashMode mode = RehashMode::Normal) 407 { 408 // Since shrinking is done just after GC runs (finalizeUnconditionally), WeakMapImpl::rehash() 409 // function must not touch any GC related features. This is why we do not allocate WeakMapBuffer 410 // in auxiliary buffer. 411 412 // This rehash modifies m_buffer which is not GC-managed buffer. But m_buffer can be touched in 413 // visitOutputConstraints. Thus, we should guard it with cellLock. 414 auto locker = holdLock(cellLock()); 415 416 uint32_t oldCapacity = m_capacity; 417 MallocPtr<WeakMapBufferType, JSValueMalloc> oldBuffer = WTFMove(m_buffer); 418 419 uint32_t capacity = m_capacity; 420 if (mode == RehashMode::RemoveBatching) { 421 ASSERT(shouldShrink()); 422 capacity = nextCapacityAfterBatchRemoval(capacity, m_keyCount); 423 } else 424 capacity = nextCapacity(capacity, m_keyCount); 425 makeAndSetNewBuffer(locker, capacity); 426 427 auto* buffer = this->buffer(); 428 const uint32_t mask = m_capacity - 1; 429 for (uint32_t oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) { 430 auto* entry = oldBuffer->buffer() + oldIndex; 431 if (entry->isEmpty() || entry->isDeleted()) 432 continue; 433 434 uint32_t index = jsWeakMapHash(entry->key()) & mask; 435 WeakMapBucketType* bucket = buffer + index; 436 while (!bucket->isEmpty()) { 437 index = (index + 1) & mask; 438 bucket = buffer + index; 439 } 440 bucket->copyFrom(*entry); 441 } 442 443 m_deleteCount = 0; 444 445 checkConsistency(); 446 } 381 void rehash(RehashMode = RehashMode::Normal); 447 382 448 383 ALWAYS_INLINE void checkConsistency() const -
trunk/Source/JavaScriptCore/runtime/WeakMapImplInlines.h
r243467 r276039 26 26 #pragma once 27 27 28 #include "HashMapImplInlines.h" 28 29 #include "WeakMapImpl.h" 29 30 30 31 namespace JSC { 32 33 ALWAYS_INLINE uint32_t jsWeakMapHash(JSObject* key) 34 { 35 return wangsInt64Hash(JSValue::encode(key)); 36 } 37 38 ALWAYS_INLINE uint32_t nextCapacityAfterBatchRemoval(uint32_t capacity, uint32_t keyCount) 39 { 40 while (shouldShrink(capacity, keyCount)) 41 capacity = nextCapacity(capacity, keyCount); 42 return capacity; 43 } 44 45 template <typename WeakMapBucket> 46 ALWAYS_INLINE void WeakMapImpl<WeakMapBucket>::add(VM& vm, JSObject* key, JSValue value) 47 { 48 DisallowGC disallowGC; 49 add(vm, key, value, jsWeakMapHash(key)); 50 } 51 52 template <typename WeakMapBucket> 53 ALWAYS_INLINE void WeakMapImpl<WeakMapBucket>::add(VM& vm, JSObject* key, JSValue value, uint32_t hash) 54 { 55 DisallowGC disallowGC; 56 ASSERT_WITH_MESSAGE(jsWeakMapHash(key) == hash, "We expect hash value is what we expect."); 57 58 addInternal(vm, key, value, hash); 59 if (shouldRehashAfterAdd()) 60 rehash(); 61 } 31 62 32 63 // Note that this function can be executed in parallel as long as the mutator stops. … … 53 84 } 54 85 86 template<typename WeakMapBucket> 87 void WeakMapImpl<WeakMapBucket>::rehash(RehashMode mode) 88 { 89 // Since shrinking is done just after GC runs (finalizeUnconditionally), WeakMapImpl::rehash() 90 // function must not touch any GC related features. This is why we do not allocate WeakMapBuffer 91 // in auxiliary buffer. 92 93 // This rehash modifies m_buffer which is not GC-managed buffer. But m_buffer can be touched in 94 // visitOutputConstraints. Thus, we should guard it with cellLock. 95 auto locker = holdLock(cellLock()); 96 97 uint32_t oldCapacity = m_capacity; 98 MallocPtr<WeakMapBufferType, JSValueMalloc> oldBuffer = WTFMove(m_buffer); 99 100 uint32_t capacity = m_capacity; 101 if (mode == RehashMode::RemoveBatching) { 102 ASSERT(shouldShrink()); 103 capacity = nextCapacityAfterBatchRemoval(capacity, m_keyCount); 104 } else 105 capacity = nextCapacity(capacity, m_keyCount); 106 makeAndSetNewBuffer(locker, capacity); 107 108 auto* buffer = this->buffer(); 109 const uint32_t mask = m_capacity - 1; 110 for (uint32_t oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) { 111 auto* entry = oldBuffer->buffer() + oldIndex; 112 if (entry->isEmpty() || entry->isDeleted()) 113 continue; 114 115 uint32_t index = jsWeakMapHash(entry->key()) & mask; 116 WeakMapBucket* bucket = buffer + index; 117 while (!bucket->isEmpty()) { 118 index = (index + 1) & mask; 119 bucket = buffer + index; 120 } 121 bucket->copyFrom(*entry); 122 } 123 124 m_deleteCount = 0; 125 126 checkConsistency(); 55 127 } 128 129 template<typename WeakMapBucket> 130 ALWAYS_INLINE uint32_t WeakMapImpl<WeakMapBucket>::shouldRehashAfterAdd() const 131 { 132 return JSC::shouldRehashAfterAdd(m_capacity, m_keyCount, m_deleteCount); 133 } 134 135 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp
r275271 r276039 1 1 /* 2 * Copyright (C) 2013-20 19Apple, Inc. All rights reserved.2 * Copyright (C) 2013-2021 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "JSCInlines.h" 30 #include "JSWeakMap .h"30 #include "JSWeakMapInlines.h" 31 31 32 32 namespace JSC { -
trunk/Source/WebCore/ChangeLog
r276033 r276039 1 2021-04-15 Mark Lam <mark.lam@apple.com> 2 3 Refactor inline functions out of HashMapImpl.h into HashMapImplInlines.h. 4 https://bugs.webkit.org/show_bug.cgi?id=224616 5 rdar://76713709 6 7 Reviewed by Yusuke Suzuki. 8 9 * bindings/js/SerializedScriptValue.cpp: 10 1 11 2021-04-15 Alex Christensen <achristensen@webkit.org> 2 12 -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp
r275882 r276039 72 72 #include <JavaScriptCore/JSCInlines.h> 73 73 #include <JavaScriptCore/JSDataView.h> 74 #include <JavaScriptCore/JSMap .h>74 #include <JavaScriptCore/JSMapInlines.h> 75 75 #include <JavaScriptCore/JSMapIterator.h> 76 #include <JavaScriptCore/JSSet .h>76 #include <JavaScriptCore/JSSetInlines.h> 77 77 #include <JavaScriptCore/JSSetIterator.h> 78 78 #include <JavaScriptCore/JSTypedArrays.h>
Note:
See TracChangeset
for help on using the changeset viewer.