Bug 881536 - Part 3: Pure path for GetElement in the VM. (r=bhackett)

This commit is contained in:
Shu-yu Guo 2013-07-08 03:24:55 -07:00
Родитель 38614b2ab9
Коммит 582bd4255c
5 изменённых файлов: 138 добавлений и 5 удалений

Просмотреть файл

@ -41,6 +41,22 @@ AtomToId(JSAtom *atom)
return JSID_FROM_BITS(size_t(atom));
}
inline bool
ValueToIdPure(const Value &v, jsid *id)
{
int32_t i;
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
*id = INT_TO_JSID(i);
return true;
}
if (!v.isString() || !v.toString()->isAtom())
return false;
*id = AtomToId(&v.toString()->asAtom());
return true;
}
template <AllowGC allowGC>
inline bool
ValueToId(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v,
@ -108,13 +124,22 @@ IndexToId(JSContext *cx, uint32_t index, MutableHandleId idp)
}
inline bool
IndexToIdNoGC(JSContext *cx, uint32_t index, jsid *idp)
IndexToIdPure(uint32_t index, jsid *idp)
{
if (index <= JSID_INT_MAX) {
*idp = INT_TO_JSID(index);
return true;
}
return false;
}
inline bool
IndexToIdNoGC(JSContext *cx, uint32_t index, jsid *idp)
{
if (IndexToIdPure(index, idp))
return true;
return IndexToIdSlow<NoGC>(cx, index, idp);
}

Просмотреть файл

@ -4161,6 +4161,12 @@ js::LookupPropertyPure(JSObject *obj, jsid id, JSObject **objp, Shape **propp)
return LookupPropertyPureInline(obj, id, objp, propp);
}
static inline bool
IdIsLength(ThreadSafeContext *tcx, jsid id)
{
return JSID_IS_ATOM(id) && tcx->names().length == JSID_TO_ATOM(id);
}
/*
* A pure version of GetPropertyHelper that can be called from parallel code
* without locking. This code path cannot GC. This variant returns false
@ -4174,16 +4180,42 @@ js::LookupPropertyPure(JSObject *obj, jsid id, JSObject **objp, Shape **propp)
bool
js::GetPropertyPure(ThreadSafeContext *tcx, JSObject *obj, jsid id, Value *vp)
{
/* Typed arrays are not native, so we fast-path them here. */
if (obj->is<TypedArrayObject>()) {
TypedArrayObject *tarr = &obj->as<TypedArrayObject>();
if (JSID_IS_INT(id)) {
uint32_t index = JSID_TO_INT(id);
if (index < tarr->length()) {
MutableHandleValue vpHandle = MutableHandleValue::fromMarkedLocation(vp);
tarr->copyTypedArrayElement(index, vpHandle);
return true;
}
return false;
}
if (IdIsLength(tcx, id)) {
vp->setNumber(tarr->length());
return true;
}
return false;
}
/* Deal with native objects. */
JSObject *obj2;
Shape *shape;
if (!LookupPropertyPureInline(obj, id, &obj2, &shape))
return false;
if (!shape) {
/* Fail if we have a non-stub class op hook? */
/* Fail if we have a non-stub class op hooks. */
if (obj->getClass()->getProperty && obj->getClass()->getProperty != JS_PropertyStub)
return false;
if (obj->getOps()->getElement)
return false;
/* Vanilla native object, return undefined. */
vp->setUndefined();
return true;
@ -4195,9 +4227,7 @@ js::GetPropertyPure(ThreadSafeContext *tcx, JSObject *obj, jsid id, Value *vp)
}
/* Special case 'length' on Array. */
if (obj->is<ArrayObject>() &&
(JSID_IS_ATOM(id) && tcx->names().length == JSID_TO_ATOM(id)))
{
if (obj->is<ArrayObject>() && IdIsLength(tcx, id)) {
vp->setNumber(obj->as<ArrayObject>().length());
return true;
}
@ -4205,6 +4235,41 @@ js::GetPropertyPure(ThreadSafeContext *tcx, JSObject *obj, jsid id, Value *vp)
return NativeGetPureInline(obj2, shape, vp);
}
static bool
JS_ALWAYS_INLINE
GetElementPure(ThreadSafeContext *tcx, JSObject *obj, uint32_t index, Value *vp)
{
jsid id;
if (!IndexToIdPure(index, &id))
return false;
return GetPropertyPure(tcx, obj, id, vp);
}
/*
* A pure version of GetObjectElementOperation that can be called from
* parallel code without locking. This variant returns false whenever a
* side-effect might have occurred.
*/
bool
js::GetObjectElementOperationPure(ThreadSafeContext *tcx, JSObject *obj, const Value &prop,
Value *vp)
{
uint32_t index;
if (IsDefinitelyIndex(prop, &index))
return GetElementPure(tcx, obj, index, vp);
/* Atomizing the property value is effectful and not threadsafe. */
if (!prop.isString() || !prop.toString()->isAtom())
return false;
JSAtom *name = &prop.toString()->asAtom();
if (name->isIndex(&index))
return GetElementPure(tcx, obj, index, vp);
return GetPropertyPure(tcx, obj, NameToId(name->asPropertyName()), vp);
}
JSBool
baseops::GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp)

Просмотреть файл

@ -1457,6 +1457,9 @@ CheckAccess(JSContext *cx, JSObject *obj, HandleId id, JSAccessMode mode,
extern bool
IsDelegate(JSContext *cx, HandleObject obj, const Value &v, bool *result);
bool
GetObjectElementOperationPure(ThreadSafeContext *tcx, JSObject *obj, const Value &prop, Value *vp);
} /* namespace js */
/*

Просмотреть файл

@ -3398,6 +3398,45 @@ DataViewObject::fun_setFloat64(JSContext *cx, unsigned argc, Value *vp)
return CallNonGenericMethod<is, setFloat64Impl>(cx, args);
}
void
TypedArrayObject::copyTypedArrayElement(uint32_t index, MutableHandleValue vp)
{
JS_ASSERT(index < length());
switch (type()) {
case TYPE_INT8:
TypedArrayObjectTemplate<int8_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_UINT8:
TypedArrayObjectTemplate<uint8_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_UINT8_CLAMPED:
TypedArrayObjectTemplate<uint8_clamped>::copyIndexToValue(this, index, vp);
break;
case TYPE_INT16:
TypedArrayObjectTemplate<int16_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_UINT16:
TypedArrayObjectTemplate<uint16_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_INT32:
TypedArrayObjectTemplate<int32_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_UINT32:
TypedArrayObjectTemplate<uint32_t>::copyIndexToValue(this, index, vp);
break;
case TYPE_FLOAT32:
TypedArrayObjectTemplate<float>::copyIndexToValue(this, index, vp);
break;
case TYPE_FLOAT64:
TypedArrayObjectTemplate<double>::copyIndexToValue(this, index, vp);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unknown TypedArray type");
break;
}
}
/***
*** JS impl
***/

Просмотреть файл

@ -364,6 +364,7 @@ class TypedArrayObject : public ArrayBufferViewObject
}
inline bool isArrayIndex(jsid id, uint32_t *ip = NULL);
void copyTypedArrayElement(uint32_t index, MutableHandleValue vp);
void neuter();