Bug 1028866 part 5 - Make NewString deflate to Latin1 if Latin1 strings are enabled and add NewStringDontDeflate. r=luke

This commit is contained in:
Jan de Mooij 2014-06-25 10:12:17 +02:00
parent d3f9af8b68
commit f4a6dcee86
7 changed files with 91 additions and 45 deletions

View File

@ -480,6 +480,11 @@ js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavi
if (!JSString::validateLength(cx, length))
return nullptr;
if (EnableLatin1Strings) {
const Latin1Char *chars = reinterpret_cast<const Latin1Char*>(bytes);
return AtomizeAndCopyChars(cx, chars, length, ib);
}
static const unsigned ATOMIZE_BUF_MAX = 32;
if (length < ATOMIZE_BUF_MAX) {
/*

View File

@ -308,7 +308,7 @@ CopyStringPure(JSContext *cx, JSString *str)
if (!str->asRope().copyTwoByteCharsZ(cx, copiedChars))
return nullptr;
return NewString<CanGC>(cx, copiedChars.forget(), len);
return NewStringDontDeflate<CanGC>(cx, copiedChars.forget(), len);
}
bool

View File

@ -719,7 +719,7 @@ ToLowerCase(JSContext *cx, JSLinearString *str)
newChars[length] = 0;
}
JSString *res = NewString<CanGC>(cx, newChars.get(), length);
JSString *res = NewStringDontDeflate<CanGC>(cx, newChars.get(), length);
if (!res)
return nullptr;
@ -4192,16 +4192,10 @@ js::str_fromCharCode_one_arg(JSContext *cx, HandleValue code, MutableHandleValue
return true;
}
jschar *chars = cx->pod_malloc<jschar>(2);
if (!chars)
jschar c = jschar(ucode);
JSString *str = NewStringCopyN<CanGC>(cx, &c, 1);
if (!str)
return false;
chars[0] = jschar(ucode);
chars[1] = 0;
JSString *str = NewString<CanGC>(cx, chars, 1);
if (!str) {
js_free(chars);
return false;
}
rval.setString(str);
return true;
@ -4268,35 +4262,6 @@ js_InitStringClass(JSContext *cx, HandleObject obj)
return proto;
}
template <AllowGC allowGC, typename CharT>
JSFlatString *
js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
{
if (length == 1) {
jschar c = chars[0];
if (StaticStrings::hasUnit(c)) {
// Free |chars| because we're taking possession of it, but it's no
// longer needed because we use the static string instead.
js_free(chars);
return cx->staticStrings().getUnit(c);
}
}
return JSFlatString::new_<allowGC>(cx, chars, length);
}
template JSFlatString *
js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
template JSFlatString *
js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
JSLinearString *
js::NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t length)
{
@ -4389,6 +4354,12 @@ NewStringDeflated(ThreadSafeContext *cx, const jschar *s, size_t n)
{
MOZ_ASSERT(EnableLatin1Strings);
if (n == 1) {
jschar c = s[0];
if (StaticStrings::hasUnit(c) && cx->staticStrings().initialized())
return cx->staticStrings().getUnit(c);
}
if (JSFatInlineString::latin1LengthFits(n))
return NewFatInlineStringDeflated<allowGC>(cx, Range<const jschar>(s, n));
@ -4402,7 +4373,7 @@ NewStringDeflated(ThreadSafeContext *cx, const jschar *s, size_t n)
}
news[n] = '\0';
JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
if (!str)
return nullptr;
@ -4417,6 +4388,64 @@ NewStringDeflated(ThreadSafeContext *cx, const Latin1Char *s, size_t n)
MOZ_CRASH("Shouldn't be called for Latin1 chars");
}
template <AllowGC allowGC, typename CharT>
JSFlatString *
js::NewStringDontDeflate(ThreadSafeContext *cx, CharT *chars, size_t length)
{
if (length == 1) {
jschar c = chars[0];
if (StaticStrings::hasUnit(c)) {
// Free |chars| because we're taking possession of it, but it's no
// longer needed because we use the static string instead.
js_free(chars);
return cx->staticStrings().getUnit(c);
}
}
return JSFlatString::new_<allowGC>(cx, chars, length);
}
template JSFlatString *
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
template JSFlatString *
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
template <AllowGC allowGC, typename CharT>
JSFlatString *
js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
{
if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(chars, length)) {
JSFlatString *s = NewStringDeflated<allowGC>(cx, chars, length);
if (!s)
return nullptr;
// Free |chars| because we're taking possession of it but not using it.
js_free(chars);
return s;
}
return NewStringDontDeflate<allowGC>(cx, chars, length);
}
template JSFlatString *
js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
template JSFlatString *
js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
template JSFlatString *
js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
namespace js {
template <AllowGC allowGC, typename CharT>
@ -4434,7 +4463,7 @@ NewStringCopyNDontDeflate(ThreadSafeContext *cx, const CharT *s, size_t n)
PodCopy(news.get(), s, n);
news[n] = 0;
JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
if (!str)
return nullptr;
@ -4452,7 +4481,7 @@ NewStringCopyNDontDeflate(ThreadSafeContext *cx, const CharT *s, size_t n)
CopyCharsMaybeInflate(news.get(), s, n);
news[n] = 0;
JSFlatString *str = NewString<allowGC>(cx, news.get(), n);
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
if (!str)
return nullptr;

View File

@ -112,6 +112,11 @@ template <js::AllowGC allowGC, typename CharT>
extern JSFlatString *
NewString(js::ThreadSafeContext *cx, CharT *chars, size_t length);
/* Like NewString, but doesn't try to deflate to Latin1. */
template <js::AllowGC allowGC, typename CharT>
extern JSFlatString *
NewStringDontDeflate(js::ThreadSafeContext *cx, CharT *chars, size_t length);
extern JSLinearString *
NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);

View File

@ -718,6 +718,8 @@ StaticStrings::init(JSContext *cx)
AutoLockForExclusiveAccess lock(cx);
AutoCompartment ac(cx, cx->runtime()->atomsCompartment());
MOZ_ASSERT(!initialized_);
for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) {
jschar buffer[] = { jschar(i), '\0' };
JSFlatString *s = NewStringCopyN<NoGC>(cx, buffer, 1);
@ -753,6 +755,7 @@ StaticStrings::init(JSContext *cx)
}
}
initialized_ = true;
return true;
}

View File

@ -1124,6 +1124,8 @@ class StaticStrings
JSAtom *length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS];
bool initialized_;
public:
/* We keep these public for the JITs. */
static const size_t UNIT_STATIC_LIMIT = 256U;
@ -1135,7 +1137,9 @@ class StaticStrings
StaticStrings() {
mozilla::PodZero(this);
}
bool initialized() const {
return initialized_;
}
bool init(JSContext *cx);
void trace(JSTracer *trc);

View File

@ -77,7 +77,7 @@ FinishStringFlat(ExclusiveContext *cx, StringBuffer &sb, Buffer &cb)
if (!buf)
return nullptr;
JSFlatString *str = NewString<CanGC>(cx, buf.get(), len);
JSFlatString *str = NewStringDontDeflate<CanGC>(cx, buf.get(), len);
if (!str)
return nullptr;