| From: Stephan Schreiber <info@fs-driver.org> |
| Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=659186 |
| Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=589735 |
| Description: Turn off JS static strings on ia64 |
| |
| --- a/js/src/jsatom.cpp |
| +++ b/js/src/jsatom.cpp |
| @@ -603,11 +603,13 @@ js_GetExistingStringAtom(JSContext *cx, |
| JSString str, *str2; |
| JSAtomState *state; |
| |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (length == 1) { |
| jschar c = *chars; |
| if (c < UNIT_STRING_LIMIT) |
| return STRING_TO_ATOM(JSString::unitString(c)); |
| } |
| +#endif |
| |
| str.initFlatNotTerminated((jschar *)chars, length); |
| state = &cx->runtime->atomState; |
| --- a/js/src/jsiter.cpp |
| +++ b/js/src/jsiter.cpp |
| @@ -1002,9 +1002,12 @@ js_IteratorNext(JSContext *cx, JSObject |
| |
| JSString *str; |
| jsint i; |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (rval->isInt32() && (jsuint(i = rval->toInt32()) < INT_STRING_LIMIT)) { |
| str = JSString::intString(i); |
| - } else { |
| + } else |
| +#endif |
| + { |
| str = js_ValueToString(cx, *rval); |
| if (!str) |
| return false; |
| --- a/js/src/jsnum.cpp |
| +++ b/js/src/jsnum.cpp |
| @@ -605,8 +605,10 @@ js_IntToString(JSContext *cx, int32 si) |
| { |
| uint32 ui; |
| if (si >= 0) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (si < INT_STRING_LIMIT) |
| return JSString::intString(si); |
| +#endif |
| ui = si; |
| } else { |
| ui = uint32(-si); |
| @@ -1169,6 +1171,7 @@ js_NumberToStringWithBase(JSContext *cx, |
| |
| int32_t i; |
| if (JSDOUBLE_IS_INT32(d, &i)) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (base == 10 && jsuint(i) < INT_STRING_LIMIT) |
| return JSString::intString(i); |
| if (jsuint(i) < jsuint(base)) { |
| @@ -1176,6 +1179,7 @@ js_NumberToStringWithBase(JSContext *cx, |
| return JSString::intString(i); |
| return JSString::unitString(jschar('a' + i - 10)); |
| } |
| +#endif |
| |
| if (JSString *str = c->dtoaCache.lookup(base, d)) |
| return str; |
| --- a/js/src/jsstr.cpp |
| +++ b/js/src/jsstr.cpp |
| @@ -3121,6 +3121,8 @@ static JSFunctionSpec string_methods[] = |
| JS_FS_END |
| }; |
| |
| +#ifdef JS_HAS_STATIC_STRINGS |
| + |
| /* |
| * Set up some tools to make it easier to generate large tables. After constant |
| * folding, for each n, Rn(0) is the comma-separated list R(0), R(1), ..., R(2^n-1). |
| @@ -3291,6 +3293,8 @@ const JSString *const JSString::intStrin |
| #undef R3 |
| #undef R7 |
| |
| +#endif /* defined(JS_HAS_STATIC_STRINGS) */ |
| + |
| JSBool |
| js_String(JSContext *cx, uintN argc, Value *vp) |
| { |
| @@ -3331,6 +3335,7 @@ str_fromCharCode(JSContext *cx, uintN ar |
| uint16_t code; |
| if (!ValueToUint16(cx, argv[0], &code)) |
| return JS_FALSE; |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (code < UNIT_STRING_LIMIT) { |
| str = JSString::unitString(code); |
| if (!str) |
| @@ -3338,6 +3343,7 @@ str_fromCharCode(JSContext *cx, uintN ar |
| vp->setString(str); |
| return JS_TRUE; |
| } |
| +#endif |
| argv[0].setInt32(code); |
| } |
| chars = (jschar *) cx->malloc((argc + 1) * sizeof(jschar)); |
| @@ -3367,8 +3373,10 @@ String_fromCharCode(JSContext* cx, int32 |
| { |
| JS_ASSERT(JS_ON_TRACE(cx)); |
| jschar c = (jschar)i; |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (c < UNIT_STRING_LIMIT) |
| return JSString::unitString(c); |
| +#endif |
| return js_NewStringCopyN(cx, &c, 1); |
| } |
| #endif |
| --- a/js/src/jsstr.h |
| +++ b/js/src/jsstr.h |
| @@ -57,6 +57,15 @@ |
| #include "jsvalue.h" |
| #include "jscell.h" |
| |
| +#if !defined(__ia64__) |
| +/* |
| + * Don't use static strings on ia64 since the compiler may put the static |
| + * memory out of the acceptable 47-bit jsval pointer range. |
| + */ |
| +# define JS_HAS_STATIC_STRINGS |
| +#endif |
| + |
| +#ifdef JS_HAS_STATIC_STRINGS |
| enum { |
| UNIT_STRING_LIMIT = 256U, |
| SMALL_CHAR_LIMIT = 128U, /* Bigger chars cannot be in a length-2 string. */ |
| @@ -64,6 +73,7 @@ enum { |
| INT_STRING_LIMIT = 256U, |
| NUM_HUNDRED_STRINGS = 156U |
| }; |
| +#endif |
| |
| extern jschar * |
| js_GetDependentStringChars(JSString *str); |
| @@ -380,10 +390,15 @@ struct JSString |
| typedef uint8 SmallChar; |
| |
| static inline bool fitsInSmallChar(jschar c) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| return c < SMALL_CHAR_LIMIT && toSmallChar[c] != INVALID_SMALL_CHAR; |
| +#else |
| + return false; |
| +#endif |
| } |
| |
| static inline bool isUnitString(void *ptr) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| jsuword delta = reinterpret_cast<jsuword>(ptr) - |
| reinterpret_cast<jsuword>(unitStringTable); |
| if (delta >= UNIT_STRING_LIMIT * sizeof(JSString)) |
| @@ -392,9 +407,13 @@ struct JSString |
| /* If ptr points inside the static array, it must be well-aligned. */ |
| JS_ASSERT(delta % sizeof(JSString) == 0); |
| return true; |
| +#else |
| + return false; |
| +#endif |
| } |
| |
| static inline bool isLength2String(void *ptr) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| jsuword delta = reinterpret_cast<jsuword>(ptr) - |
| reinterpret_cast<jsuword>(length2StringTable); |
| if (delta >= NUM_SMALL_CHARS * NUM_SMALL_CHARS * sizeof(JSString)) |
| @@ -403,9 +422,13 @@ struct JSString |
| /* If ptr points inside the static array, it must be well-aligned. */ |
| JS_ASSERT(delta % sizeof(JSString) == 0); |
| return true; |
| +#else |
| + return false; |
| +#endif |
| } |
| |
| static inline bool isHundredString(void *ptr) { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| jsuword delta = reinterpret_cast<jsuword>(ptr) - |
| reinterpret_cast<jsuword>(hundredStringTable); |
| if (delta >= NUM_HUNDRED_STRINGS * sizeof(JSString)) |
| @@ -414,6 +437,9 @@ struct JSString |
| /* If ptr points inside the static array, it must be well-aligned. */ |
| JS_ASSERT(delta % sizeof(JSString) == 0); |
| return true; |
| +#else |
| + return false; |
| +#endif |
| } |
| |
| static inline bool isStatic(void *ptr) { |
| @@ -424,6 +450,7 @@ struct JSString |
| #pragma align 8 (__1cIJSStringPunitStringTable_, __1cIJSStringSlength2StringTable_, __1cIJSStringShundredStringTable_) |
| #endif |
| |
| +#ifdef JS_HAS_STATIC_STRINGS |
| static const SmallChar INVALID_SMALL_CHAR = -1; |
| |
| static const jschar fromSmallChar[]; |
| @@ -436,6 +463,7 @@ struct JSString |
| * strings, we keep a table to map from integer to the correct string. |
| */ |
| static const JSString *const intStringTable[]; |
| +#endif |
| |
| static JSFlatString *unitString(jschar c); |
| static JSLinearString *getUnitString(JSContext *cx, JSString *str, size_t index); |
| --- a/js/src/jsstrinlines.h |
| +++ b/js/src/jsstrinlines.h |
| @@ -215,52 +215,75 @@ StringBuffer::checkLength(size_t length) |
| inline JSFlatString * |
| JSString::unitString(jschar c) |
| { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| JS_ASSERT(c < UNIT_STRING_LIMIT); |
| return const_cast<JSString *>(&unitStringTable[c])->assertIsFlat(); |
| +#else |
| + JS_NOT_REACHED("no static strings"); |
| + return NULL; |
| +#endif |
| } |
| |
| inline JSLinearString * |
| JSString::getUnitString(JSContext *cx, JSString *str, size_t index) |
| { |
| JS_ASSERT(index < str->length()); |
| +#ifdef JS_HAS_STATIC_STRINGS |
| const jschar *chars = str->getChars(cx); |
| if (!chars) |
| return NULL; |
| jschar c = chars[index]; |
| if (c < UNIT_STRING_LIMIT) |
| return unitString(c); |
| +#endif |
| return js_NewDependentString(cx, str, index, 1); |
| } |
| |
| inline JSFlatString * |
| JSString::length2String(jschar c1, jschar c2) |
| { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| JS_ASSERT(fitsInSmallChar(c1)); |
| JS_ASSERT(fitsInSmallChar(c2)); |
| return const_cast<JSString *> ( |
| &length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]] |
| )->assertIsFlat(); |
| +#else |
| + JS_NOT_REACHED("no static strings"); |
| + return NULL; |
| +#endif |
| } |
| |
| inline JSFlatString * |
| JSString::length2String(uint32 i) |
| { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| JS_ASSERT(i < 100); |
| return length2String('0' + i / 10, '0' + i % 10); |
| +#else |
| + JS_NOT_REACHED("no static strings"); |
| + return NULL; |
| +#endif |
| } |
| |
| inline JSFlatString * |
| JSString::intString(jsint i) |
| { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| jsuint u = jsuint(i); |
| JS_ASSERT(u < INT_STRING_LIMIT); |
| return const_cast<JSString *>(JSString::intStringTable[u])->assertIsFlat(); |
| +#else |
| + JS_NOT_REACHED("no static strings"); |
| + return NULL; |
| +#endif |
| } |
| |
| /* Get a static atomized string for chars if possible. */ |
| inline JSFlatString * |
| JSString::lookupStaticString(const jschar *chars, size_t length) |
| { |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (length == 1) { |
| if (chars[0] < UNIT_STRING_LIMIT) |
| return unitString(chars[0]); |
| @@ -290,6 +313,7 @@ JSString::lookupStaticString(const jscha |
| return intString(i); |
| } |
| } |
| +#endif |
| |
| return NULL; |
| } |
| --- a/js/src/jstracer.cpp |
| +++ b/js/src/jstracer.cpp |
| @@ -11505,6 +11505,7 @@ TraceRecorder::callNative(uintN argc, JS |
| } |
| if (vp[1].isString()) { |
| JSString *str = vp[1].toString(); |
| +#ifdef JS_HAS_STATIC_STRINGS |
| if (native == js_str_charAt) { |
| jsdouble i = vp[2].toNumber(); |
| if (JSDOUBLE_IS_NaN(i)) |
| @@ -11518,7 +11519,9 @@ TraceRecorder::callNative(uintN argc, JS |
| set(&vp[0], char_ins); |
| pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK; |
| return RECORD_CONTINUE; |
| - } else if (native == js_str_charCodeAt) { |
| + } else |
| +#endif |
| + if (native == js_str_charCodeAt) { |
| jsdouble i = vp[2].toNumber(); |
| if (JSDOUBLE_IS_NaN(i)) |
| i = 0; |
| @@ -12967,6 +12970,7 @@ TraceRecorder::getCharCodeAt(JSString *s |
| JS_STATIC_ASSERT(sizeof(JSString) == 16 || sizeof(JSString) == 32); |
| |
| |
| +#ifdef JS_HAS_STATIC_STRINGS |
| JS_REQUIRES_STACK LIns* |
| TraceRecorder::getUnitString(LIns* str_ins, LIns* idx_ins) |
| { |
| @@ -13010,6 +13014,7 @@ TraceRecorder::getCharAt(JSString *str, |
| } |
| return RECORD_CONTINUE; |
| } |
| +#endif |
| |
| // Typed array tracing depends on EXPANDED_LOADSTORE and F2I |
| #if NJ_EXPANDED_LOADSTORE_SUPPORTED && NJ_F2I_SUPPORTED |
| @@ -13044,6 +13049,7 @@ TraceRecorder::record_JSOP_GETELEM() |
| LIns* obj_ins = get(&lval); |
| LIns* idx_ins = get(&idx); |
| |
| +#ifdef JS_HAS_STATIC_STRINGS |
| // Special case for array-like access of strings. |
| if (lval.isString() && hasInt32Repr(idx)) { |
| if (call) |
| @@ -13056,6 +13062,7 @@ TraceRecorder::record_JSOP_GETELEM() |
| set(&lval, char_ins); |
| return ARECORD_CONTINUE; |
| } |
| +#endif |
| |
| if (lval.isPrimitive()) |
| RETURN_STOP_A("JSOP_GETLEM on a primitive"); |
| --- a/js/src/jstracer.h |
| +++ b/js/src/jstracer.h |
| @@ -1394,10 +1394,12 @@ class TraceRecorder |
| JS_REQUIRES_STACK RecordingStatus getCharCodeAt(JSString *str, |
| nanojit::LIns* str_ins, nanojit::LIns* idx_ins, |
| nanojit::LIns** out_ins); |
| +#ifdef JS_HAS_STATIC_STRINGS |
| JS_REQUIRES_STACK nanojit::LIns* getUnitString(nanojit::LIns* str_ins, nanojit::LIns* idx_ins); |
| JS_REQUIRES_STACK RecordingStatus getCharAt(JSString *str, |
| nanojit::LIns* str_ins, nanojit::LIns* idx_ins, |
| JSOp mode, nanojit::LIns** out_ins); |
| +#endif |
| |
| JS_REQUIRES_STACK RecordingStatus initOrSetPropertyByName(nanojit::LIns* obj_ins, |
| Value* idvalp, Value* rvalp, |
| --- a/js/src/tracejit/Writer.cpp |
| +++ b/js/src/tracejit/Writer.cpp |
| @@ -246,7 +246,9 @@ couldBeObjectOrString(LIns *ins) |
| // ins = andq ins_oprnd1, ins_oprnd2 |
| ret = true; |
| #endif |
| - } else if (ins->isop(LIR_addp) && |
| + } |
| +#ifdef JS_HAS_STATIC_STRINGS |
| + else if (ins->isop(LIR_addp) && |
| ((ins->oprnd1()->isImmP() && |
| (void *)ins->oprnd1()->immP() == JSString::unitStringTable) || |
| (ins->oprnd2()->isImmP() && |
| @@ -258,6 +260,7 @@ couldBeObjectOrString(LIns *ins) |
| // ins = addp JSString::unitStringTable, ... |
| ret = true; |
| } |
| +#endif |
| |
| return ret; |
| } |