mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 04:27:37 +00:00
Bug 562251 - JSSLOT_ARRAY_COUNT isn't used for slow arrays. r=brendan.
This commit is contained in:
parent
e54b6530d8
commit
2678ca9628
@ -50,7 +50,7 @@
|
||||
* - the array's length property as a uint32, accessible with
|
||||
* {get,set}ArrayLength().
|
||||
* - the number of indices that are filled (non-holes), accessible with
|
||||
* {get,set}ArrayCount().
|
||||
* {get,set}DenseArrayCount().
|
||||
* - the number of element slots (capacity), gettable with
|
||||
* getDenseArrayCapacity().
|
||||
*
|
||||
@ -125,7 +125,7 @@ INDEX_TOO_BIG(jsuint index)
|
||||
#define INDEX_TOO_SPARSE(array, index) \
|
||||
(INDEX_TOO_BIG(index) || \
|
||||
((index) > array->getDenseArrayCapacity() && (index) >= MIN_SPARSE_INDEX && \
|
||||
(index) > ((array)->getArrayCount() + 1) * 4))
|
||||
(index) > ((array)->getDenseArrayCount() + 1) * 4))
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSScopeProperty) > 4 * sizeof(jsval));
|
||||
|
||||
@ -499,7 +499,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, jsval v)
|
||||
if (idx >= obj->getArrayLength())
|
||||
obj->setArrayLength(idx + 1);
|
||||
if (obj->getDenseArrayElement(idx) == JSVAL_HOLE)
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(idx, v);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -527,7 +527,7 @@ DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index)
|
||||
jsuint idx = jsuint(index);
|
||||
if (!INDEX_TOO_SPARSE(obj, idx) && idx < obj->getDenseArrayCapacity()) {
|
||||
if (obj->getDenseArrayElement(idx) != JSVAL_HOLE)
|
||||
obj->decArrayCountBy(1);
|
||||
obj->decDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(idx, JSVAL_HOLE);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -869,7 +869,7 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
if (i >= obj->getArrayLength())
|
||||
obj->setArrayLength(i + 1);
|
||||
if (obj->getDenseArrayElement(i) == JSVAL_HOLE)
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(i, *vp);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -928,7 +928,7 @@ dense_grow(JSContext* cx, JSObject* obj, jsint i, jsval v)
|
||||
|
||||
if (u >= obj->getArrayLength())
|
||||
obj->setArrayLength(u + 1);
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
}
|
||||
|
||||
obj->setDenseArrayElement(u, v);
|
||||
@ -1038,7 +1038,7 @@ array_deleteProperty(JSContext *cx, JSObject *obj, jsval id, jsval *rval)
|
||||
|
||||
if (js_IdIsIndex(id, &i) && i < obj->getDenseArrayCapacity() &&
|
||||
obj->getDenseArrayElement(i) != JSVAL_HOLE) {
|
||||
obj->decArrayCountBy(1);
|
||||
obj->decDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(i, JSVAL_HOLE);
|
||||
}
|
||||
|
||||
@ -1119,7 +1119,7 @@ array_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
capacity = obj->getDenseArrayCapacity();
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(obj->getArrayCount());
|
||||
*idp = INT_TO_JSVAL(obj->getDenseArrayCount());
|
||||
ii = NULL;
|
||||
for (i = 0; i != capacity; ++i) {
|
||||
if (obj->getDenseArrayElement(i) == JSVAL_HOLE) {
|
||||
@ -1666,19 +1666,19 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, jsva
|
||||
if (obj->getDenseArrayElement(start + i) != JSVAL_HOLE)
|
||||
valueCount++;
|
||||
}
|
||||
JS_ASSERT(obj->getArrayCount() >= valueCount);
|
||||
obj->decArrayCountBy(valueCount);
|
||||
JS_ASSERT(obj->getDenseArrayCount() >= valueCount);
|
||||
obj->decDenseArrayCountBy(valueCount);
|
||||
}
|
||||
memcpy(obj->getDenseArrayElements() + start, vector, sizeof(jsval) * count);
|
||||
if (vectorType == SourceVectorAllValues) {
|
||||
obj->incArrayCountBy(count);
|
||||
obj->incDenseArrayCountBy(count);
|
||||
} else {
|
||||
jsuint valueCount = 0;
|
||||
for (jsuint i = 0; i < count; i++) {
|
||||
if (obj->getDenseArrayElement(start + i) != JSVAL_HOLE)
|
||||
valueCount++;
|
||||
}
|
||||
obj->incArrayCountBy(valueCount);
|
||||
obj->incDenseArrayCountBy(valueCount);
|
||||
}
|
||||
JS_ASSERT_IF(count != 0, obj->getDenseArrayElement(newlen - 1) != JSVAL_HOLE);
|
||||
return JS_TRUE;
|
||||
@ -1728,6 +1728,7 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const jsval *vector
|
||||
obj->setArrayLength(length);
|
||||
|
||||
if (vector) {
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
if (!obj->ensureDenseArrayElements(cx, length))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1741,9 +1742,11 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const jsval *vector
|
||||
obj->setDenseArrayElement(i, vector[i]);
|
||||
}
|
||||
}
|
||||
obj->setArrayCount(count);
|
||||
obj->setDenseArrayCount(count);
|
||||
} else {
|
||||
obj->setArrayCount(0);
|
||||
if (obj->isDenseArray()) {
|
||||
obj->setDenseArrayCount(0);
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -2360,7 +2363,7 @@ array_push1_dense(JSContext* cx, JSObject* obj, jsval v, jsval *rval)
|
||||
obj->setArrayLength(length + 1);
|
||||
|
||||
JS_ASSERT(obj->getDenseArrayElement(length) == JSVAL_HOLE);
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(length, v);
|
||||
return IndexToValue(cx, obj->getArrayLength(), rval);
|
||||
}
|
||||
@ -2383,7 +2386,7 @@ js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v)
|
||||
return JS_FALSE;
|
||||
}
|
||||
obj->setArrayLength(length + 1);
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(length, v);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -2512,7 +2515,7 @@ array_shift(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (*vp == JSVAL_HOLE)
|
||||
*vp = JSVAL_VOID;
|
||||
else
|
||||
obj->decArrayCountBy(1);
|
||||
obj->decDenseArrayCountBy(1);
|
||||
jsval *elems = obj->getDenseArrayElements();
|
||||
memmove(elems, elems + 1, length * sizeof(jsval));
|
||||
obj->setDenseArrayElement(length, JSVAL_HOLE);
|
||||
@ -2666,7 +2669,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
|
||||
!js_PrototypeHasIndexedProperties(cx, obj2) &&
|
||||
end <= obj->getDenseArrayCapacity()) {
|
||||
if (!InitArrayObject(cx, obj2, count, obj->getDenseArrayElements() + begin,
|
||||
obj->getArrayCount() != obj->getArrayLength())) {
|
||||
obj->getDenseArrayCount() != obj->getArrayLength())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
@ -2700,7 +2703,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
|
||||
jsval srcval = obj->getDenseArrayElement(last);
|
||||
jsval dest = obj->getDenseArrayElement(last + delta);
|
||||
if (dest == JSVAL_HOLE && srcval != JSVAL_HOLE)
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(last + delta, srcval);
|
||||
}
|
||||
obj->setArrayLength(obj->getArrayLength() + delta);
|
||||
@ -2724,7 +2727,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
|
||||
jsval srcval = obj->getDenseArrayElement(last);
|
||||
jsval dest = obj->getDenseArrayElement(last - delta);
|
||||
if (dest == JSVAL_HOLE && srcval != JSVAL_HOLE)
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(last - delta, srcval);
|
||||
}
|
||||
} else {
|
||||
@ -2778,7 +2781,7 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
|
||||
length = aobj->getArrayLength();
|
||||
jsuint capacity = aobj->getDenseArrayCapacity();
|
||||
nobj = js_NewArrayObject(cx, JS_MIN(length, capacity), aobj->getDenseArrayElements(),
|
||||
aobj->getArrayCount() != length);
|
||||
aobj->getDenseArrayCount() != length);
|
||||
if (!nobj)
|
||||
return JS_FALSE;
|
||||
nobj->setArrayLength(length);
|
||||
@ -2893,7 +2896,7 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (obj->isDenseArray() && end <= obj->getDenseArrayCapacity() &&
|
||||
!js_PrototypeHasIndexedProperties(cx, obj)) {
|
||||
nobj = js_NewArrayObject(cx, end - begin, obj->getDenseArrayElements() + begin,
|
||||
obj->getArrayCount() != obj->getArrayLength());
|
||||
obj->getDenseArrayCount() != obj->getArrayLength());
|
||||
if (!nobj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(nobj);
|
||||
@ -3353,7 +3356,7 @@ js_NewEmptyArray(JSContext* cx, JSObject* proto)
|
||||
|
||||
obj->init(&js_ArrayClass, proto, proto->getParent(), JSVAL_NULL);
|
||||
obj->setArrayLength(0);
|
||||
obj->setArrayCount(0);
|
||||
obj->setDenseArrayCount(0);
|
||||
return obj;
|
||||
}
|
||||
#ifdef JS_TRACER
|
||||
@ -3462,7 +3465,7 @@ js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
array->getArrayLength());
|
||||
if (array->isDenseArray()) {
|
||||
fprintf(stderr, ", count %lu, capacity %lu",
|
||||
array->getArrayCount(),
|
||||
array->getDenseArrayCount(),
|
||||
array->getDenseArrayCapacity());
|
||||
}
|
||||
fputs(")\n", stderr);
|
||||
@ -3546,7 +3549,7 @@ js_NewArrayObjectWithCapacity(JSContext *cx, jsuint capacity, jsval **vector)
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
obj->setArrayCount(capacity);
|
||||
obj->setDenseArrayCount(capacity);
|
||||
*vector = obj->getDenseArrayElements();
|
||||
return obj;
|
||||
}
|
||||
|
@ -2020,7 +2020,7 @@ obj_keys(JSContext *cx, uintN argc, jsval *vp)
|
||||
}
|
||||
|
||||
JS_ASSERT(len <= UINT32_MAX);
|
||||
aobj->setArrayCount(len);
|
||||
aobj->setDenseArrayCount(len);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -405,9 +405,11 @@ struct JSObject {
|
||||
*/
|
||||
|
||||
private:
|
||||
// Used by dense and slow arrays.
|
||||
static const uint32 JSSLOT_ARRAY_LENGTH = JSSLOT_PRIVATE;
|
||||
static const uint32 JSSLOT_ARRAY_COUNT = JSSLOT_PRIVATE + 1;
|
||||
static const uint32 JSSLOT_ARRAY_UNUSED = JSSLOT_PRIVATE + 2;
|
||||
|
||||
// Used only by dense arrays.
|
||||
static const uint32 JSSLOT_DENSE_ARRAY_COUNT = JSSLOT_PRIVATE + 1;
|
||||
|
||||
// This assertion must remain true; see comment in js_MakeArraySlow().
|
||||
// (Nb: This method is never called, it just contains a static assertion.
|
||||
@ -418,11 +420,11 @@ struct JSObject {
|
||||
inline uint32 getArrayLength() const;
|
||||
inline void setArrayLength(uint32 length);
|
||||
|
||||
inline uint32 getArrayCount() const;
|
||||
inline uint32 getDenseArrayCount() const;
|
||||
inline void voidDenseArrayCount();
|
||||
inline void setArrayCount(uint32 count);
|
||||
inline void incArrayCountBy(uint32 posDelta);
|
||||
inline void decArrayCountBy(uint32 negDelta);
|
||||
inline void setDenseArrayCount(uint32 count);
|
||||
inline void incDenseArrayCountBy(uint32 posDelta);
|
||||
inline void decDenseArrayCountBy(uint32 negDelta);
|
||||
|
||||
inline uint32 getDenseArrayCapacity() const;
|
||||
inline void setDenseArrayCapacity(uint32 capacity); // XXX: bug 558263 will remove this
|
||||
|
@ -130,38 +130,38 @@ JSObject::setArrayLength(uint32 length)
|
||||
}
|
||||
|
||||
inline uint32
|
||||
JSObject::getArrayCount() const
|
||||
JSObject::getDenseArrayCount() const
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
return uint32(fslots[JSSLOT_ARRAY_COUNT]);
|
||||
JS_ASSERT(isDenseArray());
|
||||
return uint32(fslots[JSSLOT_DENSE_ARRAY_COUNT]);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setArrayCount(uint32 count)
|
||||
JSObject::setDenseArrayCount(uint32 count)
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
fslots[JSSLOT_ARRAY_COUNT] = count;
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] = count;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::voidDenseArrayCount()
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_ARRAY_COUNT] = JSVAL_VOID;
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] = JSVAL_VOID;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::incArrayCountBy(uint32 posDelta)
|
||||
JSObject::incDenseArrayCountBy(uint32 posDelta)
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
fslots[JSSLOT_ARRAY_COUNT] += posDelta;
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] += posDelta;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::decArrayCountBy(uint32 negDelta)
|
||||
JSObject::decDenseArrayCountBy(uint32 negDelta)
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
fslots[JSSLOT_ARRAY_COUNT] -= negDelta;
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] -= negDelta;
|
||||
}
|
||||
|
||||
inline uint32
|
||||
|
@ -1929,7 +1929,7 @@ BEGIN_CASE(JSOP_SETELEM)
|
||||
break;
|
||||
if ((jsuint)i >= obj->getArrayLength())
|
||||
obj->setArrayLength(i + 1);
|
||||
obj->incArrayCountBy(1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
}
|
||||
obj->setDenseArrayElement(i, rval);
|
||||
goto end_setelem;
|
||||
|
@ -10546,7 +10546,7 @@ TraceRecorder::newArray(JSObject* ctor, uint32 argc, jsval* argv, jsval* rval)
|
||||
}
|
||||
|
||||
if (argc > 0)
|
||||
stobj_set_fslot(arr_ins, JSObject::JSSLOT_ARRAY_COUNT, INS_CONST(argc));
|
||||
stobj_set_fslot(arr_ins, JSObject::JSSLOT_DENSE_ARRAY_COUNT, INS_CONST(argc));
|
||||
}
|
||||
|
||||
set(rval, arr_ins);
|
||||
@ -15221,7 +15221,7 @@ TraceRecorder::record_JSOP_NEWARRAY()
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
stobj_set_fslot(v_ins, JSObject::JSSLOT_ARRAY_COUNT, INS_CONST(count));
|
||||
stobj_set_fslot(v_ins, JSObject::JSSLOT_DENSE_ARRAY_COUNT, INS_CONST(count));
|
||||
|
||||
stack(-int(len), v_ins);
|
||||
return ARECORD_CONTINUE;
|
||||
|
Loading…
Reference in New Issue
Block a user