Bug 153266 - Reduce use of equalIgnoringCase to just ignore ASCII case
Summary: Reduce use of equalIgnoringCase to just ignore ASCII case
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Darin Adler
URL:
Keywords:
Depends on: 153357
Blocks: 153294
  Show dependency treegraph
 
Reported: 2016-01-19 19:35 PST by Darin Adler
Modified: 2016-01-25 13:56 PST (History)
10 users (show)

See Also:


Attachments
Patch (293.61 KB, patch)
2016-01-19 20:20 PST, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (296.02 KB, patch)
2016-01-19 20:36 PST, Darin Adler
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews100 for mac-yosemite (760.27 KB, application/zip)
2016-01-19 21:46 PST, Build Bot
no flags Details
Archive of layout-test-results from ews117 for mac-yosemite (794.76 KB, application/zip)
2016-01-19 21:46 PST, Build Bot
no flags Details
Archive of layout-test-results from ews106 for mac-yosemite-wk2 (955.84 KB, application/zip)
2016-01-19 21:50 PST, Build Bot
no flags Details
Patch (296.08 KB, patch)
2016-01-19 22:35 PST, Darin Adler
rniwa: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Adler 2016-01-19 19:35:42 PST
Reduce use of equalIgnoringCase to just ignore ASCII case
Comment 1 Darin Adler 2016-01-19 20:20:25 PST
Created attachment 269329 [details]
Patch
Comment 2 Darin Adler 2016-01-19 20:23:12 PST
This is one step on the path to reduce the use of general Unicode functions where we want functions that only treat ASCII specially. Main categories:

1) case-ignoring equality, contains, find, startsWith, endsWith, etc.
2) functions to make lowercase and uppercase
3) functions that strip or detect whitespace

Starting with equalIgnoringCase for this first patch, and specifically the subset of calls to it that compare with string literals.
Comment 3 Darin Adler 2016-01-19 20:24:16 PST
This first patch should not change any behavior. Later patches will change the semantics, but this one is really only about not having unnecessary calls to the general purpose function that handles non-ASCII characters.
Comment 4 Darin Adler 2016-01-19 20:36:11 PST
Created attachment 269330 [details]
Patch
Comment 5 Build Bot 2016-01-19 21:46:09 PST
Comment on attachment 269330 [details]
Patch

Attachment 269330 [details] did not pass mac-ews (mac):
Output: http://webkit-queues.webkit.org/results/715397

New failing tests:
fast/doctypes/doctype-parsing.html
plugins/netscape-plugin-map-data-to-src.html
http/tests/security/contentSecurityPolicy/object-src-none-allowed.html
Comment 6 Build Bot 2016-01-19 21:46:14 PST
Created attachment 269335 [details]
Archive of layout-test-results from ews100 for mac-yosemite

The attached test failures were seen while running run-webkit-tests on the mac-ews.
Bot: ews100  Port: mac-yosemite  Platform: Mac OS X 10.10.5
Comment 7 Build Bot 2016-01-19 21:46:18 PST
Comment on attachment 269330 [details]
Patch

Attachment 269330 [details] did not pass mac-debug-ews (mac):
Output: http://webkit-queues.webkit.org/results/715388

New failing tests:
fast/doctypes/doctype-parsing.html
plugins/netscape-plugin-map-data-to-src.html
http/tests/security/contentSecurityPolicy/object-src-none-allowed.html
Comment 8 Build Bot 2016-01-19 21:46:23 PST
Created attachment 269336 [details]
Archive of layout-test-results from ews117 for mac-yosemite

The attached test failures were seen while running run-webkit-tests on the mac-debug-ews.
Bot: ews117  Port: mac-yosemite  Platform: Mac OS X 10.10.5
Comment 9 Build Bot 2016-01-19 21:50:54 PST
Comment on attachment 269330 [details]
Patch

Attachment 269330 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.webkit.org/results/715402

New failing tests:
fast/doctypes/doctype-parsing.html
plugins/netscape-plugin-map-data-to-src.html
http/tests/security/contentSecurityPolicy/object-src-none-allowed.html
Comment 10 Build Bot 2016-01-19 21:50:59 PST
Created attachment 269338 [details]
Archive of layout-test-results from ews106 for mac-yosemite-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews106  Port: mac-yosemite-wk2  Platform: Mac OS X 10.10.5
Comment 11 Darin Adler 2016-01-19 22:35:02 PST
Comment on attachment 269330 [details]
Patch

Got a new patch coming that fixes the test failures (seen on the Mac bots). Not sure how to fix the compilation feature on Windows.
Comment 12 Darin Adler 2016-01-19 22:35:17 PST
Created attachment 269341 [details]
Patch
Comment 13 Darin Adler 2016-01-19 22:36:06 PST
Brent, I’d appreciate your help figuring out why compilation of Assertions.cpp is failing on Windows.
Comment 14 Darin Adler 2016-01-19 23:30:18 PST
Comment on attachment 269341 [details]
Patch

Whatever caused the Windows build failure didn’t happen this time! Hooray! All tests passed and ready to review and land.
Comment 15 Ryosuke Niwa 2016-01-20 11:02:50 PST
Comment on attachment 269341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=269341&action=review

> Source/WTF/wtf/text/StringCommon.h:582
> +    // Don't actually use the length; we are choosing code size over speed.
> +    const char* pointer = lowercaseLetters;
> +    return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer);

Can't we just copy over the last two lines of equalLettersIgnoringASCIICaseCommonWithoutLength and make this function non-inline?
We could then make equalLettersIgnoringASCIICaseCommonWithoutLength call this function instead.

> Source/WebCore/accessibility/AXObjectCache.cpp:171
> -        if (!equalIgnoringCase(element->fastGetAttribute(aria_modalAttr), "true"))
> +        if (!equalLettersIgnoringASCIICase(element->fastGetAttribute(aria_modalAttr), "true"))

Comparison against "true" and "false" appear so often!
We should probably define a function somewhere once and for all.

> Source/WebCore/accessibility/AccessibilityNodeObject.cpp:1856
>      HTMLInputElement& input = downcast<HTMLInputElement>(*node());
>      const AtomicString& type = input.getAttribute(typeAttr);
> -    if (!equalIgnoringCase(type, "color"))
> +    if (!equalLettersIgnoringASCIICase(type, "color"))

Why don't we replace this with isColorControl as you've done above?

