mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 04:27:37 +00:00
Bug 562571 - TM: don't have two bounds checks for array getelem. r=brendan.
This commit is contained in:
parent
d3873c3d67
commit
a27cd4fbaf
@ -47,12 +47,17 @@
|
||||
* &js_ArrayClass, and can then directly manipulate the slots for efficiency.
|
||||
*
|
||||
* We track these pieces of metadata for arrays in dense mode:
|
||||
* - the array's length property as a uint32, accessible with
|
||||
* {get,set}ArrayLength().
|
||||
* - the number of indices that are filled (non-holes), accessible with
|
||||
* - The array's length property as a uint32, accessible with
|
||||
* getArrayLength(), setDenseArrayLength().
|
||||
* - The number of indices that are filled (non-holes), accessible with
|
||||
* {get,set}DenseArrayCount().
|
||||
* - the number of element slots (capacity), gettable with
|
||||
* - The number of element slots (capacity), gettable with
|
||||
* getDenseArrayCapacity().
|
||||
* - The minimum of length and capacity (minLenCap). There are no explicit
|
||||
* setters, it's updated automatically by setDenseArrayLength() and
|
||||
* setDenseArrayCapacity(). There are also no explicit getters, the only
|
||||
* user is TraceRecorder which can access it directly because it's a
|
||||
* friend.
|
||||
*
|
||||
* In dense mode, holes in the array are represented by JSVAL_HOLE. The final
|
||||
* slot in fslots is unused.
|
||||
@ -339,7 +344,7 @@ JSObject::resizeDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap,
|
||||
return false;
|
||||
|
||||
dslots = newslots + 1;
|
||||
dslots[-1] = newcap;
|
||||
setDenseArrayCapacity(newcap);
|
||||
|
||||
if (initializeAllSlots) {
|
||||
for (uint32 i = oldcap; i < newcap; i++)
|
||||
@ -497,7 +502,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, jsval v)
|
||||
if (!obj->ensureDenseArrayElements(cx, idx + 1))
|
||||
return JS_FALSE;
|
||||
if (idx >= obj->getArrayLength())
|
||||
obj->setArrayLength(idx + 1);
|
||||
obj->setDenseArrayLength(idx + 1);
|
||||
if (obj->getDenseArrayElement(idx) == JSVAL_HOLE)
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(idx, v);
|
||||
@ -647,7 +652,10 @@ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return false;
|
||||
|
||||
if (oldlen < newlen) {
|
||||
obj->setArrayLength(newlen);
|
||||
if (obj->isDenseArray())
|
||||
obj->setDenseArrayLength(newlen);
|
||||
else
|
||||
obj->setSlowArrayLength(newlen);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -656,12 +664,14 @@ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
jsuint capacity = obj->getDenseArrayCapacity();
|
||||
if (capacity > newlen && !obj->resizeDenseArrayElements(cx, capacity, newlen))
|
||||
return false;
|
||||
obj->setDenseArrayLength(newlen);
|
||||
} else if (oldlen - newlen < (1 << 24)) {
|
||||
do {
|
||||
--oldlen;
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeleteArrayElement(cx, obj, oldlen))
|
||||
return false;
|
||||
} while (oldlen != newlen);
|
||||
obj->setSlowArrayLength(newlen);
|
||||
} else {
|
||||
/*
|
||||
* We are going to remove a lot of indexes in a presumably sparse
|
||||
@ -688,9 +698,9 @@ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
obj->setSlowArrayLength(newlen);
|
||||
}
|
||||
|
||||
obj->setArrayLength(newlen);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -812,7 +822,7 @@ slowarray_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_TRUE;
|
||||
length = obj->getArrayLength();
|
||||
if (index >= length)
|
||||
obj->setArrayLength(index + 1);
|
||||
obj->setSlowArrayLength(index + 1);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -867,7 +877,7 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
|
||||
if (i >= obj->getArrayLength())
|
||||
obj->setArrayLength(i + 1);
|
||||
obj->setDenseArrayLength(i + 1);
|
||||
if (obj->getDenseArrayElement(i) == JSVAL_HOLE)
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(i, *vp);
|
||||
@ -927,7 +937,7 @@ dense_grow(JSContext* cx, JSObject* obj, jsint i, jsval v)
|
||||
return JS_FALSE;
|
||||
|
||||
if (u >= obj->getArrayLength())
|
||||
obj->setArrayLength(u + 1);
|
||||
obj->setDenseArrayLength(u + 1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
}
|
||||
|
||||
@ -1263,7 +1273,8 @@ JSClass js_ArrayClass = {
|
||||
"Array",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
|
||||
JSCLASS_NEW_ENUMERATE,
|
||||
JSCLASS_NEW_ENUMERATE |
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, js_TryValueOf, array_finalize,
|
||||
array_getObjectOps, NULL, NULL, NULL,
|
||||
@ -1286,7 +1297,7 @@ JSClass js_SlowArrayClass = {
|
||||
JSBool
|
||||
js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_ArrayClass);
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
|
||||
/*
|
||||
* Create a native scope. All slow arrays other than Array.prototype get
|
||||
@ -1337,13 +1348,13 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* Render our formerly-reserved count property GC-safe. We do not need to
|
||||
* make the length slot GC-safe because it is the private slot (this is
|
||||
* statically asserted within JSObject) where the implementation can store
|
||||
* an arbitrary value.
|
||||
* Render our formerly-reserved non-private properties GC-safe. We do not
|
||||
* need to make the length slot GC-safe because it is the private slot
|
||||
* (this is statically asserted within JSObject) where the implementation
|
||||
* can store an arbitrary value.
|
||||
*/
|
||||
JS_ASSERT(js_SlowArrayClass.flags & JSCLASS_HAS_PRIVATE);
|
||||
obj->voidDenseArrayCount();
|
||||
obj->voidDenseOnlyArraySlots();
|
||||
|
||||
/* Make sure we preserve any flags borrowing bits in classword. */
|
||||
obj->classword ^= (jsuword) &js_ArrayClass;
|
||||
@ -1657,7 +1668,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, jsva
|
||||
return JS_FALSE;
|
||||
|
||||
if (newlen > obj->getArrayLength())
|
||||
obj->setArrayLength(newlen);
|
||||
obj->setDenseArrayLength(newlen);
|
||||
|
||||
JS_ASSERT(count < size_t(-1) / sizeof(jsval));
|
||||
if (targetType == TargetElementsMayContainValues) {
|
||||
@ -1725,10 +1736,9 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const jsval *vector
|
||||
{
|
||||
JS_ASSERT(obj->isArray());
|
||||
|
||||
obj->setArrayLength(length);
|
||||
|
||||
if (vector) {
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
obj->setDenseArrayLength(length);
|
||||
if (!obj->ensureDenseArrayElements(cx, length))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1745,7 +1755,10 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const jsval *vector
|
||||
obj->setDenseArrayCount(count);
|
||||
} else {
|
||||
if (obj->isDenseArray()) {
|
||||
obj->setDenseArrayLength(length);
|
||||
obj->setDenseArrayCount(0);
|
||||
} else {
|
||||
obj->setSlowArrayLength(length);
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
@ -2360,7 +2373,7 @@ array_push1_dense(JSContext* cx, JSObject* obj, jsval v, jsval *rval)
|
||||
|
||||
if (!obj->ensureDenseArrayElements(cx, length + 1))
|
||||
return JS_FALSE;
|
||||
obj->setArrayLength(length + 1);
|
||||
obj->setDenseArrayLength(length + 1);
|
||||
|
||||
JS_ASSERT(obj->getDenseArrayElement(length) == JSVAL_HOLE);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
@ -2385,7 +2398,7 @@ js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v)
|
||||
if (!obj->ensureDenseArrayElements(cx, length + 1))
|
||||
return JS_FALSE;
|
||||
}
|
||||
obj->setArrayLength(length + 1);
|
||||
obj->setDenseArrayLength(length + 1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(length, v);
|
||||
return JS_TRUE;
|
||||
@ -2461,7 +2474,7 @@ array_pop_dense(JSContext *cx, JSObject* obj, jsval *vp)
|
||||
return JS_FALSE;
|
||||
if (!hole && !DeleteArrayElement(cx, obj, index))
|
||||
return JS_FALSE;
|
||||
obj->setArrayLength(index);
|
||||
obj->setDenseArrayLength(index);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -2519,7 +2532,7 @@ array_shift(JSContext *cx, uintN argc, jsval *vp)
|
||||
jsval *elems = obj->getDenseArrayElements();
|
||||
memmove(elems, elems + 1, length * sizeof(jsval));
|
||||
obj->setDenseArrayElement(length, JSVAL_HOLE);
|
||||
obj->setArrayLength(length);
|
||||
obj->setDenseArrayLength(length);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -2706,7 +2719,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
|
||||
obj->incDenseArrayCountBy(1);
|
||||
obj->setDenseArrayElement(last + delta, srcval);
|
||||
}
|
||||
obj->setArrayLength(obj->getArrayLength() + delta);
|
||||
obj->setDenseArrayLength(obj->getArrayLength() + delta);
|
||||
} else {
|
||||
/* (uint) end could be 0, so we can't use a vanilla >= test. */
|
||||
while (last-- > end) {
|
||||
@ -2784,7 +2797,7 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
|
||||
aobj->getDenseArrayCount() != length);
|
||||
if (!nobj)
|
||||
return JS_FALSE;
|
||||
nobj->setArrayLength(length);
|
||||
nobj->setDenseArrayLength(length);
|
||||
*vp = OBJECT_TO_JSVAL(nobj);
|
||||
if (argc == 0)
|
||||
return JS_TRUE;
|
||||
@ -3355,7 +3368,7 @@ js_NewEmptyArray(JSContext* cx, JSObject* proto)
|
||||
obj->map = const_cast<JSObjectMap *>(&SharedArrayMap);
|
||||
|
||||
obj->init(&js_ArrayClass, proto, proto->getParent(), JSVAL_NULL);
|
||||
obj->setArrayLength(0);
|
||||
obj->setDenseArrayLength(0);
|
||||
obj->setDenseArrayCount(0);
|
||||
return obj;
|
||||
}
|
||||
@ -3371,7 +3384,7 @@ js_NewEmptyArrayWithLength(JSContext* cx, JSObject* proto, int32 len)
|
||||
JSObject *obj = js_NewEmptyArray(cx, proto);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
obj->setArrayLength(len);
|
||||
obj->setDenseArrayLength(len);
|
||||
return obj;
|
||||
}
|
||||
#ifdef JS_TRACER
|
||||
@ -3385,7 +3398,7 @@ js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len)
|
||||
JSObject* obj = js_NewEmptyArray(cx, proto);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
obj->setArrayLength(len);
|
||||
obj->setDenseArrayLength(len);
|
||||
if (!obj->resizeDenseArrayElements(cx, 0, JS_MAX(len, ARRAY_CAPACITY_MIN)))
|
||||
return NULL;
|
||||
return obj;
|
||||
@ -3436,7 +3449,7 @@ js_NewSlowArrayObject(JSContext *cx)
|
||||
{
|
||||
JSObject *obj = NewObject(cx, &js_SlowArrayClass, NULL, NULL);
|
||||
if (obj)
|
||||
obj->setArrayLength(0);
|
||||
obj->setSlowArrayLength(0);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -2486,7 +2486,7 @@ DefinePropertyArray(JSContext *cx, JSObject *obj, const PropertyDescriptor &desc
|
||||
|
||||
if (index >= oldLen) {
|
||||
JS_ASSERT(index != UINT32_MAX);
|
||||
obj->setArrayLength(index + 1);
|
||||
obj->setSlowArrayLength(index + 1);
|
||||
}
|
||||
|
||||
*rval = true;
|
||||
|
@ -409,19 +409,25 @@ struct JSObject {
|
||||
static const uint32 JSSLOT_ARRAY_LENGTH = JSSLOT_PRIVATE;
|
||||
|
||||
// Used only by dense arrays.
|
||||
static const uint32 JSSLOT_DENSE_ARRAY_COUNT = JSSLOT_PRIVATE + 1;
|
||||
static const uint32 JSSLOT_DENSE_ARRAY_COUNT = JSSLOT_PRIVATE + 1;
|
||||
static const uint32 JSSLOT_DENSE_ARRAY_MINLENCAP = JSSLOT_PRIVATE + 2;
|
||||
|
||||
// This assertion must remain true; see comment in js_MakeArraySlow().
|
||||
// (Nb: This method is never called, it just contains a static assertion.
|
||||
// The static assertion isn't inline because that doesn't work on Mac.)
|
||||
inline void staticAssertArrayLengthIsInPrivateSlot();
|
||||
|
||||
inline bool isDenseArrayMinLenCapOk() const;
|
||||
|
||||
inline uint32 uncheckedGetArrayLength() const;
|
||||
inline uint32 uncheckedGetDenseArrayCapacity() const;
|
||||
|
||||
public:
|
||||
inline uint32 getArrayLength() const;
|
||||
inline void setArrayLength(uint32 length);
|
||||
inline void setDenseArrayLength(uint32 length);
|
||||
inline void setSlowArrayLength(uint32 length);
|
||||
|
||||
inline uint32 getDenseArrayCount() const;
|
||||
inline void voidDenseArrayCount();
|
||||
inline void setDenseArrayCount(uint32 count);
|
||||
inline void incDenseArrayCountBy(uint32 posDelta);
|
||||
inline void decDenseArrayCountBy(uint32 negDelta);
|
||||
@ -439,6 +445,8 @@ struct JSObject {
|
||||
bool initializeAllSlots = true);
|
||||
inline void freeDenseArrayElements(JSContext *cx);
|
||||
|
||||
inline void voidDenseOnlyArraySlots(); // used when converting a dense array to a slow array
|
||||
|
||||
/*
|
||||
* Arguments-specific getters and setters.
|
||||
*/
|
||||
|
@ -115,17 +115,42 @@ inline void JSObject::staticAssertArrayLengthIsInPrivateSlot()
|
||||
JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH == JSSLOT_PRIVATE);
|
||||
}
|
||||
|
||||
inline bool JSObject::isDenseArrayMinLenCapOk() const
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
uint32 length = uncheckedGetArrayLength();
|
||||
uint32 capacity = uncheckedGetDenseArrayCapacity();
|
||||
uint32 minLenCap = uint32(fslots[JSSLOT_DENSE_ARRAY_MINLENCAP]);
|
||||
return minLenCap == JS_MIN(length, capacity);
|
||||
}
|
||||
|
||||
inline uint32
|
||||
JSObject::uncheckedGetArrayLength() const
|
||||
{
|
||||
return uint32(fslots[JSSLOT_ARRAY_LENGTH]);
|
||||
}
|
||||
|
||||
inline uint32
|
||||
JSObject::getArrayLength() const
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
return uint32(fslots[JSSLOT_ARRAY_LENGTH]);
|
||||
JS_ASSERT_IF(isDenseArray(), isDenseArrayMinLenCapOk());
|
||||
return uncheckedGetArrayLength();
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setArrayLength(uint32 length)
|
||||
JSObject::setDenseArrayLength(uint32 length)
|
||||
{
|
||||
JS_ASSERT(isArray());
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_ARRAY_LENGTH] = length;
|
||||
uint32 capacity = uncheckedGetDenseArrayCapacity();
|
||||
fslots[JSSLOT_DENSE_ARRAY_MINLENCAP] = JS_MIN(length, capacity);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setSlowArrayLength(uint32 length)
|
||||
{
|
||||
JS_ASSERT(isSlowArray());
|
||||
fslots[JSSLOT_ARRAY_LENGTH] = length;
|
||||
}
|
||||
|
||||
@ -143,13 +168,6 @@ JSObject::setDenseArrayCount(uint32 count)
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] = count;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::voidDenseArrayCount()
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] = JSVAL_VOID;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::incDenseArrayCountBy(uint32 posDelta)
|
||||
{
|
||||
@ -164,11 +182,18 @@ JSObject::decDenseArrayCountBy(uint32 negDelta)
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] -= negDelta;
|
||||
}
|
||||
|
||||
inline uint32
|
||||
JSObject::uncheckedGetDenseArrayCapacity() const
|
||||
{
|
||||
return dslots ? uint32(dslots[-1]) : 0;
|
||||
}
|
||||
|
||||
inline uint32
|
||||
JSObject::getDenseArrayCapacity() const
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
return dslots ? uint32(dslots[-1]) : 0;
|
||||
JS_ASSERT(isDenseArrayMinLenCapOk());
|
||||
return uncheckedGetDenseArrayCapacity();
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -177,6 +202,8 @@ JSObject::setDenseArrayCapacity(uint32 capacity)
|
||||
JS_ASSERT(isDenseArray());
|
||||
JS_ASSERT(dslots);
|
||||
dslots[-1] = capacity;
|
||||
uint32 length = uncheckedGetArrayLength();
|
||||
fslots[JSSLOT_DENSE_ARRAY_MINLENCAP] = JS_MIN(length, capacity);
|
||||
}
|
||||
|
||||
inline jsval
|
||||
@ -205,10 +232,21 @@ JSObject::getDenseArrayElements() const
|
||||
inline void
|
||||
JSObject::freeDenseArrayElements(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
if (dslots) {
|
||||
cx->free(dslots - 1);
|
||||
dslots = NULL;
|
||||
}
|
||||
fslots[JSSLOT_DENSE_ARRAY_MINLENCAP] = 0;
|
||||
JS_ASSERT(isDenseArrayMinLenCapOk());
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::voidDenseOnlyArraySlots()
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
fslots[JSSLOT_DENSE_ARRAY_COUNT] = JSVAL_VOID;
|
||||
fslots[JSSLOT_DENSE_ARRAY_MINLENCAP] = JSVAL_VOID;
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -1928,7 +1928,7 @@ BEGIN_CASE(JSOP_SETELEM)
|
||||
if (js_PrototypeHasIndexedProperties(cx, obj))
|
||||
break;
|
||||
if ((jsuint)i >= obj->getArrayLength())
|
||||
obj->setArrayLength(i + 1);
|
||||
obj->setDenseArrayLength(i + 1);
|
||||
obj->incDenseArrayCountBy(1);
|
||||
}
|
||||
obj->setDenseArrayElement(i, rval);
|
||||
|
@ -13127,7 +13127,8 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
VMSideExit* exit = snapshot(BRANCH_EXIT);
|
||||
|
||||
/* check that the index is within bounds */
|
||||
LIns* dslots_ins = lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, dslots), ACC_OTHER);
|
||||
LIns* dslots_ins =
|
||||
addName(lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, dslots), ACC_OTHER), "dslots");
|
||||
jsuint capacity = obj->getDenseArrayCapacity();
|
||||
bool within = (jsuint(idx) < obj->getArrayLength() && jsuint(idx) < capacity);
|
||||
if (!within) {
|
||||
@ -13141,32 +13142,18 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* If not idx < length, stay on trace (and read value as undefined). */
|
||||
LIns* length = stobj_get_fslot(obj_ins, JSObject::JSSLOT_ARRAY_LENGTH);
|
||||
if (pidx_ins != length) {
|
||||
LIns* br2 = lir->insBranch(LIR_jf,
|
||||
lir->ins2(LIR_pult, pidx_ins, length),
|
||||
NULL);
|
||||
/* If not idx < min(length, capacity), stay on trace (and read value as undefined). */
|
||||
LIns* minLenCap =
|
||||
addName(stobj_get_fslot(obj_ins, JSObject::JSSLOT_DENSE_ARRAY_MINLENCAP), "minLenCap");
|
||||
LIns* br2 = lir->insBranch(LIR_jf,
|
||||
lir->ins2(LIR_pult, pidx_ins, minLenCap),
|
||||
NULL);
|
||||
|
||||
/* If dslots is NULL, stay on trace (and read value as undefined). */
|
||||
LIns* br3 = lir->insBranch(LIR_jt, lir->insEqP_0(dslots_ins), NULL);
|
||||
|
||||
/* If not idx < capacity, stay on trace (and read value as undefined). */
|
||||
LIns* br4 = lir->insBranch(LIR_jf,
|
||||
lir->ins2(LIR_pult,
|
||||
pidx_ins,
|
||||
lir->insLoad(LIR_ldp, dslots_ins,
|
||||
-(int)sizeof(jsval), ACC_OTHER)),
|
||||
NULL);
|
||||
|
||||
lir->insGuard(LIR_x, NULL, createGuardRecord(exit));
|
||||
LIns* label = lir->ins0(LIR_label);
|
||||
if (br1)
|
||||
br1->setTarget(label);
|
||||
br2->setTarget(label);
|
||||
br3->setTarget(label);
|
||||
br4->setTarget(label);
|
||||
}
|
||||
lir->insGuard(LIR_x, NULL, createGuardRecord(exit));
|
||||
LIns* label = lir->ins0(LIR_label);
|
||||
if (br1)
|
||||
br1->setTarget(label);
|
||||
br2->setTarget(label);
|
||||
|
||||
CHECK_STATUS(guardPrototypeHasNoIndexedProperties(obj, obj_ins, MISMATCH_EXIT));
|
||||
|
||||
@ -13185,21 +13172,11 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
exit);
|
||||
}
|
||||
|
||||
/* Guard array length */
|
||||
/* Guard array min(length, capacity). */
|
||||
LIns* minLenCap =
|
||||
addName(stobj_get_fslot(obj_ins, JSObject::JSSLOT_DENSE_ARRAY_MINLENCAP), "minLenCap");
|
||||
guard(true,
|
||||
lir->ins2(LIR_pult, pidx_ins, stobj_get_fslot(obj_ins, JSObject::JSSLOT_ARRAY_LENGTH)),
|
||||
exit);
|
||||
|
||||
/* dslots must not be NULL */
|
||||
guard(false,
|
||||
lir->insEqP_0(dslots_ins),
|
||||
exit);
|
||||
|
||||
/* Guard array capacity */
|
||||
guard(true,
|
||||
lir->ins2(LIR_pult,
|
||||
pidx_ins,
|
||||
lir->insLoad(LIR_ldp, dslots_ins, 0 - (int)sizeof(jsval), ACC_OTHER)),
|
||||
lir->ins2(LIR_pult, pidx_ins, minLenCap),
|
||||
exit);
|
||||
|
||||
/* Load the value and guard on its type to unbox it. */
|
||||
|
Loading…
Reference in New Issue
Block a user