From b5fa01096cc3d498532bfb7563cfc9257758ee32 Mon Sep 17 00:00:00 2001 From: wuggy Date: Sun, 26 Apr 2026 11:18:52 -0700 Subject: [PATCH] Enhance optimization tracking by caching last accessed types and attempts, and improve string search functions with early exit for empty search strings. Co-authored-by: Copilot --- js/src/jit/OptimizationTracking.cpp | 32 ++++++++++++++++++++++++++--- js/src/jit/OptimizationTracking.h | 9 +++++++- js/src/jsstr.cpp | 32 ++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index 47df600945..dfc83f16d8 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -339,13 +339,25 @@ uint8_t UniqueTrackedOptimizations::indexOf(const TrackedOptimizations* optimizations) const { MOZ_ASSERT(sorted()); + + if (lastTypes_ == &optimizations->types_ && + lastAttempts_ == &optimizations->attempts_ && + lastIndex_ != UINT8_MAX) + { + return lastIndex_; + } + Key key; key.types = &optimizations->types_; key.attempts = &optimizations->attempts_; AttemptsMap::Ptr p = map_.lookup(key); MOZ_ASSERT(p); MOZ_ASSERT(p->value().index != UINT8_MAX); - return p->value().index; + uint8_t index = p->value().index; + lastTypes_ = key.types; + lastAttempts_ = key.attempts; + lastIndex_ = index; + return index; } // Assigns each unique tracked type an index; outputs a compact list. @@ -366,11 +378,15 @@ class jit::UniqueTrackedTypes TypesMap map_; Vector list_; + Maybe lastType_; + uint8_t lastTypeIndex_; public: explicit UniqueTrackedTypes(JSContext* cx) : map_(cx), - list_(cx) + list_(cx), + lastType_(Nothing()), + lastTypeIndex_(0) { } bool init() { return map_.init(); } @@ -383,9 +399,17 @@ class jit::UniqueTrackedTypes bool UniqueTrackedTypes::getIndexOf(JSContext* cx, TypeSet::Type ty, uint8_t* indexp) { + if (lastType_.isSome() && *lastType_ == ty) { + *indexp = lastTypeIndex_; + return true; + } + TypesMap::AddPtr p = map_.lookupForAdd(ty); if (p) { - *indexp = p->value(); + uint8_t index = p->value(); + lastType_ = Some(ty); + lastTypeIndex_ = index; + *indexp = index; return true; } @@ -399,6 +423,8 @@ UniqueTrackedTypes::getIndexOf(JSContext* cx, TypeSet::Type ty, uint8_t* indexp) return false; if (!list_.append(ty)) return false; + lastType_ = Some(ty); + lastTypeIndex_ = index; *indexp = index; return true; } diff --git a/js/src/jit/OptimizationTracking.h b/js/src/jit/OptimizationTracking.h index 1854fc1652..9dc347e2ad 100644 --- a/js/src/jit/OptimizationTracking.h +++ b/js/src/jit/OptimizationTracking.h @@ -167,10 +167,17 @@ class UniqueTrackedOptimizations // TempOptimizationAttemptsVectors sorted by frequency. SortedVector sorted_; + mutable const TempOptimizationTypeInfoVector* lastTypes_; + mutable const TempOptimizationAttemptsVector* lastAttempts_; + mutable uint8_t lastIndex_; + public: explicit UniqueTrackedOptimizations(JSContext* cx) : map_(cx), - sorted_(cx) + sorted_(cx), + lastTypes_(nullptr), + lastAttempts_(nullptr), + lastIndex_(UINT8_MAX) { } MOZ_MUST_USE bool init() { return map_.init(); } diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index e2e6e55631..aa0a503f72 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2061,6 +2061,17 @@ js::str_includes(JSContext* cx, unsigned argc, Value* vp) // Step 12 uint32_t start = Min(Max(pos, 0U), textLen); + uint32_t searchLen = searchStr->length(); + if (searchLen == 0) { + args.rval().setBoolean(true); + return true; + } + + if (searchLen > textLen - start) { + args.rval().setBoolean(false); + return true; + } + // Steps 13 and 14 JSLinearString* text = str->ensureLinear(cx); if (!text) @@ -2113,6 +2124,17 @@ js::str_indexOf(JSContext* cx, unsigned argc, Value* vp) // Step 9 uint32_t start = Min(Max(pos, 0U), textLen); + uint32_t searchLen = searchStr->length(); + if (searchLen == 0) { + args.rval().setInt32(start); + return true; + } + + if (searchLen > textLen - start) { + args.rval().setInt32(-1); + return true; + } + // Steps 10 and 11 JSLinearString* text = str->ensureLinear(cx); if (!text) @@ -2174,6 +2196,11 @@ js::str_lastIndexOf(JSContext* cx, unsigned argc, Value* vp) // Step 8. size_t searchLen = searchStr->length(); + if (searchLen > len) { + args.rval().setInt32(-1); + return true; + } + // Steps 4-5, 7. int start = len - searchLen; // Start searching here if (args.hasDefined(1)) { @@ -2197,11 +2224,6 @@ js::str_lastIndexOf(JSContext* cx, unsigned argc, Value* vp) } } - if (searchLen > len) { - args.rval().setInt32(-1); - return true; - } - if (searchLen == 0) { args.rval().setInt32(start); return true;