> Source/WebCore/html/HTMLElement.cpp:643
> -    if (equalIgnoringCase(where, "beforeBegin")) {
> +    if (equalLettersIgnoringASCIICase(where, "beforebegin")) {

Now that I'm seeing more of these changes, I've started to think equalLettersIgnoringASCIILowercase might be a better name for this function.

> Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:93
> +    // FIXME: Why is this checking case since the check in supportsKeySystemAndMimeType is ignoring case?
>      if (mimeType == "keyrelease")

Looks like this is a bug??
Comment 16 Darin Adler 2016-01-20 16:08:04 PST
Comment on attachment 269341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=269341&action=review

>> Source/WTF/wtf/text/StringCommon.h:582
>> +    return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer);
> 
> Can't we just copy over the last two lines of equalLettersIgnoringASCIICaseCommonWithoutLength and make this function non-inline?
> We could then make equalLettersIgnoringASCIICaseCommonWithoutLength call this function instead.

This patch is choosing code size over speed. We don’t want to compile in code to pass the length at each call site of all the equalLettersIgnoringASCIICase functions, and that would happen if this function wasn’t an inline that ignores the length.

Also, there’s no way to turn a pointer into an array with a length, so no, that other function could *not* call this function.

> Source/WTF/wtf/text/StringImpl.h:972
> +template<unsigned charactersCount> bool equalLettersIgnoringASCIICase(const StringImpl&, const char (&lowercaseLetters)[charactersCount]);
> +template<unsigned charactersCount> bool equalLettersIgnoringASCIICase(const StringImpl*, const char (&lowercaseLetters)[charactersCount]);

Oops, I meant to call it "length" here, not "charactersCount".

>> Source/WebCore/accessibility/AXObjectCache.cpp:171
>> +        if (!equalLettersIgnoringASCIICase(element->fastGetAttribute(aria_modalAttr), "true"))
> 
> Comparison against "true" and "false" appear so often!
> We should probably define a function somewhere once and for all.

That’s a neat idea. I’ll put that on the list to do later.

>> Source/WebCore/accessibility/AccessibilityNodeObject.cpp:1856
>> +    if (!equalLettersIgnoringASCIICase(type, "color"))
> 
> Why don't we replace this with isColorControl as you've done above?

Good idea. I will do that.

> Source/WebCore/css/CSSParserValues.h:142
> +template<unsigned length> bool equalLettersIgnoringASCIICase(const CSSParserValue&, const char (&lowercaseLetters)[length]);

Oops, meant to remove this from the header.

>> Source/WebCore/html/HTMLElement.cpp:643
>> +    if (equalLettersIgnoringASCIICase(where, "beforebegin")) {
> 
> Now that I'm seeing more of these changes, I've started to think equalLettersIgnoringASCIILowercase might be a better name for this function.

Not sure I agree, but I am happy to consider alternate better names, including this one. We can do that as a global replace after we land this.

>> Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:93
>>      if (mimeType == "keyrelease")
> 
> Looks like this is a bug??

Yes, that’s what the FIXME is intended to say. I’d like to find an expert on media who can help me write a test case and then fix it.
Comment 17 Ryosuke Niwa 2016-01-20 16:18:57 PST
Comment on attachment 269341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=269341&action=review

>>> Source/WTF/wtf/text/StringCommon.h:582
>>> +    return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer);
>> 
>> Can't we just copy over the last two lines of equalLettersIgnoringASCIICaseCommonWithoutLength and make this function non-inline?
>> We could then make equalLettersIgnoringASCIICaseCommonWithoutLength call this function instead.
> 
> This patch is choosing code size over speed. We don’t want to compile in code to pass the length at each call site of all the equalLettersIgnoringASCIICase functions, and that would happen if this function wasn’t an inline that ignores the length.
> 
> Also, there’s no way to turn a pointer into an array with a length, so no, that other function could *not* call this function.

Well, the first thing equalLettersIgnoringASCIICaseCommonWithoutLength does is strlen(lowercaseLetters) and comparing it to string.length().
I'm also not sure if passing an extra argument via register will be that expensive in the code size.
Not passing in the length and doing an extra strlen call to figure out length doesn't seem like
a good code-size/runtime trade off to me especially when the length is a compile-time constant.
Comment 18 Darin Adler 2016-01-20 16:39:00 PST
Comment on attachment 269341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=269341&action=review

>>>> Source/WTF/wtf/text/StringCommon.h:582
>>>> +    return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer);
>>> 
>>> Can't we just copy over the last two lines of equalLettersIgnoringASCIICaseCommonWithoutLength and make this function non-inline?
>>> We could then make equalLettersIgnoringASCIICaseCommonWithoutLength call this function instead.
>> 
>> This patch is choosing code size over speed. We don’t want to compile in code to pass the length at each call site of all the equalLettersIgnoringASCIICase functions, and that would happen if this function wasn’t an inline that ignores the length.
>> 
>> Also, there’s no way to turn a pointer into an array with a length, so no, that other function could *not* call this function.
> 
> Well, the first thing equalLettersIgnoringASCIICaseCommonWithoutLength does is strlen(lowercaseLetters) and comparing it to string.length().
> I'm also not sure if passing an extra argument via register will be that expensive in the code size.
> Not passing in the length and doing an extra strlen call to figure out length doesn't seem like
> a good code-size/runtime trade off to me especially when the length is a compile-time constant.

