Changeset 291756 in webkit
- Timestamp:
- Mar 23, 2022, 11:47:18 AM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
runtime/JSCustomGetterFunction.h (modified) (1 diff)
-
runtime/JSCustomSetterFunction.h (modified) (1 diff)
-
runtime/JSGlobalObject.h (modified) (1 diff)
-
runtime/JSGlobalObjectInlines.h (modified) (3 diffs)
-
runtime/JSObject.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r291755 r291756 1 2022-03-23 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC][MSVC] custom getter creation needs to include classInfo since MSVC ICF is not "safe" variant 4 https://bugs.webkit.org/show_bug.cgi?id=238030 5 6 Reviewed by Alexey Shvayka. 7 8 MSVC performs very aggressive ICF (identical code folding) and it even merges the identical two functions 9 into one even though a pointer to this function is used. This means MSVC's ICF is not "safe"[1], and custom 10 function weakmap is broken on MSVC since it is assuming function pointers are different for different functions. 11 Unfortunately, it seems that there is no attribute / annotation to prevent this behavior, so we need to workaround it. 12 Since JSCustomGetterFunction does separate thing based on attached DOMAttribute, we need to include const ClassInfo* 13 into a key of JSCustomGetterFunction weakmap to ensure that two identical functions with different const ClassInfo* 14 do not get the same JSCustomGetterFunction. 15 16 [1]: https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36912.pdf 17 18 * runtime/JSCustomGetterFunction.h: 19 * runtime/JSCustomSetterFunction.h: 20 * runtime/JSGlobalObject.h: 21 * runtime/JSGlobalObjectInlines.h: 22 (JSC::JSGlobalObject::WeakCustomGetterOrSetterHash<T>::hash): 23 * runtime/JSObject.cpp: 24 (JSC::WeakCustomGetterOrSetterHashTranslator::hash): 25 (JSC::WeakCustomGetterOrSetterHashTranslator::equal): 26 (JSC::createCustomGetterFunction): 27 (JSC::createCustomSetterFunction): 28 1 29 2022-03-23 Chris Dumez <cdumez@apple.com> 2 30 -
trunk/Source/JavaScriptCore/runtime/JSCustomGetterFunction.h
r290129 r291756 60 60 CustomFunctionPointer customFunctionPointer() const { return m_getter; }; 61 61 std::optional<DOMAttributeAnnotation> domAttribute() const { return m_domAttribute; }; 62 const ClassInfo* slotBaseClassInfoIfExists() const 63 { 64 if (m_domAttribute) 65 return m_domAttribute->classInfo; 66 return nullptr; 67 } 62 68 63 69 private: -
trunk/Source/JavaScriptCore/runtime/JSCustomSetterFunction.h
r290129 r291756 59 59 CustomFunctionPointer setter() const { return m_setter; }; 60 60 CustomFunctionPointer customFunctionPointer() const { return m_setter; }; 61 const ClassInfo* slotBaseClassInfoIfExists() const { return nullptr; } 61 62 62 63 private: -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r290209 r291756 600 600 static unsigned hash(const Weak<T>&); 601 601 static bool equal(const Weak<T>&, const Weak<T>&); 602 static unsigned hash(const PropertyName&, typename T::CustomFunctionPointer );602 static unsigned hash(const PropertyName&, typename T::CustomFunctionPointer, const ClassInfo*); 603 603 604 604 static constexpr bool safeToCompareToEmptyOrDeleted = false; -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h
r284590 r291756 35 35 #include "LinkTimeConstant.h" 36 36 #include "ObjectPrototype.h" 37 #include <wtf/Hasher.h> 37 38 38 39 namespace JSC { … … 154 155 if (!value) 155 156 return 0; 156 return hash(value->propertyName(), value->customFunctionPointer() );157 return hash(value->propertyName(), value->customFunctionPointer(), value->slotBaseClassInfoIfExists()); 157 158 } 158 159 … … 166 167 167 168 template<typename T> 168 inline unsigned JSGlobalObject::WeakCustomGetterOrSetterHash<T>::hash(const PropertyName& propertyName, typename T::CustomFunctionPointer functionPointer )169 inline unsigned JSGlobalObject::WeakCustomGetterOrSetterHash<T>::hash(const PropertyName& propertyName, typename T::CustomFunctionPointer functionPointer, const ClassInfo* classInfo) 169 170 { 170 unsigned hash = DefaultHash<typename T::CustomFunctionPointer>::hash(functionPointer);171 171 if (!propertyName.isNull()) 172 hash = WTF::pairIntHash(hash, propertyName.uid()->existingSymbolAwareHash());173 return hash;172 return WTF::computeHash(functionPointer, propertyName.uid()->existingSymbolAwareHash(), classInfo); 173 return WTF::computeHash(functionPointer, classInfo); 174 174 } 175 175 -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r288815 r291756 3622 3622 using BaseHash = JSGlobalObject::WeakCustomGetterOrSetterHash<T>; 3623 3623 3624 using Key = std:: pair<PropertyName, typename T::CustomFunctionPointer>;3624 using Key = std::tuple<PropertyName, typename T::CustomFunctionPointer, const ClassInfo*>; 3625 3625 3626 3626 static unsigned hash(const Key& key) 3627 3627 { 3628 return BaseHash::hash(std::get<0>(key), std::get<1>(key) );3628 return BaseHash::hash(std::get<0>(key), std::get<1>(key), std::get<2>(key)); 3629 3629 } 3630 3630 … … 3633 3633 if (!a) 3634 3634 return false; 3635 return a->propertyName() == std::get<0>(b) && a->customFunctionPointer() == std::get<1>(b) ;3635 return a->propertyName() == std::get<0>(b) && a->customFunctionPointer() == std::get<1>(b) && a->slotBaseClassInfoIfExists() == std::get<2>(b); 3636 3636 } 3637 3637 }; … … 3644 3644 // We use DeferGC here (1) not to invoke GC when executing WeakGCSet::ensureValue and (2) to avoid looking up HashSet twice. 3645 3645 DeferGC deferGC(vm); 3646 return globalObject->customGetterFunctionSet().ensureValue<Translator>(std::make_pair(propertyName, getValueFunc), [&] { 3646 const ClassInfo* classInfo = nullptr; 3647 if (domAttribute) 3648 classInfo = domAttribute->classInfo; 3649 return globalObject->customGetterFunctionSet().ensureValue<Translator>(std::tuple { propertyName, getValueFunc, classInfo }, [&] { 3647 3650 return JSCustomGetterFunction::create(vm, globalObject, propertyName, getValueFunc, domAttribute); 3648 3651 }); … … 3656 3659 // We use DeferGC here (1) not to invoke GC when executing WeakGCSet::ensureValue and (2) to avoid looking up HashSet twice. 3657 3660 DeferGC deferGC(vm); 3658 return globalObject->customSetterFunctionSet().ensureValue<Translator>(std:: make_pair(propertyName, putValueFunc), [&] {3661 return globalObject->customSetterFunctionSet().ensureValue<Translator>(std::tuple { propertyName, putValueFunc, nullptr }, [&] { 3659 3662 return JSCustomSetterFunction::create(vm, globalObject, propertyName, putValueFunc); 3660 3663 });
Note:
See TracChangeset
for help on using the changeset viewer.