Detect some OOM conditions. b=602935, r=jorendorff.

This commit is contained in:
Sean Stangl 2010-10-14 19:24:09 -04:00
Родитель 051c03078f
Коммит 5dfc1b29e9
7 изменённых файлов: 206 добавлений и 209 удалений

Просмотреть файл

@ -2315,6 +2315,8 @@ ethogram_construct(JSContext *cx, uintN argc, jsval *vp)
EthogramEventBuffer *p;
p = (EthogramEventBuffer *) JS_malloc(cx, sizeof(EthogramEventBuffer));
if (!p)
return JS_FALSE;
p->mReadPos = p->mWritePos = 0;
p->mScripts = NULL;

Просмотреть файл

@ -328,201 +328,202 @@ js_dtobasestr(DtoaState *state, int base, double dinput)
dval(d) = dinput;
buffer = (char*) js_malloc(DTOBASESTR_BUFFER_SIZE);
if (buffer) {
p = buffer;
if (dval(d) < 0.0
if (!buffer)
return NULL;
p = buffer;
if (dval(d) < 0.0
#if defined(XP_WIN) || defined(XP_OS2)
&& !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */
&& !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */
#endif
) {
*p++ = '-';
dval(d) = -dval(d);
}
) {
*p++ = '-';
dval(d) = -dval(d);
}
/* Check for Infinity and NaN */
if ((word0(d) & Exp_mask) == Exp_mask) {
strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN");
return buffer;
}
/* Check for Infinity and NaN */
if ((word0(d) & Exp_mask) == Exp_mask) {
strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN");
return buffer;
}
/* Output the integer part of d with the digits in reverse order. */
pInt = p;
dval(di) = floor(dval(d));
if (dval(di) <= 4294967295.0) {
uint32 n = (uint32)dval(di);
if (n)
do {
uint32 m = n / base;
digit = n - m*base;
n = m;
JS_ASSERT(digit < (uint32)base);
*p++ = BASEDIGIT(digit);
} while (n);
else *p++ = '0';
} else {
int e;
int bits; /* Number of significant bits in di; not used. */
Bigint *b = d2b(PASS_STATE di, &e, &bits);
if (!b)
goto nomem1;
b = lshift(PASS_STATE b, e);
if (!b) {
nomem1:
Bfree(PASS_STATE b);
js_free(buffer);
return NULL;
}
/* Output the integer part of d with the digits in reverse order. */
pInt = p;
dval(di) = floor(dval(d));
if (dval(di) <= 4294967295.0) {
uint32 n = (uint32)dval(di);
if (n)
do {
digit = divrem(b, base);
uint32 m = n / base;
digit = n - m*base;
n = m;
JS_ASSERT(digit < (uint32)base);
*p++ = BASEDIGIT(digit);
} while (b->wds);
} while (n);
else *p++ = '0';
} else {
int e;
int bits; /* Number of significant bits in di; not used. */
Bigint *b = d2b(PASS_STATE di, &e, &bits);
if (!b)
goto nomem1;
b = lshift(PASS_STATE b, e);
if (!b) {
nomem1:
Bfree(PASS_STATE b);
js_free(buffer);
return NULL;
}
/* Reverse the digits of the integer part of d. */
q = p-1;
while (q > pInt) {
char ch = *pInt;
*pInt++ = *q;
*q-- = ch;
}
do {
digit = divrem(b, base);
JS_ASSERT(digit < (uint32)base);
*p++ = BASEDIGIT(digit);
} while (b->wds);
Bfree(PASS_STATE b);
}
/* Reverse the digits of the integer part of d. */
q = p-1;
while (q > pInt) {
char ch = *pInt;
*pInt++ = *q;
*q-- = ch;
}
dval(df) = dval(d) - dval(di);
if (dval(df) != 0.0) {
/* We have a fraction. */
int e, bbits;
int32 s2, done;
Bigint *b, *s, *mlo, *mhi;
dval(df) = dval(d) - dval(di);
if (dval(df) != 0.0) {
/* We have a fraction. */
int e, bbits;
int32 s2, done;
Bigint *b, *s, *mlo, *mhi;
b = s = mlo = mhi = NULL;
b = s = mlo = mhi = NULL;
*p++ = '.';
b = d2b(PASS_STATE df, &e, &bbits);
if (!b) {
nomem2:
Bfree(PASS_STATE b);
Bfree(PASS_STATE s);
if (mlo != mhi)
Bfree(PASS_STATE mlo);
Bfree(PASS_STATE mhi);
js_free(buffer);
return NULL;
}
JS_ASSERT(e < 0);
/* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1);
#ifndef Sudden_Underflow
if (!s2)
s2 = -1;
#endif
s2 += Bias + P;
/* 1/2^s2 = (nextDouble(d) - d)/2 */
JS_ASSERT(-s2 < e);
mlo = i2b(PASS_STATE 1);
if (!mlo)
goto nomem2;
mhi = mlo;
if (!word1(d) && !(word0(d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0(d) & (Exp_mask & Exp_mask << 1)
#endif
) {
/* The special case. Here we want to be within a quarter of the last input
significant digit instead of one half of it when the output string's value is less than d. */
s2 += Log2P;
mhi = i2b(PASS_STATE 1<<Log2P);
if (!mhi)
goto nomem2;
}
b = lshift(PASS_STATE b, e + s2);
if (!b)
goto nomem2;
s = i2b(PASS_STATE 1);
if (!s)
goto nomem2;
s = lshift(PASS_STATE s, s2);
if (!s)
goto nomem2;
/* At this point we have the following:
* s = 2^s2;
* 1 > df = b/2^s2 > 0;
* (d - prevDouble(d))/2 = mlo/2^s2;
* (nextDouble(d) - d)/2 = mhi/2^s2. */
done = JS_FALSE;
do {
int32 j, j1;
Bigint *delta;
b = multadd(PASS_STATE b, base, 0);
if (!b)
goto nomem2;
digit = quorem2(b, s2);
if (mlo == mhi) {
mlo = mhi = multadd(PASS_STATE mlo, base, 0);
if (!mhi)
goto nomem2;
}
else {
mlo = multadd(PASS_STATE mlo, base, 0);
if (!mlo)
goto nomem2;
mhi = multadd(PASS_STATE mhi, base, 0);
if (!mhi)
goto nomem2;
}
/* Do we yet have the shortest string that will round to d? */
j = cmp(b, mlo);
/* j is b/2^s2 compared with mlo/2^s2. */
delta = diff(PASS_STATE s, mhi);
if (!delta)
goto nomem2;
j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(PASS_STATE delta);
/* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
#ifndef ROUND_BIASED
if (j1 == 0 && !(word1(d) & 1)) {
if (j > 0)
digit++;
done = JS_TRUE;
} else
#endif
if (j < 0 || (j == 0
#ifndef ROUND_BIASED
&& !(word1(d) & 1)
#endif
)) {
if (j1 > 0) {
/* Either dig or dig+1 would work here as the least significant digit.
Use whichever would produce an output value closer to d. */
b = lshift(PASS_STATE b, 1);
if (!b)
goto nomem2;
j1 = cmp(b, s);
if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
* such as 3.5 in base 3. */
digit++;
}
done = JS_TRUE;
} else if (j1 > 0) {
digit++;
done = JS_TRUE;
}
JS_ASSERT(digit < (uint32)base);
*p++ = BASEDIGIT(digit);
} while (!done);
*p++ = '.';
b = d2b(PASS_STATE df, &e, &bbits);
if (!b) {
nomem2:
Bfree(PASS_STATE b);
Bfree(PASS_STATE s);
if (mlo != mhi)
Bfree(PASS_STATE mlo);
Bfree(PASS_STATE mhi);
js_free(buffer);
return NULL;
}
JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE);
*p = '\0';
JS_ASSERT(e < 0);
/* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1);
#ifndef Sudden_Underflow
if (!s2)
s2 = -1;
#endif
s2 += Bias + P;
/* 1/2^s2 = (nextDouble(d) - d)/2 */
JS_ASSERT(-s2 < e);
mlo = i2b(PASS_STATE 1);
if (!mlo)
goto nomem2;
mhi = mlo;
if (!word1(d) && !(word0(d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0(d) & (Exp_mask & Exp_mask << 1)
#endif
) {
/* The special case. Here we want to be within a quarter of the last input
significant digit instead of one half of it when the output string's value is less than d. */
s2 += Log2P;
mhi = i2b(PASS_STATE 1<<Log2P);
if (!mhi)
goto nomem2;
}
b = lshift(PASS_STATE b, e + s2);
if (!b)
goto nomem2;
s = i2b(PASS_STATE 1);
if (!s)
goto nomem2;
s = lshift(PASS_STATE s, s2);
if (!s)
goto nomem2;
/* At this point we have the following:
* s = 2^s2;
* 1 > df = b/2^s2 > 0;
* (d - prevDouble(d))/2 = mlo/2^s2;
* (nextDouble(d) - d)/2 = mhi/2^s2. */
done = JS_FALSE;
do {
int32 j, j1;
Bigint *delta;
b = multadd(PASS_STATE b, base, 0);
if (!b)
goto nomem2;
digit = quorem2(b, s2);
if (mlo == mhi) {
mlo = mhi = multadd(PASS_STATE mlo, base, 0);
if (!mhi)
goto nomem2;
}
else {
mlo = multadd(PASS_STATE mlo, base, 0);
if (!mlo)
goto nomem2;
mhi = multadd(PASS_STATE mhi, base, 0);
if (!mhi)
goto nomem2;
}
/* Do we yet have the shortest string that will round to d? */
j = cmp(b, mlo);
/* j is b/2^s2 compared with mlo/2^s2. */
delta = diff(PASS_STATE s, mhi);
if (!delta)
goto nomem2;
j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(PASS_STATE delta);
/* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
#ifndef ROUND_BIASED
if (j1 == 0 && !(word1(d) & 1)) {
if (j > 0)
digit++;
done = JS_TRUE;
} else
#endif
if (j < 0 || (j == 0
#ifndef ROUND_BIASED
&& !(word1(d) & 1)
#endif
)) {
if (j1 > 0) {
/* Either dig or dig+1 would work here as the least significant digit.
Use whichever would produce an output value closer to d. */
b = lshift(PASS_STATE b, 1);
if (!b)
goto nomem2;
j1 = cmp(b, s);
if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
* such as 3.5 in base 3. */
digit++;
}
done = JS_TRUE;
} else if (j1 > 0) {
digit++;
done = JS_TRUE;
}
JS_ASSERT(digit < (uint32)base);
*p++ = BASEDIGIT(digit);
} while (!done);
Bfree(PASS_STATE b);
Bfree(PASS_STATE s);
if (mlo != mhi)
Bfree(PASS_STATE mlo);
Bfree(PASS_STATE mhi);
}
JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE);
*p = '\0';
return buffer;
}

Просмотреть файл

@ -1657,6 +1657,8 @@ js_DumpOpMeters()
# define SIGNIFICANT(count,total) (200. * (count) >= (total))
graph = (Edge *) js_calloc(nedges * sizeof graph[0]);
if (!graph)
return;
for (i = nedges = 0; i < JSOP_LIMIT; i++) {
from = js_CodeName[i];
for (j = 0; j < JSOP_LIMIT; j++) {

Просмотреть файл

@ -404,20 +404,6 @@ js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
return FinishConcat(cx, leftRopeTop, rightRopeTop, left, right, length, buf);
}
JSString * JS_FASTCALL
js_ConcatStringsZ(JSContext *cx, const char *left, JSString *right)
{
const size_t leftLength = strlen(left);
const size_t newLength = leftLength + right->length();
const size_t newSize = (newLength + 1) * sizeof(jschar);
jschar *chars = static_cast<jschar *>(cx->malloc(newSize));
for (size_t i = 0; i < leftLength; ++i)
chars[i] = left[i];
js_strncpy(chars + leftLength, right->chars(), right->length());
JSString *str = js_NewString(cx, chars, newLength);
return str;
}
const jschar *
JSString::undepend(JSContext *cx)
{

Просмотреть файл

@ -76,9 +76,6 @@ js_GetDependentStringChars(JSString *str);
extern JSString * JS_FASTCALL
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
extern JSString * JS_FASTCALL
js_ConcatStringsZ(JSContext *cx, const char *left, JSString *right);
JS_STATIC_ASSERT(JS_BITS_PER_WORD >= 32);
struct JSRopeBufferInfo {

Просмотреть файл

@ -4594,10 +4594,12 @@ TraceRecorder::compile()
/* Associate a filename and line number with the fragment. */
const char* filename = cx->fp()->script()->filename;
char* label = (char*)js_malloc((filename ? strlen(filename) : 7) + 16);
sprintf(label, "%s:%u", filename ? filename : "<stdin>",
js_FramePCToLineNumber(cx, cx->fp()));
lirbuf->printer->addrNameMap->addAddrRange(fragment, sizeof(Fragment), 0, label);
js_free(label);
if (label) {
sprintf(label, "%s:%u", filename ? filename : "<stdin>",
js_FramePCToLineNumber(cx, cx->fp()));
lirbuf->printer->addrNameMap->addAddrRange(fragment, sizeof(Fragment), 0, label);
js_free(label);
}
#endif
Assembler *assm = traceMonitor->assembler;

Просмотреть файл

@ -927,7 +927,8 @@ class TypedArrayTemplate
return false;
}
tarray->copyFrom(src, offset);
if (!tarray->copyFrom(cx, src, offset))
return false;
} else if (arg0->wrappedObject(cx)->isArray()) {
jsuint len;
if (!js_GetLengthProperty(cx, arg0, &len))
@ -1007,7 +1008,8 @@ class TypedArrayTemplate
if (!createBufferWithSizeAndCount(cx, sizeof(NativeType), tarray->length))
return false;
copyFrom(tarray);
if (!copyFrom(cx, tarray))
return false;
} else if (other->getClass() == &ArrayBuffer::jsclass) {
ArrayBuffer *abuf = ArrayBuffer::fromJSObject(other);
@ -1154,21 +1156,19 @@ class TypedArrayTemplate
return true;
}
void
copyFrom(TypedArray *tarray, jsuint offset = 0)
bool
copyFrom(JSContext *cx, TypedArray *tarray, jsuint offset = 0)
{
JS_ASSERT(offset <= length);
JS_ASSERT(tarray->length <= length - offset);
if (tarray->buffer == buffer) {
copyFromWithOverlap(tarray, offset);
return;
}
if (tarray->buffer == buffer)
return copyFromWithOverlap(cx, tarray, offset);
NativeType *dest = static_cast<NativeType*>(data) + offset;
if (tarray->type == type) {
memcpy(dest, tarray->data, tarray->byteLength);
return;
return true;
}
uintN srclen = tarray->length;
@ -1226,10 +1226,12 @@ class TypedArrayTemplate
JS_NOT_REACHED("copyFrom with a TypedArray of unknown type");
break;
}
return true;
}
void
copyFromWithOverlap(TypedArray *tarray, jsuint offset = 0)
bool
copyFromWithOverlap(JSContext *cx, TypedArray *tarray, jsuint offset = 0)
{
JS_ASSERT(offset < length);
@ -1237,12 +1239,16 @@ class TypedArrayTemplate
if (tarray->type == type) {
memmove(dest, tarray->data, tarray->byteLength);
return;
return true;
}
// We have to make a copy of the source array here, since
// there's overlap, and we have to convert types.
void *srcbuf = js_malloc(tarray->byteLength);
if (!srcbuf) {
js_ReportOutOfMemory(cx);
return false;
}
memcpy(srcbuf, tarray->data, tarray->byteLength);
switch (tarray->type) {
@ -1301,6 +1307,7 @@ class TypedArrayTemplate
}
js_free(srcbuf);
return true;
}
bool