This is the same tradeoff that Ben made when he introduced ASCIILiteral, not an original idea of my own. I’m happy to change this if someone wants to help me measure the difference. It’s really easy to change the implementation to use the length if we want to do that.
Comment 19 Ryosuke Niwa 2016-01-20 16:52:43 PST
(In reply to comment #18)
> Comment on attachment 269341 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=269341&action=review
> 
> >>>> Source/WTF/wtf/text/StringCommon.h:582
> >>>> +    return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer);
> >>> 
> >>> Can't we just copy over the last two lines of equalLettersIgnoringASCIICaseCommonWithoutLength and make this function non-inline?
> >>> We could then make equalLettersIgnoringASCIICaseCommonWithoutLength call this function instead.
> >> 
> >> This patch is choosing code size over speed. We don’t want to compile in code to pass the length at each call site of all the equalLettersIgnoringASCIICase functions, and that would happen if this function wasn’t an inline that ignores the length.
> >> 
> >> Also, there’s no way to turn a pointer into an array with a length, so no, that other function could *not* call this function.
> > 
> > Well, the first thing equalLettersIgnoringASCIICaseCommonWithoutLength does is strlen(lowercaseLetters) and comparing it to string.length().
> > I'm also not sure if passing an extra argument via register will be that expensive in the code size.
> > Not passing in the length and doing an extra strlen call to figure out length doesn't seem like
> > a good code-size/runtime trade off to me especially when the length is a compile-time constant.
> 
> This is the same tradeoff that Ben made when he introduced ASCIILiteral, not
> an original idea of my own. I’m happy to change this if someone wants to
> help me measure the difference. It’s really easy to change the
> implementation to use the length if we want to do that.

I see. Okay, I guess we can change that later if we find it be a runtime cost.
Comment 20 Ryosuke Niwa 2016-01-20 17:00:36 PST
I got a help from Jer to create a test case for case-sensitive comparison of MIME type against "keyrelease" and attached on the bug 153294.
Comment 21 Darin Adler 2016-01-22 09:17:16 PST
Committed r195452: <http://trac.webkit.org/changeset/195452>
Comment 22 Ryan Haddad 2016-01-22 09:49:04 PST
This change appears to have broken the iOS build:

<https://build.webkit.org/builders/Apple%20iOS%209%20Simulator%20Release%20%28Build%29/builds/2737>
<https://build.webkit.org/builders/Apple%20iOS%209%20Release%20%28Build%29/builds/2106>

/Volumes/Data/slave/ios-9-release/build/Source/WebCore/accessibility/AccessibilityNodeObject.cpp:1855:16: error: no member named 'isColorControl' in 'WebCore::HTMLInputElement'
    if (!input.isColorControl())
         ~~~~~ ^
