Closed Bug 1467907 Opened 7 years ago Closed 7 years ago

Create a CacheIR IC for Compare(String,Int32)

Categories

(Core :: JavaScript Engine: JIT, enhancement, P1)

enhancement

Tracking

()

RESOLVED FIXED
mozilla64
Tracking Status
firefox62 --- wontfix
firefox63 --- wontfix
firefox64 --- fixed

People

(Reporter: mgaudet, Assigned: mgaudet)

References

Details

(Keywords: perf)

Attachments

(2 files, 2 obsolete files)

In Bug 1341261 I have been working on replacing the Shared IC with CacheIR. Using the CACHEIR_LOGS, it's become pretty obvious we have a coverage gap for comparing strings to integers.
(Just a thought that this should be reasonably simple for indexed strings, assuming hasIndexValue and getIndexValue do what they should)
We apparently have a dtoa cache. I wonder if an IC for string identity to specific integer would ever be useful. https://searchfox.org/mozilla-central/source/js/src/vm/Realm.h#410
Attachment #9002445 - Flags: review?(jdemooij)
Assignee: nobody → mgaudet
Status: NEW → ASSIGNED
Attachment #9002448 - Flags: review?(jdemooij)
Attachment #9002445 - Attachment is obsolete: true
Attachment #9002445 - Flags: review?(jdemooij)
Comment on attachment 9002448 [details] [diff] [review] Add an IC for String Int32 comparison Review of attachment 9002448 [details] [diff] [review]: ----------------------------------------------------------------- Makes sense, but some suggestions below. ::: js/src/jit/CacheIR.cpp @@ +5012,5 @@ > +CompareIRGenerator::tryAttachStringIndexed(ValOperandId lhsId, ValOperandId rhsId) > +{ > + if (!(lhsVal_.isString() && rhsVal_.isInt32()) && > + !(rhsVal_.isString() && lhsVal_.isInt32())) > + return false; Nit: add {}, with { on its own line. @@ +5019,5 @@ > + return false; > + > + JSString* str = lhsVal_.isString() ? lhsVal_.toString() : rhsVal_.toString(); > + // Flat strings don't have indexes > + if (!str->isFlat()) The comment doesn't match the code. @@ +5023,5 @@ > + if (!str->isFlat()) > + return false; > + > + // Don't try to attach if the string has no index value. > + if (!str->hasIndexValue()) GuardAndGetIndexFromString will call GetIndexFromString if the string has no index value, so should we call GetIndexFromString instead here? What's perf like when comparing a string-without-index to an int32 if we do that? I'm also a bit worried about the stub failing for negative integers for no good reason (-1 is pretty common). What do you think about adding guardAndGetInt32FromString? It could work mostly the same way, but it would call js::StringToNumber and fail if the double does not fit in an int32. Or we could use js::StringToNumber and make the stub work for all doubles, that might be even nicer. @@ +5029,5 @@ > + > + auto createGuards = [&](HandleValue v, ValOperandId vId) { > + if (v.isString()) { > + StringOperandId strId = writer.guardIsString(vId); > + return writer.guardAndGetIndexFromString(strId); Nit: remove extra space after return. @@ +5065,5 @@ > ValOperandId rhsId(writer.setInputOperandId(rhsIndex)); > > // For sloppy equality ops, there are cases this IC does not handle: > // - {Symbol} x {Null, Undefined, String, Bool, Number}. > + // - {String} x {Null, Undefined, Symbol, Bool, Number}. Unrelated, but is this true, we don't have an IC for |<anything> ==/!= {null,undefined,true,false}|? Maybe worth fixing too. @@ +5108,5 @@ > return true; > if (tryAttachNumber(lhsId, rhsId)) > return true; > > + if (tryAttachStringIndexed(lhsId,rhsId)) Nit: add a space after the ','
Attachment #9002448 - Flags: review?(jdemooij)
Attachment #9002448 - Attachment is obsolete: true
Attached file compare_bench.js
Benchmarking shows the patch to be ~2x faster on a concentrated microbenchmark for the cases where it applies. (x64, opt shell build on OS/X run with no arguments. Note, The inputs of this benchmark are absolutely worth questioning (2 indexed strings, 3-non indexed), I think this is overall a minor issue. Without: String_Number_GT1 1.404970947265625 String_Number_GTE1 1.399468994140625 String_Number_LT1 1.378340087890625 String_Number_LTE1 1.40908203125 String_Number_EQ1 1.719333984375 String_Number_NEQ1 1.7414580078125 String_Number_SEQ1 0.47639501953125 String_Number_SNEQ1 0.47108203125 With: String_Number_GT1 0.724429931640625 String_Number_GTE1 0.742053955078125 String_Number_LT1 0.7125439453125 String_Number_LTE1 0.715946044921875 String_Number_EQ1 0.825533935546875 String_Number_NEQ1 0.83451416015625 String_Number_SEQ1 0.47579296875 String_Number_SNEQ1 0.48748681640625 The lack of impact for SEQ and SNEQ are because those cases are being handled by a separate IC (the strictly different types IC).
Comment on attachment 9003888 [details] Bug 1467907 - Add an IC for String x Number comparison r=jandem Jan de Mooij [:jandem] has approved the revision.
Attachment #9003888 - Flags: review+
Pushed by mgaudet@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/a23a0c5054d9 Add an IC for String x Number comparison r=jandem
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla64
Shouldn't this bug have a `perf` keyword?
I mean, perhaps? I guess my hesitation from marking this as 'perf' mostly relates to us not having a specific use case in mind, outside of us trying to avoid performance cliffs. Is there a particular purpose you'd want this marked perf for?
Just to make it easier for anybody to find all performance improvements.
Keywords: perf
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: