mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 479566 - Rename array "dense length" to capacity. r=shaver.
This commit is contained in:
parent
bf8b9e17e4
commit
15b9f03458
@ -49,7 +49,7 @@
|
||||
* We track these pieces of metadata for arrays in dense mode:
|
||||
* - the array's length property as a uint32, in JSSLOT_ARRAY_LENGTH,
|
||||
* - the number of indices that are filled (non-holes), in JSSLOT_ARRAY_COUNT,
|
||||
* - the net number of slots starting at dslots (DENSELEN), in dslots[-1] if
|
||||
* - the net number of slots starting at dslots (capacity), in dslots[-1] if
|
||||
* dslots is non-NULL.
|
||||
*
|
||||
* In dense mode, holes in the array are represented by JSVAL_HOLE. The final
|
||||
@ -58,22 +58,18 @@
|
||||
*
|
||||
* Arrays are converted to use js_SlowArrayClass when any of these conditions
|
||||
* are met:
|
||||
* - the load factor (COUNT / DENSELEN) is less than 0.25, and there are
|
||||
* - the load factor (COUNT / capacity) is less than 0.25, and there are
|
||||
* more than MIN_SPARSE_INDEX slots total
|
||||
* - a property is set that is non-numeric (and not "length"); or
|
||||
* - a hole is filled below DENSELEN (possibly implicitly through methods like
|
||||
* |reverse| or |splice|).
|
||||
* - a property is defined that has non-default property attributes.
|
||||
*
|
||||
* In the latter two cases, property creation order is no longer index order,
|
||||
* which necessitates use of a structure that keeps track of property creation
|
||||
* order. (ES4, due to expectations baked into web script, requires that
|
||||
* enumeration order be the order in which properties were created.)
|
||||
*
|
||||
* An alternative in the latter case (out-of-order index set) would be to
|
||||
* maintain the scope to track property enumeration order, but still use
|
||||
* the fast slot access. That would have the same memory cost as just using
|
||||
* a js_SlowArrayClass, but have the same performance characteristics as
|
||||
* a dense array for slot accesses, at some cost in code complexity.
|
||||
* Dense arrays do not track property creation order, so unlike other native
|
||||
* objects and slow arrays, enumerating an array does not necessarily visit the
|
||||
* properties in the order they were created. We could instead maintain the
|
||||
* scope to track property enumeration order, but still use the fast slot
|
||||
* access. That would have the same memory cost as just using a
|
||||
* js_SlowArrayClass, but have the same performance characteristics as a dense
|
||||
* array for slot accesses, at some cost in code complexity.
|
||||
*/
|
||||
#include "jsstddef.h"
|
||||
#include <stdlib.h>
|
||||
@ -110,7 +106,7 @@
|
||||
#define INDEX_TOO_BIG(index) ((index) > JS_BIT(29) - 1)
|
||||
#define INDEX_TOO_SPARSE(array, index) \
|
||||
(INDEX_TOO_BIG(index) || \
|
||||
((index) > ARRAY_DENSE_LENGTH(array) && (index) >= MIN_SPARSE_INDEX && \
|
||||
((index) > js_DenseArrayCapacity(array) && (index) >= MIN_SPARSE_INDEX && \
|
||||
(index) > (uint32)((array)->fslots[JSSLOT_ARRAY_COUNT] + 1) * 4))
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSScopeProperty) > 4 * sizeof(jsval));
|
||||
@ -312,11 +308,11 @@ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldlen, uint32 len)
|
||||
ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldsize, uint32 size)
|
||||
{
|
||||
jsval *slots, *newslots;
|
||||
|
||||
if (len == 0) {
|
||||
if (size == 0) {
|
||||
if (obj->dslots) {
|
||||
JS_free(cx, obj->dslots - 1);
|
||||
obj->dslots = NULL;
|
||||
@ -324,29 +320,29 @@ ResizeSlots(JSContext *cx, JSObject *obj, uint32 oldlen, uint32 len)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (len > ~(uint32)0 / sizeof(jsval)) {
|
||||
if (size > ~(uint32)0 / sizeof(jsval)) {
|
||||
js_ReportAllocationOverflow(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
slots = obj->dslots ? obj->dslots - 1 : NULL;
|
||||
newslots = (jsval *) JS_realloc(cx, slots, sizeof (jsval) * (len + 1));
|
||||
newslots = (jsval *) JS_realloc(cx, slots, sizeof (jsval) * (size + 1));
|
||||
if (!newslots)
|
||||
return JS_FALSE;
|
||||
|
||||
obj->dslots = newslots + 1;
|
||||
ARRAY_SET_DENSE_LENGTH(obj, len);
|
||||
js_SetDenseArrayCapacity(obj, size);
|
||||
|
||||
for (slots = obj->dslots + oldlen; slots < obj->dslots + len; slots++)
|
||||
for (slots = obj->dslots + oldsize; slots < obj->dslots + size; slots++)
|
||||
*slots = JSVAL_HOLE;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
EnsureLength(JSContext *cx, JSObject *obj, uint32 len)
|
||||
EnsureCapacity(JSContext *cx, JSObject *obj, uint32 len)
|
||||
{
|
||||
uint32 oldlen = ARRAY_DENSE_LENGTH(obj);
|
||||
uint32 oldlen = js_DenseArrayCapacity(obj);
|
||||
|
||||
if (len > oldlen) {
|
||||
return ResizeSlots(cx, obj, oldlen,
|
||||
@ -369,7 +365,7 @@ GetArrayElement(JSContext *cx, JSObject *obj, jsuint index, JSBool *hole,
|
||||
JSObject *obj2;
|
||||
JSProperty *prop;
|
||||
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj) && index < ARRAY_DENSE_LENGTH(obj) &&
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj) && index < js_DenseArrayCapacity(obj) &&
|
||||
(*vp = obj->dslots[index]) != JSVAL_HOLE) {
|
||||
*hole = JS_FALSE;
|
||||
return JS_TRUE;
|
||||
@ -412,7 +408,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsuint index, jsval v)
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
/* Predicted/prefeched code should favor the remains-dense case. */
|
||||
if (!INDEX_TOO_SPARSE(obj, index)) {
|
||||
if (!EnsureLength(cx, obj, index + 1))
|
||||
if (!EnsureCapacity(cx, obj, index + 1))
|
||||
return JS_FALSE;
|
||||
if (index >= (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] = index + 1;
|
||||
@ -443,7 +439,7 @@ DeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index)
|
||||
jsval junk;
|
||||
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
if (index < ARRAY_DENSE_LENGTH(obj)) {
|
||||
if (index < js_DenseArrayCapacity(obj)) {
|
||||
if (obj->dslots[index] != JSVAL_HOLE)
|
||||
obj->fslots[JSSLOT_ARRAY_COUNT]--;
|
||||
obj->dslots[index] = JSVAL_HOLE;
|
||||
@ -581,7 +577,7 @@ 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 = ARRAY_DENSE_LENGTH(obj);
|
||||
jsuint oldsize = js_DenseArrayCapacity(obj);
|
||||
if (oldsize >= newlen && !ResizeSlots(cx, obj, oldsize, newlen))
|
||||
return JS_FALSE;
|
||||
} else if (oldlen - newlen < (1 << 24)) {
|
||||
@ -640,13 +636,13 @@ array_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
return js_LookupProperty(cx, obj, id, objp, propp);
|
||||
|
||||
/*
|
||||
* We have only indexed properties up to DENSELEN (excepting holes), plus
|
||||
* We have only indexed properties up to capacity (excepting holes), plus
|
||||
* the length property. For all else, we delegate to the prototype.
|
||||
*/
|
||||
if (id != ATOM_TO_JSID(cx->runtime->atomState.lengthAtom) &&
|
||||
(!js_IdIsIndex(id, &i) ||
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] == 0 ||
|
||||
i >= ARRAY_DENSE_LENGTH(obj) ||
|
||||
i >= js_DenseArrayCapacity(obj) ||
|
||||
obj->dslots[i] == JSVAL_HOLE))
|
||||
{
|
||||
JSObject *proto = STOBJ_GET_PROTO(obj);
|
||||
@ -697,7 +693,7 @@ array_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
if (!OBJ_IS_DENSE_ARRAY(cx, obj))
|
||||
return js_GetProperty(cx, obj, id, vp);
|
||||
|
||||
if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || i >= ARRAY_DENSE_LENGTH(obj) ||
|
||||
if (!js_IdIsIndex(ID_TO_VALUE(id), &i) || i >= js_DenseArrayCapacity(obj) ||
|
||||
obj->dslots[i] == JSVAL_HOLE) {
|
||||
JSObject *obj2;
|
||||
JSProperty *prop;
|
||||
@ -783,7 +779,7 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
return js_SetProperty(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
if (!EnsureLength(cx, obj, i + 1))
|
||||
if (!EnsureCapacity(cx, obj, i + 1))
|
||||
return JS_FALSE;
|
||||
|
||||
if (i >= (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
|
||||
@ -801,8 +797,8 @@ js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
|
||||
|
||||
do {
|
||||
jsuint length = ARRAY_DENSE_LENGTH(obj);
|
||||
if ((jsuint)i < length) {
|
||||
jsuint capacity = js_DenseArrayCapacity(obj);
|
||||
if ((jsuint)i < capacity) {
|
||||
if (obj->dslots[i] == JSVAL_HOLE) {
|
||||
if (cx->runtime->anyArrayProtoHasElement)
|
||||
break;
|
||||
@ -870,7 +866,7 @@ array_deleteProperty(JSContext *cx, JSObject *obj, jsval id, jsval *rval)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (js_IdIsIndex(id, &i) && i < ARRAY_DENSE_LENGTH(obj) &&
|
||||
if (js_IdIsIndex(id, &i) && i < js_DenseArrayCapacity(obj) &&
|
||||
obj->dslots[i] != JSVAL_HOLE) {
|
||||
obj->fslots[JSSLOT_ARRAY_COUNT]--;
|
||||
obj->dslots[i] = JSVAL_HOLE;
|
||||
@ -945,34 +941,34 @@ static JSBool
|
||||
array_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
uint32 length, i;
|
||||
uint32 capacity, i;
|
||||
JSIndexIterState *ii;
|
||||
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
|
||||
length = ARRAY_DENSE_LENGTH(obj);
|
||||
capacity = js_DenseArrayCapacity(obj);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(obj->fslots[JSSLOT_ARRAY_COUNT]);
|
||||
ii = NULL;
|
||||
for (i = 0; i != length; ++i) {
|
||||
for (i = 0; i != capacity; ++i) {
|
||||
if (obj->dslots[i] == JSVAL_HOLE) {
|
||||
if (!ii) {
|
||||
ii = (JSIndexIterState *)
|
||||
JS_malloc(cx, offsetof(JSIndexIterState, holes) +
|
||||
JS_BITMAP_SIZE(length));
|
||||
JS_BITMAP_SIZE(capacity));
|
||||
if (!ii)
|
||||
return JS_FALSE;
|
||||
ii->hasHoles = JS_TRUE;
|
||||
memset(ii->holes, 0, JS_BITMAP_SIZE(length));
|
||||
memset(ii->holes, 0, JS_BITMAP_SIZE(capacity));
|
||||
}
|
||||
JS_SET_BIT(ii->holes, i);
|
||||
}
|
||||
}
|
||||
if (!ii) {
|
||||
/* Array has no holes. */
|
||||
if (length <= PACKED_UINT_PAIR_MASK) {
|
||||
*statep = UINT_PAIR_TO_BOOLEAN_JSVAL(0, length);
|
||||
if (capacity <= PACKED_UINT_PAIR_MASK) {
|
||||
*statep = UINT_PAIR_TO_BOOLEAN_JSVAL(0, capacity);
|
||||
break;
|
||||
}
|
||||
ii = (JSIndexIterState *)
|
||||
@ -982,17 +978,17 @@ array_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
ii->hasHoles = JS_FALSE;
|
||||
}
|
||||
ii->index = 0;
|
||||
ii->length = length;
|
||||
ii->length = capacity;
|
||||
*statep = (jsval) ii | INDEX_ITER_TAG;
|
||||
JS_ASSERT(*statep & JSVAL_INT);
|
||||
break;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
if (JSVAL_TAG(*statep) == JSVAL_BOOLEAN) {
|
||||
BOOLEAN_JSVAL_TO_UINT_PAIR(*statep, i, length);
|
||||
if (i != length) {
|
||||
BOOLEAN_JSVAL_TO_UINT_PAIR(*statep, i, capacity);
|
||||
if (i != capacity) {
|
||||
*idp = INT_TO_JSID(i);
|
||||
*statep = UINT_PAIR_TO_BOOLEAN_JSVAL(i + 1, length);
|
||||
*statep = UINT_PAIR_TO_BOOLEAN_JSVAL(i + 1, capacity);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -1055,14 +1051,14 @@ array_finalize(JSContext *cx, JSObject *obj)
|
||||
static void
|
||||
array_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
uint32 length;
|
||||
uint32 capacity;
|
||||
size_t i;
|
||||
jsval v;
|
||||
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
|
||||
|
||||
length = ARRAY_DENSE_LENGTH(obj);
|
||||
for (i = 0; i < length; i++) {
|
||||
capacity = js_DenseArrayCapacity(obj);
|
||||
for (i = 0; i < capacity; i++) {
|
||||
v = obj->dslots[i];
|
||||
if (JSVAL_IS_TRACEABLE(v)) {
|
||||
JS_SET_TRACING_INDEX(trc, "array_dslots", i);
|
||||
@ -1153,7 +1149,7 @@ JSBool
|
||||
js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObjectMap *map, *oldmap;
|
||||
uint32 i, length;
|
||||
uint32 i, capacity;
|
||||
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_ArrayClass);
|
||||
|
||||
@ -1163,16 +1159,16 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
||||
if (!map)
|
||||
return JS_FALSE;
|
||||
|
||||
length = ARRAY_DENSE_LENGTH(obj);
|
||||
if (length) {
|
||||
capacity = js_DenseArrayCapacity(obj);
|
||||
if (capacity) {
|
||||
map->freeslot = STOBJ_NSLOTS(obj) + JS_INITIAL_NSLOTS;
|
||||
obj->dslots[-1] = JS_INITIAL_NSLOTS + length;
|
||||
obj->dslots[-1] = JS_INITIAL_NSLOTS + capacity;
|
||||
} else {
|
||||
map->freeslot = STOBJ_NSLOTS(obj);
|
||||
}
|
||||
|
||||
/* Create new properties pointing to existing values in dslots */
|
||||
for (i = 0; i < length; i++) {
|
||||
for (i = 0; i < capacity; i++) {
|
||||
jsid id;
|
||||
JSScopeProperty *sprop;
|
||||
|
||||
@ -1197,7 +1193,7 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
||||
* we can tell when only named properties have been added to a dense array
|
||||
* to make it slow-but-not-sparse.
|
||||
*/
|
||||
length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
uint32 length = obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
obj->fslots[JSSLOT_ARRAY_COUNT] = INT_FITS_IN_JSVAL(length)
|
||||
? INT_TO_JSVAL(length)
|
||||
: JSVAL_VOID;
|
||||
@ -1488,7 +1484,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint end,
|
||||
jsval *vector)
|
||||
{
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
if (!EnsureLength(cx, obj, end))
|
||||
if (!EnsureCapacity(cx, obj, end))
|
||||
return JS_FALSE;
|
||||
|
||||
if (end > (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH])
|
||||
@ -1516,7 +1512,7 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector,
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] = length;
|
||||
|
||||
if (vector) {
|
||||
if (!EnsureLength(cx, obj, length))
|
||||
if (!EnsureCapacity(cx, obj, length))
|
||||
return JS_FALSE;
|
||||
|
||||
jsuint count = length;
|
||||
@ -2126,7 +2122,7 @@ array_push1_dense(JSContext* cx, JSObject* obj, jsval v, jsval *rval)
|
||||
return array_push_slowly(cx, obj, 1, &v, rval);
|
||||
}
|
||||
|
||||
if (!EnsureLength(cx, obj, length + 1))
|
||||
if (!EnsureCapacity(cx, obj, length + 1))
|
||||
return JS_FALSE;
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] = length + 1;
|
||||
|
||||
@ -2141,9 +2137,9 @@ js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
|
||||
uint32_t length = (uint32_t) obj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
JS_ASSERT(length <= ARRAY_DENSE_LENGTH(obj));
|
||||
JS_ASSERT(length <= js_DenseArrayCapacity(obj));
|
||||
|
||||
if (length == ARRAY_DENSE_LENGTH(obj)) {
|
||||
if (length == js_DenseArrayCapacity(obj)) {
|
||||
if (length >= ARRAY_INIT_LIMIT) {
|
||||
JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_ARRAY_INIT_TOO_BIG);
|
||||
@ -2497,15 +2493,15 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
|
||||
aobj = JS_THIS_OBJECT(cx, vp);
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, aobj)) {
|
||||
/*
|
||||
* Clone aobj but pass the minimum of its length and capacity (aka
|
||||
* "dense length"), to handle a = [1,2,3]; a.length = 10000 "dense"
|
||||
* cases efficiently. In such a case we'll pass 8 (not 3) due to the
|
||||
* ARRAY_GROWBY over-allocation policy, which will cause nobj to be
|
||||
* over-allocated to 16. But in the normal case where length is <=
|
||||
* capacity, nobj and aobj will have the same dense length.
|
||||
* Clone aobj but pass the minimum of its length and capacity, to handle
|
||||
* a = [1,2,3]; a.length = 10000 "dense" cases efficiently. In such a
|
||||
* case we'll pass 8 (not 3) due to the ARRAY_GROWBY over-allocation
|
||||
* policy, which will cause nobj to be over-allocated to 16. But in the
|
||||
* normal case where length is <= capacity, nobj and aobj will have the
|
||||
* same capacity.
|
||||
*/
|
||||
length = aobj->fslots[JSSLOT_ARRAY_LENGTH];
|
||||
jsuint capacity = ARRAY_DENSE_LENGTH(aobj);
|
||||
jsuint capacity = js_DenseArrayCapacity(aobj);
|
||||
nobj = js_NewArrayObject(cx, JS_MIN(length, capacity), aobj->dslots,
|
||||
aobj->fslots[JSSLOT_ARRAY_COUNT] !=
|
||||
(jsval) length);
|
||||
@ -2637,7 +2633,7 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (begin > end)
|
||||
begin = end;
|
||||
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj) && end <= ARRAY_DENSE_LENGTH(obj)) {
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj) && end <= js_DenseArrayCapacity(obj)) {
|
||||
nobj = js_NewArrayObject(cx, end - begin, obj->dslots + begin,
|
||||
obj->fslots[JSSLOT_ARRAY_COUNT] !=
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH]);
|
||||
@ -3141,7 +3137,7 @@ js_NewUninitializedArray(JSContext* cx, JSObject* proto, uint32 len)
|
||||
jsval* newslots = (jsval*) JS_malloc(cx, sizeof (jsval) * (len + 1)); \
|
||||
if (newslots) { \
|
||||
obj->dslots = newslots + 1; \
|
||||
ARRAY_SET_DENSE_LENGTH(obj, len); \
|
||||
js_SetDenseArrayCapacity(obj, len); \
|
||||
{newslots_code} \
|
||||
while (++newslots < obj->dslots + len) \
|
||||
*newslots = JSVAL_HOLE; \
|
||||
@ -3232,9 +3228,9 @@ js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
OBJ_IS_DENSE_ARRAY(cx, array) ? "dense" : "sparse",
|
||||
array->fslots[JSSLOT_ARRAY_LENGTH]);
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, array)) {
|
||||
fprintf(stderr, ", count %lu, denselen %lu",
|
||||
fprintf(stderr, ", count %lu, capacity %lu",
|
||||
array->fslots[JSSLOT_ARRAY_COUNT],
|
||||
ARRAY_DENSE_LENGTH(array));
|
||||
js_DenseArrayCapacity(array));
|
||||
}
|
||||
fputs(")\n", stderr);
|
||||
JS_free(cx, bytes);
|
||||
|
@ -44,6 +44,7 @@
|
||||
*/
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
@ -78,12 +79,20 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj);
|
||||
#define JSSLOT_ARRAY_COUNT (JSSLOT_ARRAY_LENGTH + 1)
|
||||
#define JSSLOT_ARRAY_LOOKUP_HOLDER (JSSLOT_ARRAY_COUNT + 1)
|
||||
|
||||
#define ARRAY_DENSE_LENGTH(obj) \
|
||||
(JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj)), \
|
||||
(obj)->dslots ? (uint32)(obj)->dslots[-1] : 0)
|
||||
static JS_INLINE uint32
|
||||
js_DenseArrayCapacity(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj));
|
||||
return obj->dslots ? (uint32) obj->dslots[-1] : 0;
|
||||
}
|
||||
|
||||
#define ARRAY_SET_DENSE_LENGTH(obj, max) \
|
||||
(JS_ASSERT((obj)->dslots), (obj)->dslots[-1] = (jsval)(max))
|
||||
static JS_INLINE void
|
||||
js_SetDenseArrayCapacity(JSObject *obj, uint32 capacity)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj));
|
||||
JS_ASSERT(obj->dslots);
|
||||
obj->dslots[-1] = (jsval) capacity;
|
||||
}
|
||||
|
||||
#define ARRAY_GROWBY 8
|
||||
|
||||
|
@ -4671,7 +4671,7 @@ js_Interpret(JSContext *cx)
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
jsuint length;
|
||||
|
||||
length = ARRAY_DENSE_LENGTH(obj);
|
||||
length = js_DenseArrayCapacity(obj);
|
||||
i = JSVAL_TO_INT(rval);
|
||||
if ((jsuint)i < length &&
|
||||
i < obj->fslots[JSSLOT_ARRAY_LENGTH]) {
|
||||
@ -4724,7 +4724,7 @@ js_Interpret(JSContext *cx)
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj) && JSID_IS_INT(id)) {
|
||||
jsuint length;
|
||||
|
||||
length = ARRAY_DENSE_LENGTH(obj);
|
||||
length = js_DenseArrayCapacity(obj);
|
||||
i = JSID_TO_INT(id);
|
||||
if ((jsuint)i < length) {
|
||||
if (obj->dslots[i] == JSVAL_HOLE) {
|
||||
|
@ -5743,7 +5743,7 @@ js_DumpObject(JSObject *obj)
|
||||
/* OBJ_IS_DENSE_ARRAY ignores the cx argument. */
|
||||
if (OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj)) {
|
||||
slots = JS_MIN((jsuint) obj->fslots[JSSLOT_ARRAY_LENGTH],
|
||||
ARRAY_DENSE_LENGTH(obj));
|
||||
js_DenseArrayCapacity(obj));
|
||||
fprintf(stderr, "elements\n");
|
||||
for (i = 0; i < slots; i++) {
|
||||
fprintf(stderr, " %3d: ", i);
|
||||
|
@ -5929,9 +5929,9 @@ JS_REQUIRES_STACK bool
|
||||
TraceRecorder::guardDenseArrayIndex(JSObject* obj, jsint idx, LIns* obj_ins,
|
||||
LIns* dslots_ins, LIns* idx_ins, ExitType exitType)
|
||||
{
|
||||
jsuint length = ARRAY_DENSE_LENGTH(obj);
|
||||
jsuint capacity = js_DenseArrayCapacity(obj);
|
||||
|
||||
bool cond = (jsuint(idx) < jsuint(obj->fslots[JSSLOT_ARRAY_LENGTH]) && jsuint(idx) < length);
|
||||
bool cond = (jsuint(idx) < jsuint(obj->fslots[JSSLOT_ARRAY_LENGTH]) && jsuint(idx) < capacity);
|
||||
if (cond) {
|
||||
/* Guard array length */
|
||||
LIns* exit = guard(true,
|
||||
@ -7156,7 +7156,7 @@ TraceRecorder::record_JSOP_GETELEM()
|
||||
idx = ID_TO_VALUE(id);
|
||||
jsuint index;
|
||||
if (js_IdIsIndex(idx, &index) && guardDenseArray(obj, obj_ins, BRANCH_EXIT)) {
|
||||
v = (index >= ARRAY_DENSE_LENGTH(obj)) ? JSVAL_HOLE : obj->dslots[index];
|
||||
v = (index >= js_DenseArrayCapacity(obj)) ? JSVAL_HOLE : obj->dslots[index];
|
||||
if (v == JSVAL_HOLE)
|
||||
ABORT_TRACE("can't see through hole in dense array");
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user