[INFER] Store base of data directly in typed arrays, bug 677743.

This commit is contained in:
Brian Hackett 2011-08-09 17:12:52 -07:00
parent c743913090
commit 3f74089b59
6 changed files with 30 additions and 76 deletions

View File

@ -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");

View File

@ -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 */ \

View File

@ -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

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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 {