Bug 1549578: Cache most recently used UDateTimePatternGenerator in SharedIntlData. r=jwalden

Differential Revision: https://phabricator.services.mozilla.com/D30114

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-06-14 03:34:33 +00:00
parent b23d78eb85
commit a39b233aa1
3 changed files with 63 additions and 6 deletions

View File

@ -548,14 +548,12 @@ bool js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp) {
mozilla::Range<const char16_t> skelChars = skeleton.twoByteRange();
UErrorCode status = U_ZERO_ERROR;
SharedIntlData& sharedIntlData = cx->runtime()->sharedIntlData.ref();
UDateTimePatternGenerator* gen =
udatpg_open(IcuLocale(locale.get()), &status);
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
sharedIntlData.getDateTimePatternGenerator(cx, locale.get());
if (!gen) {
return false;
}
ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen);
JSString* str = CallICU(
cx, [gen, &skelChars](UChar* chars, uint32_t size, UErrorCode* status) {

View File

@ -13,6 +13,7 @@
#include "mozilla/TextUtils.h"
#include <stdint.h>
#include <utility>
#include "builtin/intl/CommonFunctions.h"
#include "builtin/intl/ICUStubs.h"
@ -395,6 +396,39 @@ bool js::intl::SharedIntlData::isUpperCaseFirst(JSContext* cx,
return true;
}
void js::intl::DateTimePatternGeneratorDeleter::operator()(
UDateTimePatternGenerator* ptr) {
udatpg_close(ptr);
}
UDateTimePatternGenerator*
js::intl::SharedIntlData::getDateTimePatternGenerator(JSContext* cx,
const char* locale) {
// Return the cached instance if the requested locale matches the locale
// of the cached generator.
if (dateTimePatternGeneratorLocale &&
StringsAreEqual(dateTimePatternGeneratorLocale.get(), locale)) {
return dateTimePatternGenerator.get();
}
UErrorCode status = U_ZERO_ERROR;
UniqueUDateTimePatternGenerator gen(udatpg_open(IcuLocale(locale), &status));
if (U_FAILURE(status)) {
intl::ReportInternalError(cx);
return nullptr;
}
JS::UniqueChars localeCopy = js::DuplicateString(cx, locale);
if (!localeCopy) {
return nullptr;
}
dateTimePatternGenerator = std::move(gen);
dateTimePatternGeneratorLocale = std::move(localeCopy);
return dateTimePatternGenerator.get();
}
void js::intl::SharedIntlData::destroyInstance() {
availableTimeZones.clearAndCompact();
ianaZonesTreatedAsLinksByICU.clearAndCompact();
@ -418,5 +452,6 @@ size_t js::intl::SharedIntlData::sizeOfExcludingThis(
ianaZonesTreatedAsLinksByICU.shallowSizeOfExcludingThis(mallocSizeOf) +
ianaLinksCanonicalizedDifferentlyByICU.shallowSizeOfExcludingThis(
mallocSizeOf) +
upperCaseFirstLocales.shallowSizeOfExcludingThis(mallocSizeOf);
upperCaseFirstLocales.shallowSizeOfExcludingThis(mallocSizeOf) +
mallocSizeOf(dateTimePatternGeneratorLocale.get());
}

View File

@ -8,6 +8,7 @@
#define builtin_intl_SharedIntlData_h
#include "mozilla/MemoryReporting.h"
#include "mozilla/UniquePtr.h"
#include <stddef.h>
@ -19,10 +20,17 @@
#include "js/Utility.h"
#include "vm/StringType.h"
using UDateTimePatternGenerator = void*;
namespace js {
namespace intl {
class DateTimePatternGeneratorDeleter {
public:
void operator()(UDateTimePatternGenerator* ptr);
};
/**
* Stores Intl data which can be shared across compartments (but not contexts).
*
@ -203,6 +211,22 @@ class SharedIntlData {
bool isUpperCaseFirst(JSContext* cx, JS::Handle<JSString*> locale,
bool* isUpperFirst);
private:
using UniqueUDateTimePatternGenerator =
mozilla::UniquePtr<UDateTimePatternGenerator,
DateTimePatternGeneratorDeleter>;
UniqueUDateTimePatternGenerator dateTimePatternGenerator;
JS::UniqueChars dateTimePatternGeneratorLocale;
public:
/**
* Wrapper around |udatpg_open| to return a possibly cached generator
* instance. The returned pointer must not be closed via |udatpg_close|.
*/
UDateTimePatternGenerator* getDateTimePatternGenerator(JSContext* cx,
const char* locale);
public:
void destroyInstance();