зеркало из https://github.com/mozilla/gecko-dev.git
Bug 881536 - Part 3: Pure path for GetElement in the VM. (r=bhackett)
This commit is contained in:
Родитель
38614b2ab9
Коммит
582bd4255c
|
@ -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();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче