mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 04:03:47 +00:00
Fix net vs. gross botches from patch for 489899 (514112, r=gal).
This commit is contained in:
parent
fb283f7442
commit
953fdff59e
@ -308,11 +308,11 @@ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldsize, uint32 size)
|
||||
ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldlen, uint32 newlen)
|
||||
{
|
||||
jsval *slots, *newslots;
|
||||
|
||||
if (size == 0) {
|
||||
if (newlen == 0) {
|
||||
if (obj->dslots) {
|
||||
cx->free(obj->dslots - 1);
|
||||
obj->dslots = NULL;
|
||||
@ -320,24 +320,20 @@ ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldsize, uint32 size)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* MAX_DSLOTS_LENGTH is the maximum net capacity supported. Since we allocate
|
||||
* one additional slot to hold the array length, we have to use >= here.
|
||||
*/
|
||||
if (size >= MAX_DSLOTS_LENGTH) {
|
||||
if (newlen > MAX_DSLOTS_LENGTH) {
|
||||
js_ReportAllocationOverflow(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
slots = obj->dslots ? obj->dslots - 1 : NULL;
|
||||
newslots = (jsval *) cx->realloc(slots, (size + 1) * sizeof(jsval));
|
||||
newslots = (jsval *) cx->realloc(slots, (newlen + 1) * sizeof(jsval));
|
||||
if (!newslots)
|
||||
return JS_FALSE;
|
||||
|
||||
obj->dslots = newslots + 1;
|
||||
js_SetDenseArrayCapacity(obj, size);
|
||||
js_SetDenseArrayCapacity(obj, newlen);
|
||||
|
||||
for (slots = obj->dslots + oldsize; slots < obj->dslots + size; slots++)
|
||||
for (slots = obj->dslots + oldlen; slots < obj->dslots + newlen; slots++)
|
||||
*slots = JSVAL_HOLE;
|
||||
|
||||
return JS_TRUE;
|
||||
@ -359,31 +355,31 @@ ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldsize, uint32 size)
|
||||
#define CAPACITY_CHUNK (1024 * 1024 / sizeof(jsval))
|
||||
|
||||
static JSBool
|
||||
EnsureCapacity(JSContext *cx, JSObject *obj, uint32 capacity)
|
||||
EnsureCapacity(JSContext *cx, JSObject *obj, uint32 newcap)
|
||||
{
|
||||
uint32 oldsize = js_DenseArrayCapacity(obj);
|
||||
uint32 oldcap = js_DenseArrayCapacity(obj);
|
||||
|
||||
if (capacity > oldsize) {
|
||||
if (newcap > oldcap) {
|
||||
/*
|
||||
* If this overflows uint32, capacity is very large. nextsize will end
|
||||
* up being less than capacity, the code below will thus disregard it,
|
||||
* If this overflows uint32, newcap is very large. nextsize will end
|
||||
* up being less than newcap, the code below will thus disregard it,
|
||||
* and ResizeSlots will fail.
|
||||
*
|
||||
* The way we use dslots[-1] forces a few +1s and -1s here. For
|
||||
* example, (oldsize * 2 + 1) produces the sequence 7, 15, 31, 63, ...
|
||||
* example, (oldcap * 2 + 1) produces the sequence 7, 15, 31, 63, ...
|
||||
* which makes the total allocation size (with dslots[-1]) a power
|
||||
* of two.
|
||||
*/
|
||||
uint32 nextsize = (oldsize <= CAPACITY_DOUBLING_MAX)
|
||||
? oldsize * 2 + 1
|
||||
: oldsize + (oldsize >> 3);
|
||||
uint32 nextsize = (oldcap <= CAPACITY_DOUBLING_MAX)
|
||||
? oldcap * 2 + 1
|
||||
: oldcap + (oldcap >> 3);
|
||||
|
||||
capacity = JS_MAX(capacity, nextsize);
|
||||
if (capacity >= CAPACITY_CHUNK)
|
||||
capacity = JS_ROUNDUP(capacity + 1, CAPACITY_CHUNK) - 1; /* -1 for dslots[-1] */
|
||||
else if (capacity < ARRAY_CAPACITY_MIN)
|
||||
capacity = ARRAY_CAPACITY_MIN;
|
||||
return ResizeSlots(cx, obj, oldsize, capacity);
|
||||
newcap = JS_MAX(newcap, nextsize);
|
||||
if (newcap >= CAPACITY_CHUNK)
|
||||
newcap = JS_ROUNDUP(newcap + 1, CAPACITY_CHUNK) - 1; /* -1 for dslots[-1] */
|
||||
else if (newcap < ARRAY_CAPACITY_MIN)
|
||||
newcap = ARRAY_CAPACITY_MIN;
|
||||
return ResizeSlots(cx, obj, oldcap, newcap);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -646,8 +642,8 @@ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
/* Don't reallocate if we're not actually shrinking our slots. */
|
||||
jsuint oldsize = js_DenseArrayCapacity(obj);
|
||||
if (oldsize >= newlen && !ResizeSlots(cx, obj, oldsize, newlen))
|
||||
jsuint capacity = js_DenseArrayCapacity(obj);
|
||||
if (capacity > newlen && !ResizeSlots(cx, obj, capacity, newlen))
|
||||
return JS_FALSE;
|
||||
} else if (oldlen - newlen < (1 << 24)) {
|
||||
do {
|
||||
@ -898,8 +894,8 @@ dense_grow(JSContext* cx, JSObject* obj, jsint i, jsval v)
|
||||
/*
|
||||
* Let the interpreter worry about negative array indexes.
|
||||
*/
|
||||
JS_ASSERT((MAX_DSLOTS_LENGTH > JSVAL_INT_MAX) == (sizeof(jsval) != sizeof(uint32)));
|
||||
if (MAX_DSLOTS_LENGTH > JSVAL_INT_MAX) {
|
||||
JS_ASSERT((MAX_DSLOTS_LENGTH > MAX_DSLOTS_LENGTH32) == (sizeof(jsval) != sizeof(uint32)));
|
||||
if (MAX_DSLOTS_LENGTH > MAX_DSLOTS_LENGTH32) {
|
||||
/*
|
||||
* Have to check for negative values bleeding through on 64-bit machines only,
|
||||
* since we can't allocate large enough arrays for this on 32-bit machines.
|
||||
|
@ -308,10 +308,12 @@ struct JSObject {
|
||||
+ JSCLASS_RESERVED_SLOTS(clasp))
|
||||
|
||||
/*
|
||||
* Maximum net gross capacity of the obj->dslots vector, excluding the additional
|
||||
* hidden slot used to store the length of the vector.
|
||||
* Maximum capacity of the obj->dslots vector, net of the hidden slot at
|
||||
* obj->dslots[-1] that is used to store the length of the vector biased by
|
||||
* JS_INITIAL_NSLOTS (and again net of the slot at index -1).
|
||||
*/
|
||||
#define MAX_DSLOTS_LENGTH (JS_MAX(~(uint32)0, ~(size_t)0) / sizeof(jsval))
|
||||
#define MAX_DSLOTS_LENGTH (JS_MAX(~uint32(0), ~size_t(0)) / sizeof(jsval) - 1)
|
||||
#define MAX_DSLOTS_LENGTH32 (~uint32(0) / sizeof(jsval) - 1)
|
||||
|
||||
/*
|
||||
* STOBJ prefix means Single Threaded Object. Use the following fast macros to
|
||||
|
@ -11303,8 +11303,9 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
if (!within) {
|
||||
/* If idx < 0, stay on trace (and read value as undefined, since this is a dense array). */
|
||||
LIns* br1 = NULL;
|
||||
if (MAX_DSLOTS_LENGTH > JS_BITMASK(30) && !idx_ins->isconst()) {
|
||||
JS_ASSERT(sizeof(jsval) == 8); // Only 64-bit machines support large enough arrays for this.
|
||||
if (MAX_DSLOTS_LENGTH > MAX_DSLOTS_LENGTH32 && !idx_ins->isconst()) {
|
||||
/* Only 64-bit machines support large enough arrays for this. */
|
||||
JS_ASSERT(sizeof(jsval) == 8);
|
||||
br1 = lir->insBranch(LIR_jt,
|
||||
lir->ins2i(LIR_lt, idx_ins, 0),
|
||||
NULL);
|
||||
@ -11345,8 +11346,9 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
}
|
||||
|
||||
/* Guard against negative index */
|
||||
if (MAX_DSLOTS_LENGTH > JS_BITMASK(30) && !idx_ins->isconst()) {
|
||||
JS_ASSERT(sizeof(jsval) == 8); // Only 64-bit machines support large enough arrays for this.
|
||||
if (MAX_DSLOTS_LENGTH > MAX_DSLOTS_LENGTH32 && !idx_ins->isconst()) {
|
||||
/* Only 64-bit machines support large enough arrays for this. */
|
||||
JS_ASSERT(sizeof(jsval) == 8);
|
||||
guard(false,
|
||||
lir->ins2i(LIR_lt, idx_ins, 0),
|
||||
exit);
|
||||
|
Loading…
x
Reference in New Issue
Block a user