mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 16:46:26 +00:00
[INFER] Store base of data directly in typed arrays, bug 677743.
This commit is contained in:
parent
c743913090
commit
3f74089b59
@ -13203,21 +13203,14 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
||||
// be an integer.
|
||||
CHECK_STATUS_A(makeNumberInt32(idx_ins, &idx_ins));
|
||||
|
||||
LIns* slots_ins = w.ldpObjFixedSlots(obj_ins);
|
||||
// Ensure idx >= 0 && idx < length (by using uint32)
|
||||
CHECK_STATUS_A(guard(true,
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(slots_ins)),
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(obj_ins)),
|
||||
"inRange"),
|
||||
OVERFLOW_EXIT, /* abortIfAlwaysExits = */true));
|
||||
|
||||
// We're now ready to store
|
||||
LIns* data_base_ins = w.ldpConstTypedArrayData(slots_ins);
|
||||
LIns* offset_ins = w.ldiConstTypedArrayByteOffset(slots_ins);
|
||||
#ifdef NANOJIT_64BIT
|
||||
LIns* data_ins = w.addp(data_base_ins, w.ui2uq(offset_ins));
|
||||
#else
|
||||
LIns* data_ins = w.addp(data_base_ins, offset_ins);
|
||||
#endif
|
||||
LIns* data_ins = w.ldpConstTypedArrayData(obj_ins);
|
||||
|
||||
LIns* pidx_ins = w.ui2p(idx_ins);
|
||||
LIns* typed_v_ins = v_ins;
|
||||
@ -14294,8 +14287,6 @@ TraceRecorder::typedArrayElement(Value& oval, Value& ival, Value*& vp, LIns*& v_
|
||||
JSObject* tarray = js::TypedArray::getTypedArray(obj);
|
||||
JS_ASSERT(tarray);
|
||||
|
||||
LIns *slots_ins = w.ldpObjFixedSlots(obj_ins);
|
||||
|
||||
/* Abort if out-of-range. */
|
||||
if ((jsuint) idx >= js::TypedArray::getLength(tarray))
|
||||
RETURN_STOP_A("out-of-range index on typed array");
|
||||
@ -14310,18 +14301,12 @@ TraceRecorder::typedArrayElement(Value& oval, Value& ival, Value*& vp, LIns*& v_
|
||||
* length.
|
||||
*/
|
||||
guard(true,
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(slots_ins)), "inRange"),
|
||||
w.name(w.ltui(idx_ins, w.ldiConstTypedArrayLength(obj_ins)), "inRange"),
|
||||
BRANCH_EXIT);
|
||||
|
||||
/* We are now ready to load. Do a different type of load
|
||||
* depending on what type of thing we're loading. */
|
||||
LIns* data_base_ins = w.ldpConstTypedArrayData(slots_ins);
|
||||
LIns* offset_ins = w.ldiConstTypedArrayByteOffset(slots_ins);
|
||||
#ifdef NANOJIT_64BIT
|
||||
LIns* data_ins = w.addp(data_base_ins, w.ui2uq(offset_ins));
|
||||
#else
|
||||
LIns* data_ins = w.addp(data_base_ins, offset_ins);
|
||||
#endif
|
||||
LIns* data_ins = w.ldpConstTypedArrayData(obj_ins);
|
||||
|
||||
switch (js::TypedArray::getType(tarray)) {
|
||||
case js::TypedArray::TYPE_INT8:
|
||||
@ -16326,7 +16311,7 @@ TraceRecorder::record_JSOP_LENGTH()
|
||||
} else if (OkToTraceTypedArrays && js_IsTypedArray(obj)) {
|
||||
// Ensure array is a typed array and is the same type as what was written
|
||||
guardClass(obj_ins, obj->getClass(), snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
v_ins = w.i2d(w.ldiConstTypedArrayLength(w.ldpObjFixedSlots(obj_ins)));
|
||||
v_ins = w.i2d(w.ldiConstTypedArrayLength(obj_ins));
|
||||
} else {
|
||||
if (!obj->isNative())
|
||||
RETURN_STOP_A("can't trace length property access on non-array, non-native object");
|
||||
|
@ -935,21 +935,14 @@ class TypedArrayTemplate
|
||||
obj->setType(type);
|
||||
|
||||
obj->setSlot(FIELD_TYPE, Int32Value(ArrayTypeID()));
|
||||
obj->setSlot(FIELD_BUFFER, ObjectValue(*bufobj));
|
||||
|
||||
do {
|
||||
obj->setSlot(FIELD_BUFFER, ObjectValue(*bufobj));
|
||||
/*
|
||||
* NOTE: unlike the earlier implementation where the 'data' pointed
|
||||
* directly to the right offset in the ArrayBuffer
|
||||
* this points to the base of the ArrayBuffer.
|
||||
* getIndex is modified to get the right index.
|
||||
*
|
||||
* This is because on 64 bit systems the jsval.h Private API
|
||||
* requires pointers stored in jsvals to be two-byte aligned.
|
||||
* TM and JM both need a few extra instructions to add the offset.
|
||||
*/
|
||||
obj->setSlot(FIELD_DATA, PrivateValue(ArrayBuffer::getDataOffset(bufobj)));
|
||||
} while(0);
|
||||
/*
|
||||
* N.B. The base of the array's data is stored in the object's
|
||||
* private data rather than a slot, to avoid alignment restrictions
|
||||
* on private Values.
|
||||
*/
|
||||
obj->setPrivate(ArrayBuffer::getDataOffset(bufobj) + byteOffset);
|
||||
|
||||
obj->setSlot(FIELD_LENGTH, Int32Value(len));
|
||||
obj->setSlot(FIELD_BYTEOFFSET, Int32Value(byteOffset));
|
||||
@ -1755,6 +1748,7 @@ JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(TypedArray::FIELD_MAX) | \
|
||||
JSCLASS_HAS_PRIVATE | \
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray), \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
@ -1770,6 +1764,7 @@ JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(TypedArray::FIELD_MAX) | \
|
||||
JSCLASS_HAS_PRIVATE | \
|
||||
Class::NON_NATIVE, \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
|
@ -147,12 +147,12 @@ struct JS_FRIEND_API(TypedArray) {
|
||||
};
|
||||
|
||||
enum {
|
||||
/* Properties of the typed array stored in reserved slots. */
|
||||
FIELD_LENGTH = 0,
|
||||
FIELD_BYTEOFFSET,
|
||||
FIELD_BYTELENGTH,
|
||||
FIELD_TYPE,
|
||||
FIELD_BUFFER,
|
||||
FIELD_DATA,
|
||||
FIELD_MAX
|
||||
};
|
||||
|
||||
@ -186,8 +186,6 @@ struct JS_FRIEND_API(TypedArray) {
|
||||
static JSObject * getBuffer(JSObject *obj);
|
||||
static void * getDataOffset(JSObject *obj);
|
||||
|
||||
static void *offsetData(JSObject *obj, uint32 offs);
|
||||
|
||||
public:
|
||||
static bool
|
||||
isArrayIndex(JSContext *cx, JSObject *obj, jsid id, jsuint *ip = NULL);
|
||||
@ -217,8 +215,13 @@ struct JS_FRIEND_API(TypedArray) {
|
||||
return slotWidth(getType(obj));
|
||||
}
|
||||
|
||||
static inline int lengthOffset();
|
||||
static inline int dataOffset();
|
||||
static inline int lengthOffset() {
|
||||
return JSObject::getFixedSlotOffset(FIELD_LENGTH);
|
||||
}
|
||||
|
||||
static inline int dataOffset() {
|
||||
return offsetof(JSObject, privateData);
|
||||
}
|
||||
};
|
||||
|
||||
extern bool
|
||||
|
@ -94,17 +94,7 @@ TypedArray::getBuffer(JSObject *obj) {
|
||||
|
||||
inline void *
|
||||
TypedArray::getDataOffset(JSObject *obj) {
|
||||
return (void *)((uint8*)obj->getFixedSlot(FIELD_DATA).toPrivate() + getByteOffset(obj));
|
||||
}
|
||||
|
||||
inline int
|
||||
TypedArray::lengthOffset() {
|
||||
return JSObject::getFixedSlotOffset(FIELD_LENGTH);
|
||||
}
|
||||
|
||||
inline int
|
||||
TypedArray::dataOffset() {
|
||||
return JSObject::getFixedSlotOffset(FIELD_DATA);
|
||||
return (void *)obj->getPrivate();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2661,7 +2661,7 @@ GetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, const Value &v, jsi
|
||||
}
|
||||
|
||||
// Load the array's packed data vector.
|
||||
masm.loadPrivate(Address(objReg, TypedArray::dataOffset()), objReg);
|
||||
masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
|
||||
|
||||
Int32Key key = idRemat.isConstant()
|
||||
? Int32Key::FromConstant(v.toInt32())
|
||||
@ -3010,11 +3010,9 @@ SetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, int32 key)
|
||||
outOfBounds = masm.branch32(Assembler::BelowOrEqual, typedArrayLength, keyReg);
|
||||
|
||||
// Load the array's packed data vector.
|
||||
JSObject *tarray = js::TypedArray::getTypedArray(obj);
|
||||
int byteOffset = js::TypedArray::getByteOffset(tarray);
|
||||
masm.loadPrivate(Address(objReg, TypedArray::dataOffset()), objReg);
|
||||
masm.addPtr(Imm32(byteOffset), objReg);
|
||||
masm.loadPtr(Address(objReg, TypedArray::dataOffset()), objReg);
|
||||
|
||||
JSObject *tarray = js::TypedArray::getTypedArray(obj);
|
||||
int shift = js::TypedArray::slotWidth(obj);
|
||||
if (hasConstantKey) {
|
||||
Address addr(objReg, keyValue * shift);
|
||||
|
@ -545,31 +545,14 @@ class Writer
|
||||
"fixed_slots");
|
||||
}
|
||||
|
||||
nj::LIns *ldiConstTypedArrayLength(nj::LIns *array) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, sizeof(Value) * js::TypedArray::FIELD_LENGTH + sPayloadOffset, ACCSET_TARRAY,
|
||||
nj::LIns *ldiConstTypedArrayLength(nj::LIns *obj) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, obj, TypedArray::lengthOffset(), ACCSET_TARRAY,
|
||||
nj::LOAD_CONST),
|
||||
"typedArrayLength");
|
||||
}
|
||||
|
||||
nj::LIns *ldiConstTypedArrayByteOffset(nj::LIns *array) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, sizeof(Value) * js::TypedArray::FIELD_BYTEOFFSET + sPayloadOffset, ACCSET_TARRAY,
|
||||
nj::LOAD_CONST),
|
||||
"typedArrayByteOffset");
|
||||
}
|
||||
|
||||
nj::LIns *ldpConstTypedArrayData(nj::LIns *array) const {
|
||||
//return name(lir->insLoad(nj::LIR_ldp, array, sizeof(Value) * js::TypedArray::FIELD_DATA + sPayloadOffset, ACCSET_TARRAY,
|
||||
//nj::LOAD_CONST),
|
||||
//"typedElems");
|
||||
uint32 offset = sizeof(Value) * js::TypedArray::FIELD_DATA + sPayloadOffset;
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
return name(lir->insLoad(nj::LIR_ldi, array, offset, ACCSET_TARRAY, nj::LOAD_CONST), "typedArrayData");
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
/* N.B. On 64-bit, privatized value are encoded differently from other pointers. */
|
||||
nj::LIns *v_ins = lir->insLoad(nj::LIR_ldq, array, offset,
|
||||
ACCSET_TARRAY, nj::LOAD_CONST);
|
||||
return name(lshqN(v_ins, 1), "typedArrayData");
|
||||
#endif
|
||||
nj::LIns *ldpConstTypedArrayData(nj::LIns *obj) const {
|
||||
return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, privateData), ACCSET_TARRAY, nj::LOAD_CONST), "typedArrayData");
|
||||
}
|
||||
|
||||
nj::LIns *ldc2iTypedArrayElement(nj::LIns *elems, nj::LIns *index) const {
|
||||
|
Loading…
Reference in New Issue
Block a user