Changeset 273766 in webkit
- Timestamp:
- Mar 2, 2021 3:33:43 PM (17 months ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
-
ChangeLog (modified) (1 diff)
-
runtime/ClassInfo.h (modified) (2 diffs)
-
runtime/JSCast.h (modified) (1 diff)
-
runtime/JSCell.cpp (modified) (1 diff)
-
runtime/JSCell.h (modified) (1 diff)
-
runtime/JSObject.cpp (modified) (3 diffs)
-
runtime/JSObject.h (modified) (1 diff)
-
runtime/JSPropertyNameEnumerator.h (modified) (1 diff)
-
runtime/JSProxy.cpp (modified) (1 diff)
-
runtime/JSProxy.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r273751 r273766 1 2021-03-02 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Optimize getEnumerableLength 4 https://bugs.webkit.org/show_bug.cgi?id=222539 5 6 Reviewed by Alexey Shvayka. 7 8 Now getEnumerableLength is only overridden by JSProxy. And this is called in the critical path of propertyNameEnumerator. 9 We should not use indirect call for getEnumerableLength. We remove indirect functions for getEnumerableLength. For JSProxy, 10 any results is OK since anyway JSProxy does not utilize the result of this function since it cannot use fast index enumerator. 11 12 We also avoid calling holesMustForwardToPrototype in getEnumerableLength when it is meaningless. For example, 13 if the object is ALL_BLANK_INDEXING_TYPES, then regardless of the condition of holesMustForwardToPrototype, the result of 14 getEnumerableLength is zero. 15 16 * runtime/ClassInfo.h: 17 * runtime/JSCast.h: 18 * runtime/JSCell.cpp: 19 (JSC::JSCell::getEnumerableLength): Deleted. 20 * runtime/JSCell.h: 21 * runtime/JSObject.cpp: 22 (JSC::JSObject::getEnumerableLength): 23 * runtime/JSObject.h: 24 * runtime/JSPropertyNameEnumerator.h: 25 (JSC::propertyNameEnumerator): 26 * runtime/JSProxy.cpp: 27 (JSC::JSProxy::getEnumerableLength): Deleted. 28 * runtime/JSProxy.h: 29 1 30 2021-03-02 BJ Burg <bburg@apple.com> 2 31 -
trunk/Source/JavaScriptCore/runtime/ClassInfo.h
r273138 r273766 81 81 GetOwnPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnPropertyNames); 82 82 GetOwnPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnSpecialPropertyNames); 83 84 using GetEnumerableLengthFunctionPtr = uint32_t (*)(JSGlobalObject*, JSObject*);85 GetEnumerableLengthFunctionPtr METHOD_TABLE_ENTRY(getEnumerableLength);86 83 87 84 using ClassNameFunctionPtr = String (*)(const JSObject*, VM&); … … 173 170 &ClassName::getOwnPropertyNames, \ 174 171 &ClassName::getOwnSpecialPropertyNames, \ 175 &ClassName::getEnumerableLength, \176 172 &ClassName::className, \ 177 173 &ClassName::toStringName, \ -
trunk/Source/JavaScriptCore/runtime/JSCast.h
r263134 r273766 80 80 macro(JSArrayBufferView, FirstTypedArrayType, LastTypedArrayType) \ 81 81 macro(JSPromise, JSType::JSPromiseType, JSType::JSPromiseType) \ 82 macro(JSProxy, JSType::PureForwardingProxyType, JSType::ImpureProxyType) \ 82 83 macro(JSSet, JSType::JSSetType, JSType::JSSetType) \ 83 84 macro(JSMap, JSType::JSMapType, JSType::JSMapType) \ -
trunk/Source/JavaScriptCore/runtime/JSCell.cpp
r271269 r273766 246 246 } 247 247 248 uint32_t JSCell::getEnumerableLength(JSGlobalObject*, JSObject*)249 {250 RELEASE_ASSERT_NOT_REACHED();251 return 0;252 }253 254 248 bool JSCell::preventExtensions(JSObject*, JSGlobalObject*) 255 249 { -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r273138 r273766 249 249 static NO_RETURN_DUE_TO_CRASH void getOwnSpecialPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode); 250 250 251 static uint32_t getEnumerableLength(JSGlobalObject*, JSObject*);252 251 static NO_RETURN_DUE_TO_CRASH bool preventExtensions(JSObject*, JSGlobalObject*); 253 252 static NO_RETURN_DUE_TO_CRASH bool isExtensible(JSObject*, JSGlobalObject*); -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r273138 r273766 3755 3755 } 3756 3756 3757 uint32_t JSObject::getEnumerableLength(JSGlobalObject* globalObject , JSObject* object)3757 uint32_t JSObject::getEnumerableLength(JSGlobalObject* globalObject) 3758 3758 { 3759 3759 VM& vm = globalObject->vm(); 3760 Structure* structure = object->structure(vm); 3761 if (structure->holesMustForwardToPrototype(vm, object)) 3762 return 0; 3760 JSObject* object = this; 3761 3763 3762 switch (object->indexingType()) { 3764 3763 case ALL_BLANK_INDEXING_TYPES: 3765 3764 case ALL_UNDECIDED_INDEXING_TYPES: 3765 // Regardless of holesMustForwardToPrototype condition, it returns zero. 3766 3766 return 0; 3767 3767 … … 3769 3769 case ALL_CONTIGUOUS_INDEXING_TYPES: { 3770 3770 Butterfly* butterfly = object->butterfly(); 3771 unsigned usedLength = butterfly->publicLength(); 3772 for (unsigned i = 0; i < usedLength; ++i) { 3771 unsigned enumerableLength = butterfly->publicLength(); 3772 if (!enumerableLength) 3773 return 0; 3774 if (object->structure(vm)->holesMustForwardToPrototype(vm, object)) 3775 return 0; 3776 for (unsigned i = 0; i < enumerableLength; ++i) { 3773 3777 if (!butterfly->contiguous().at(object, i)) 3774 3778 return 0; 3775 3779 } 3776 return usedLength;3780 return enumerableLength; 3777 3781 } 3778 3782 3779 3783 case ALL_DOUBLE_INDEXING_TYPES: { 3780 3784 Butterfly* butterfly = object->butterfly(); 3781 unsigned usedLength = butterfly->publicLength(); 3782 for (unsigned i = 0; i < usedLength; ++i) { 3785 unsigned enumerableLength = butterfly->publicLength(); 3786 if (!enumerableLength) 3787 return 0; 3788 if (object->structure(vm)->holesMustForwardToPrototype(vm, object)) 3789 return 0; 3790 for (unsigned i = 0; i < enumerableLength; ++i) { 3783 3791 double value = butterfly->contiguousDouble().at(object, i); 3784 3792 if (value != value) 3785 3793 return 0; 3786 3794 } 3787 return usedLength;3795 return enumerableLength; 3788 3796 } 3789 3797 … … 3793 3801 return 0; 3794 3802 3795 unsigned usedVectorLength = std::min(storage->length(), storage->vectorLength()); 3796 for (unsigned i = 0; i < usedVectorLength; ++i) { 3803 unsigned enumerableLength = std::min(storage->length(), storage->vectorLength()); 3804 if (!enumerableLength) 3805 return 0; 3806 if (object->structure(vm)->holesMustForwardToPrototype(vm, object)) 3807 return 0; 3808 for (unsigned i = 0; i < enumerableLength; ++i) { 3797 3809 if (!storage->m_vector[i]) 3798 3810 return 0; 3799 3811 } 3800 return usedVectorLength;3812 return enumerableLength; 3801 3813 } 3802 3814 -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r273138 r273766 686 686 void getNonReifiedStaticPropertyNames(VM&, PropertyNameArray&, DontEnumPropertiesMode); 687 687 688 JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(JSGlobalObject*, JSObject*);688 JS_EXPORT_PRIVATE uint32_t getEnumerableLength(JSGlobalObject*); 689 689 690 690 JS_EXPORT_PRIVATE JSValue toPrimitive(JSGlobalObject*, PreferredPrimitiveType = NoPreference) const; -
trunk/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h
r273138 r273766 109 109 auto scope = DECLARE_THROW_SCOPE(vm); 110 110 111 uint32_t indexedLength = base-> methodTable(vm)->getEnumerableLength(globalObject, base);111 uint32_t indexedLength = base->getEnumerableLength(globalObject); 112 112 113 113 JSPropertyNameEnumerator* enumerator = nullptr; -
trunk/Source/JavaScriptCore/runtime/JSProxy.cpp
r273138 r273766 119 119 } 120 120 121 uint32_t JSProxy::getEnumerableLength(JSGlobalObject* globalObject, JSObject* object)122 {123 JSProxy* thisObject = jsCast<JSProxy*>(object);124 return thisObject->target()->methodTable(globalObject->vm())->getEnumerableLength(globalObject, thisObject->target());125 }126 127 121 void JSProxy::getOwnPropertyNames(JSObject* object, JSGlobalObject* globalObject, PropertyNameArray& propertyNames, DontEnumPropertiesMode mode) 128 122 { -
trunk/Source/JavaScriptCore/runtime/JSProxy.h
r273138 r273766 97 97 JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, JSGlobalObject*, unsigned); 98 98 JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode); 99 JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(JSGlobalObject*, JSObject*);100 99 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 101 100 JS_EXPORT_PRIVATE static bool setPrototype(JSObject*, JSGlobalObject*, JSValue, bool shouldThrowIfCantSet);
Note: See TracChangeset
for help on using the changeset viewer.