From 77a08731671185f2fcfb1674a125856f86cfd82b Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 26 Oct 2010 16:20:21 -0700 Subject: [PATCH] Bug 605186 - js_NewStringFromCharBuffer should create short strings if it can (r=waldo) --- js/src/jsstr.cpp | 87 +++++++++++++++++++++++++---------------------- js/src/jsvector.h | 2 ++ 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 2281c5f3512..721bdb3bf4a 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -3418,6 +3418,47 @@ js_NewString(JSContext *cx, jschar *chars, size_t length) return str; } +static JS_ALWAYS_INLINE JSString * +NewShortString(JSContext *cx, const jschar *chars, size_t length) +{ + JS_ASSERT(JSShortString::fitsIntoShortString(length)); + JSShortString *str = js_NewGCShortString(cx); + if (!str) + return NULL; + jschar *storage = str->init(length); + js_short_strncpy(storage, chars, length); + storage[length] = 0; + return str->header(); +} + +static JSString * +NewShortString(JSContext *cx, const char *chars, size_t length) +{ + JS_ASSERT(JSShortString::fitsIntoShortString(length)); + JSShortString *str = js_NewGCShortString(cx); + if (!str) + return NULL; + jschar *storage = str->init(length); + + if (js_CStringsAreUTF8) { +#ifdef DEBUG + size_t oldLength = length; +#endif + if (!js_InflateStringToBuffer(cx, chars, length, storage, &length)) + return NULL; + JS_ASSERT(length <= oldLength); + storage[length] = 0; + str->resetLength(length); + } else { + size_t n = length; + jschar *p = storage; + while (n--) + *p++ = jschar(*chars++); + *p = 0; + } + return str->header(); +} + static const size_t sMinWasteSize = 16; JSString * @@ -3427,6 +3468,11 @@ js_NewStringFromCharBuffer(JSContext *cx, JSCharBuffer &cb) return ATOM_TO_STRING(cx->runtime->atomState.emptyAtom); size_t length = cb.length(); + + JS_STATIC_ASSERT(JSShortString::MAX_SHORT_STRING_LENGTH < JSCharBuffer::InlineLength); + if (JSShortString::fitsIntoShortString(length)) + return NewShortString(cx, cb.begin(), length); + if (!cb.append('\0')) return NULL; @@ -3520,47 +3566,6 @@ void printJSStringStats(JSRuntime *rt) } #endif -JSString * -NewShortString(JSContext *cx, const jschar *chars, size_t length) -{ - JS_ASSERT(JSShortString::fitsIntoShortString(length)); - JSShortString *str = js_NewGCShortString(cx); - if (!str) - return NULL; - jschar *storage = str->init(length); - js_short_strncpy(storage, chars, length); - storage[length] = 0; - return str->header(); -} - -JSString * -NewShortString(JSContext *cx, const char *chars, size_t length) -{ - JS_ASSERT(JSShortString::fitsIntoShortString(length)); - JSShortString *str = js_NewGCShortString(cx); - if (!str) - return NULL; - jschar *storage = str->init(length); - - if (js_CStringsAreUTF8) { -#ifdef DEBUG - size_t oldLength = length; -#endif - if (!js_InflateStringToBuffer(cx, chars, length, storage, &length)) - return NULL; - JS_ASSERT(length <= oldLength); - storage[length] = 0; - str->resetLength(length); - } else { - size_t n = length; - jschar *p = storage; - while (n--) - *p++ = jschar(*chars++); - *p = 0; - } - return str->header(); -} - JSString * js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n) { diff --git a/js/src/jsvector.h b/js/src/jsvector.h index 90917f8a582..ee974faf603 100644 --- a/js/src/jsvector.h +++ b/js/src/jsvector.h @@ -314,6 +314,8 @@ class Vector : AllocPolicy /* accessors */ + enum { InlineLength = N }; + size_t length() const { return usingInlineStorage() ? inlineLength() : heapLength(); }