RESOLVED FIXED 262941
AX: -[WebAccessibilityObjectWrapper accessibilityIndexOfChild:] unnecessarily allocates an NSArray
https://bugs.webkit.org/show_bug.cgi?id=262941
Summary AX: -[WebAccessibilityObjectWrapper accessibilityIndexOfChild:] unnecessarily...
Tyler Wilcock
Reported 2023-10-09 21:45:03 PDT
This shows up on samples for some sites.
Attachments
Patch (4.17 KB, patch)
2023-10-09 21:53 PDT, Tyler Wilcock
no flags
Patch (4.15 KB, patch)
2023-10-10 10:30 PDT, Tyler Wilcock
no flags
Patch (4.18 KB, patch)
2023-10-10 13:14 PDT, Tyler Wilcock
no flags
Radar WebKit Bug Importer
Comment 1 2023-10-09 21:45:15 PDT
Tyler Wilcock
Comment 2 2023-10-09 21:53:31 PDT
Andres Gonzalez
Comment 3 2023-10-10 06:21:45 PDT
(In reply to Tyler Wilcock from comment #2) > Created attachment 468142 [details] > Patch diff --git a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm index f39430c64827..48916783a1f4 100644 --- a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm +++ b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm @@ -3596,7 +3596,7 @@ - (BOOL)accessibilityShouldUseUniqueId } // API that AppKit uses for faster access -- (NSUInteger)accessibilityIndexOfChild:(id)child +- (NSUInteger)accessibilityIndexOfChild:(id)targetChild { RefPtr<AXCoreObject> backingObject = self.updateObjectBackingStore; if (!backingObject) @@ -3605,29 +3605,27 @@ - (NSUInteger)accessibilityIndexOfChild:(id)child // Tree objects return their rows as their children. We can use the original method // here, because we won't gain any speed up. if (backingObject->isTree()) - return [super accessibilityIndexOfChild:child]; + return [super accessibilityIndexOfChild:targetChild]; - NSArray *children = self.childrenVectorArray; - if (!children.count) { + const auto& children = backingObject->children(); + if (!children.size()) { if (auto *renderWidgetChildren = [self renderWidgetChildren]) - return [renderWidgetChildren indexOfObject:child]; + return [renderWidgetChildren indexOfObject:targetChild]; #if ENABLE(MODEL_ELEMENT) if (backingObject->isModel()) - return backingObject->modelElementChildren().find(child); + return backingObject->modelElementChildren().find(targetChild); #endif } - NSUInteger count = [children count]; - for (NSUInteger i = 0; i < count; ++i) { - WebAccessibilityObjectWrapper *wrapper = children[i]; - auto* object = wrapper.axBackingObject; - if (!object) + size_t childCount = children.size(); + for (size_t i = 0; i < childCount; i++) { + RefPtr child = children[i]; AG: you can use children[i] without this temp and the additional ref count. Also it wouldn't be needed to name the param targetChild and then keep the original child. + if (!child) continue; - - if (wrapper == child || (object->isAttachment() && [wrapper attachmentView] == child)) + WebAccessibilityObjectWrapper *childWrapper = child->wrapper(); + if (childWrapper == targetChild || (child->isAttachment() && [childWrapper attachmentView] == targetChild)) return i; } - return NSNotFound; }
Tyler Wilcock
Comment 4 2023-10-10 10:30:25 PDT
Tyler Wilcock
Comment 5 2023-10-10 10:34:47 PDT
> - NSUInteger count = [children count]; > - for (NSUInteger i = 0; i < count; ++i) { > - WebAccessibilityObjectWrapper *wrapper = children[i]; > - auto* object = wrapper.axBackingObject; > - if (!object) > + size_t childCount = children.size(); > + for (size_t i = 0; i < childCount; i++) { > + RefPtr child = children[i]; > > AG: you can use children[i] without this temp and the additional ref count. > Also it wouldn't be needed to name the param targetChild and then keep the > original child. Removed the unnecessary RefPtr as you mentioned. I decided to keep the targetChild rename because I think it makes reading the code easier (otherwise we'd be comparing, e.g., childWrapper == child which doesn't read well in my opinion).
chris fleizach
Comment 6 2023-10-10 11:30:58 PDT
Comment on attachment 468152 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=468152&action=review > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:3624 > + WebAccessibilityObjectWrapper *childWrapper = children[i]->wrapper(); won't this incur a function call into Vector::indexedObject (whatever) the method name is each time? is that faster than making a local variable? feel like we should know the answer to that before deciding which is better
chris fleizach
Comment 7 2023-10-10 11:31:05 PDT
View in context: https://bugs.webkit.org/attachment.cgi?id=468152&action=review > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:3624 > + WebAccessibilityObjectWrapper *childWrapper = children[i]->wrapper(); won't this incur a function call into Vector::indexedObject (whatever) the method name is each time? is that faster than making a local variable? feel like we should know the answer to that before deciding which is better
Andres Gonzalez
Comment 8 2023-10-10 11:38:11 PDT
(In reply to chris fleizach from comment #7) > View in context: > https://bugs.webkit.org/attachment.cgi?id=468152&action=review > > > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:3624 > > + WebAccessibilityObjectWrapper *childWrapper = children[i]->wrapper(); > > won't this incur a function call into Vector::indexedObject (whatever) the > method name is each time? is that faster than making a local variable? > feel like we should know the answer to that before deciding which is better Vector::operator[] is an inline, random access method, so I think this is better than creating a new RefPtr.
Andres Gonzalez
Comment 9 2023-10-10 11:59:03 PDT
(In reply to Andres Gonzalez from comment #8) > (In reply to chris fleizach from comment #7) > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=468152&action=review > > > > > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:3624 > > > + WebAccessibilityObjectWrapper *childWrapper = children[i]->wrapper(); > > > > won't this incur a function call into Vector::indexedObject (whatever) the > > method name is each time? is that faster than making a local variable? > > feel like we should know the answer to that before deciding which is better > > Vector::operator[] is an inline, random access method, so I think this is > better than creating a new RefPtr. we can also do + auto& child = children[i]; that doesn't creat a new RefPtr, and you don't have to write children[i] evetywhere.
Tyler Wilcock
Comment 10 2023-10-10 13:14:14 PDT
Tyler Wilcock
Comment 11 2023-10-10 13:15:23 PDT
(In reply to Andres Gonzalez from comment #9) > (In reply to Andres Gonzalez from comment #8) > > (In reply to chris fleizach from comment #7) > > > View in context: > > > https://bugs.webkit.org/attachment.cgi?id=468152&action=review > > > > > > > Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:3624 > > > > + WebAccessibilityObjectWrapper *childWrapper = children[i]->wrapper(); > > > > > > won't this incur a function call into Vector::indexedObject (whatever) the > > > method name is each time? is that faster than making a local variable? > > > feel like we should know the answer to that before deciding which is better > > > > Vector::operator[] is an inline, random access method, so I think this is > > better than creating a new RefPtr. > > we can also do > > + auto& child = children[i]; > > that doesn't creat a new RefPtr, and you don't have to write children[i] > evetywhere. Fixed.
EWS
Comment 12 2023-10-10 21:04:50 PDT
Committed 269187@main (f36f30e2e548): <https://commits.webkit.org/269187@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 468157 [details].
Note You need to log in before you can comment on or make changes to this bug.