1 error generated.
Comment 23 Chris Dumez 2016-01-22 10:06:55 PST
(In reply to comment #22)
> This change appears to have broken the iOS build:
> 
> <https://build.webkit.org/builders/
> Apple%20iOS%209%20Simulator%20Release%20%28Build%29/builds/2737>
> <https://build.webkit.org/builders/Apple%20iOS%209%20Release%20%28Build%29/
> builds/2106>
> 
> /Volumes/Data/slave/ios-9-release/build/Source/WebCore/accessibility/
> AccessibilityNodeObject.cpp:1855:16: error: no member named 'isColorControl'
> in 'WebCore::HTMLInputElement'
>     if (!input.isColorControl())
>          ~~~~~ ^
> 1 error generated.

iOS build fix landed in <https://trac.webkit.org/r195455>.
Comment 24 Chris Dumez 2016-01-22 10:26:05 PST
(In reply to comment #23)
> (In reply to comment #22)
> > This change appears to have broken the iOS build:
> > 
> > <https://build.webkit.org/builders/
> > Apple%20iOS%209%20Simulator%20Release%20%28Build%29/builds/2737>
> > <https://build.webkit.org/builders/Apple%20iOS%209%20Release%20%28Build%29/
> > builds/2106>
> > 
> > /Volumes/Data/slave/ios-9-release/build/Source/WebCore/accessibility/
> > AccessibilityNodeObject.cpp:1855:16: error: no member named 'isColorControl'
> > in 'WebCore::HTMLInputElement'
> >     if (!input.isColorControl())
> >          ~~~~~ ^
> > 1 error generated.
> 
> iOS build fix landed in <https://trac.webkit.org/r195455>.

And another build fix: <http://trac.webkit.org/changeset/195458>
for
WTF\wtf\Assertions.cpp(492): error C3861: 'equalLettersIgnoringASCIICase': identifier not found
on Windows.
Comment 25 Chris Dumez 2016-01-22 10:44:45 PST
(In reply to comment #24)
> (In reply to comment #23)
> > (In reply to comment #22)
> > > This change appears to have broken the iOS build:
> > > 
> > > <https://build.webkit.org/builders/
> > > Apple%20iOS%209%20Simulator%20Release%20%28Build%29/builds/2737>
> > > <https://build.webkit.org/builders/Apple%20iOS%209%20Release%20%28Build%29/
> > > builds/2106>
> > > 
> > > /Volumes/Data/slave/ios-9-release/build/Source/WebCore/accessibility/
> > > AccessibilityNodeObject.cpp:1855:16: error: no member named 'isColorControl'
> > > in 'WebCore::HTMLInputElement'
> > >     if (!input.isColorControl())
> > >          ~~~~~ ^
> > > 1 error generated.
> > 
> > iOS build fix landed in <https://trac.webkit.org/r195455>.
> 
> And another build fix: <http://trac.webkit.org/changeset/195458>
> for
> WTF\wtf\Assertions.cpp(492): error C3861: 'equalLettersIgnoringASCIICase':
> identifier not found
> on Windows.

Hmm, my Windows fix did not work. I am not sure yet what's wrong. WTFString.h is correctly included in Assertions.cpp.
Comment 26 Darin Adler 2016-01-24 17:18:45 PST
Why is this reopened? Was this actually rolled out?
Comment 27 Chris Dumez 2016-01-24 17:23:43 PST
(In reply to comment #26)
> Why is this reopened? Was this actually rolled out?

It was about to be rolled out for breaking iOS and Windows. However, we landed a build fix for iOS instead:
<https://trac.webkit.org/r195455>

and it seems Windows just needed a clean build.

Closing again.
Comment 28 Darin Adler 2016-01-24 18:02:10 PST
(In reply to comment #27)
> (In reply to comment #26)
> > Why is this reopened? Was this actually rolled out?
> 
> It was about to be rolled out for breaking iOS and Windows. However, we
> landed a build fix for iOS instead:
> <https://trac.webkit.org/r195455>

Thanks! I noticed that fix and meant to thank you for that.

> and it seems Windows just needed a clean build.

I saw that same Windows build failure on EWS. Then later another EWS build succeeded. I’m not really happy with the Windows build system having all these problems that require us forcing a clean build. Alex said he might know how to fix that. Seems really important to do it!

Thanks again for making this easier by fixing it rather than rolling it out.
Comment 29 Alex Christensen 2016-01-25 13:56:45 PST
(In reply to comment #28)
> (In reply to comment #27)
> I saw that same Windows build failure on EWS. Then later another EWS build
> succeeded. I’m not really happy with the Windows build system having all
> these problems that require us forcing a clean build. Alex said he might
> know how to fix that. Seems really important to do it!
https://bugs.webkit.org/show_bug.cgi?id=153434 should have fixed this.