Bug 648022: Backout bug 518230 due to startup crashes, r=igor

This commit is contained in:
Michael Wu 2011-05-16 09:20:40 -07:00
parent 0ee427542f
commit 53b677e2a1
2 changed files with 85 additions and 113 deletions

View File

@ -414,55 +414,67 @@ JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
return JS_XDRCString(xdr, sp);
}
static JSBool
XDRChars(JSXDRState *xdr, jschar *chars, uint32 nchars)
{
uint32 i, padlen, nbytes;
jschar *raw;
nbytes = nchars * sizeof(jschar);
padlen = nbytes % JSXDR_ALIGN;
if (padlen) {
padlen = JSXDR_ALIGN - padlen;
nbytes += padlen;
}
if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
return JS_FALSE;
if (xdr->mode == JSXDR_ENCODE) {
for (i = 0; i != nchars; i++)
raw[i] = JSXDR_SWAB16(chars[i]);
if (padlen)
memset((char *)raw + nbytes - padlen, 0, padlen);
} else if (xdr->mode == JSXDR_DECODE) {
for (i = 0; i != nchars; i++)
chars[i] = JSXDR_SWAB16(raw[i]);
}
return JS_TRUE;
}
/*
* Convert between a JS (Unicode) string and the XDR representation.
*/
JS_PUBLIC_API(JSBool)
JS_XDRString(JSXDRState *xdr, JSString **strp)
{
uint32 nchars = 0;
size_t len;
uint32 nchars;
jschar *chars;
if (xdr->mode == JSXDR_ENCODE) {
len = GetDeflatedUTF8StringLength(xdr->cx,
(*strp)->getChars(xdr->cx),
(*strp)->length(),
CESU8Encoding);
/* GetDeflatedUTF8StringLength never fails in CESU8 mode */
JS_ASSERT(len != (size_t) -1);
JS_ASSERT(size_t(uint32(len)) == len);
/* ensure MAX_LENGTH strings can always fit when CESU8 encoded */
JS_STATIC_ASSERT(JSString::MAX_LENGTH < (uint32(-1) / 3));
nchars = (uint32)len;
}
if (xdr->mode == JSXDR_ENCODE)
nchars = (*strp)->length();
if (!JS_XDRUint32(xdr, &nchars))
return false;
return JS_FALSE;
JS_ASSERT(xdr->ops == &xdrmem_ops);
uint32 paddedLen = (nchars + JSXDR_MASK) & ~JSXDR_MASK;
char *buf = (char *)mem_raw(xdr, paddedLen);
if (!buf)
return false;
if (xdr->mode == JSXDR_DECODE)
chars = (jschar *) xdr->cx->malloc_((nchars + 1) * sizeof(jschar));
else
chars = const_cast<jschar *>((*strp)->getChars(xdr->cx));
if (!chars)
return JS_FALSE;
len = (uint32)nchars;
if (xdr->mode == JSXDR_ENCODE) {
JS_ALWAYS_TRUE(DeflateStringToUTF8Buffer(xdr->cx,
(*strp)->getChars(xdr->cx),
(*strp)->length(), buf,
&len, CESU8Encoding));
} else {
jschar *chars = InflateString(xdr->cx, buf, &len, CESU8Encoding);
if (!chars)
return false;
*strp = js_NewString(xdr->cx, chars, len);
if (!*strp) {
xdr->cx->free_(chars);
return false;
}
if (!XDRChars(xdr, chars, nchars))
goto bad;
if (xdr->mode == JSXDR_DECODE) {
chars[nchars] = 0;
*strp = JS_NewUCString(xdr->cx, chars, nchars);
if (!*strp)
goto bad;
}
return JS_TRUE;
return true;
bad:
if (xdr->mode == JSXDR_DECODE)
xdr->cx->free_(chars);
return JS_FALSE;
}
JS_PUBLIC_API(JSBool)
@ -605,76 +617,50 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
return JS_XDRUint32(xdr, &type) && XDRValueBody(xdr, type, vp);
}
static uint32
XDRGetAtomIndex(JSXDRState *xdr, JSAtom *atom)
{
if (XDRAtomsHashMap::Ptr p = xdr->state->atomsMap.lookup(atom))
return p->value;
return uint32(-1);
}
static bool
XDRPutAtomIndex(JSXDRState *xdr, JSAtom *atom)
{
XDRScriptState *state = xdr->state;
if (state->atoms.length() >= size_t(uint32(-1)))
return true;
if ((xdr->mode == JSXDR_DECODE ||
state->atomsMap.put(atom, uint32(state->atoms.length()))) &&
state->atoms.append(atom))
return true;
js_ReportOutOfMemory(xdr->cx);
return false;
}
extern JSBool
js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
{
uint32 idx;
JSString *str;
uint32 nchars;
JSAtom *atom;
JSContext *cx;
jschar *chars;
jschar stackChars[256];
if (xdr->mode == JSXDR_ENCODE) {
idx = XDRGetAtomIndex(xdr, *atomp);
if (idx == uint32(-1) &&
!XDRPutAtomIndex(xdr, *atomp))
return false;
str = *atomp;
return JS_XDRString(xdr, &str);
}
if (!JS_XDRUint32(xdr, &idx))
return false;
if (xdr->mode == JSXDR_DECODE) {
if (idx != uint32(-1)) {
JS_ASSERT(size_t(idx) < xdr->state->atoms.length());
*atomp = xdr->state->atoms[idx];
} else {
uint32 len;
if (!JS_XDRUint32(xdr, &len))
return false;
JS_ASSERT(xdr->ops == &xdrmem_ops);
uint32 paddedLen = (len + JSXDR_MASK) & ~JSXDR_MASK;
char *buf = (char *)mem_raw(xdr, paddedLen);
if (!buf)
return false;
JSAtom *atom = js_Atomize(xdr->cx, buf, len, DoNotInternAtom, CESU8Encoding);
if (!atom)
return false;
if (!XDRPutAtomIndex(xdr, atom))
return false;
*atomp = atom;
}
/*
* Inline JS_XDRString when decoding to avoid JSString allocation
* for already existing atoms. See bug 321985.
*/
if (!JS_XDRUint32(xdr, &nchars))
return JS_FALSE;
atom = NULL;
cx = xdr->cx;
if (nchars <= JS_ARRAY_LENGTH(stackChars)) {
chars = stackChars;
} else {
if (idx == uint32(-1)) {
JSString *str = *atomp;
return JS_XDRString(xdr, &str);
}
/*
* This is very uncommon. Don't use the tempPool arena for this as
* most allocations here will be bigger than tempPool's arenasize.
*/
chars = (jschar *) cx->malloc_(nchars * sizeof(jschar));
if (!chars)
return JS_FALSE;
}
return true;
if (XDRChars(xdr, chars, nchars))
atom = js_AtomizeChars(cx, chars, nchars);
if (chars != stackChars)
cx->free_(chars);
if (!atom)
return JS_FALSE;
*atomp = atom;
return JS_TRUE;
}
XDRScriptState::XDRScriptState(JSXDRState *x)
@ -684,11 +670,6 @@ XDRScriptState::XDRScriptState(JSXDRState *x)
{
JS_ASSERT(!xdr->state);
if (xdr->mode == JSXDR_ENCODE && !atomsMap.init()) {
js_ReportOutOfMemory(xdr->cx);
return;
}
xdr->state = this;
}

View File

@ -61,11 +61,8 @@
* Spiritually guided by Sun's XDR, where appropriate.
*/
#include "jsatom.h"
#include "jspubtd.h"
#include "jsprvtd.h"
#include "jsvector.h"
#include "jshashtable.h"
JS_BEGIN_EXTERN_C
@ -85,7 +82,6 @@ JS_BEGIN_EXTERN_C
#endif
#define JSXDR_ALIGN 4
#define JSXDR_MASK (JSXDR_ALIGN - 1)
typedef enum JSXDRMode {
JSXDR_ENCODE,
@ -109,9 +105,6 @@ typedef struct JSXDROps {
void (*finalize)(JSXDRState *);
} JSXDROps;
typedef js::Vector<JSAtom *, 1, js::SystemAllocPolicy> XDRAtoms;
typedef js::HashMap<JSAtom *, uint32, js::DefaultHasher<JSAtom *>, js::SystemAllocPolicy> XDRAtomsHashMap;
struct JSXDRState;
namespace js {
@ -124,8 +117,6 @@ public:
JSXDRState *xdr;
const char *filename;
bool filenameSaved;
XDRAtoms atoms;
XDRAtomsHashMap atomsMap;
};
} /* namespace JS */
@ -231,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 86)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 88)
/*
* Library-private functions.