Bug 1225605: Store SIMD type descriptors on the global SIMD object rather than on the global; r=jolesen

This commit is contained in:
Benjamin Bouvier 2015-11-20 10:52:33 +01:00
parent 225689f73f
commit e24eea9d45
6 changed files with 94 additions and 134 deletions

View File

@ -719,7 +719,7 @@ struct JSClass {
// application.
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
#define JSCLASS_GLOBAL_SLOT_COUNT \
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 37)
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 32)
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \

View File

@ -92,12 +92,21 @@ ErrorWrongTypeArg(JSContext* cx, size_t argIndex, Handle<TypeDescr*> typeDescr)
return false;
}
template<typename T>
static SimdTypeDescr*
GetTypeDescr(JSContext* cx)
{
return cx->global()->getOrCreateSimdTypeDescr<T>(cx);
}
template<typename V>
bool
js::ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out)
{
typedef typename V::Elem Elem;
Rooted<TypeDescr*> typeDescr(cx, &V::GetTypeDescr(*cx->global()));
Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
if (!typeDescr)
return false;
if (!IsVectorObject<V>(v))
return ErrorWrongTypeArg(cx, 1, typeDescr);
@ -352,7 +361,7 @@ const JSFunctionSpec Int32x4Defn::Methods[] = {
template<typename T>
static JSObject*
CreateAndBindSimdClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject SIMD,
CreateAndBindSimdClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject globalSimdObject,
HandlePropertyName stringRepr)
{
const SimdTypeDescr::Type type = T::type;
@ -402,12 +411,15 @@ CreateAndBindSimdClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject
// Bind type descriptor to the global SIMD object
RootedValue typeValue(cx, ObjectValue(*typeDescr));
if (!JS_DefineFunctions(cx, typeDescr, T::Methods) ||
!DefineProperty(cx, SIMD, stringRepr, typeValue, nullptr, nullptr,
!DefineProperty(cx, globalSimdObject, stringRepr, typeValue, nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
uint32_t slot = uint32_t(typeDescr->type());
globalSimdObject->as<NativeObject>().setReservedSlot(slot, ObjectValue(*typeDescr));
return typeDescr;
}
@ -454,71 +466,42 @@ SimdTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
///////////////////////////////////////////////////////////////////////////
// SIMD class
static const uint32_t SIMD_SLOTS_COUNT = SimdTypeDescr::LAST_TYPE + 1;
const Class SIMDObject::class_ = {
"SIMD",
JSCLASS_HAS_CACHED_PROTO(JSProto_SIMD)
JSCLASS_HAS_RESERVED_SLOTS(SIMD_SLOTS_COUNT)
};
JSObject*
SIMDObject::initClass(JSContext* cx, Handle<GlobalObject*> global)
bool
GlobalObject::initSimdObject(JSContext* cx, Handle<GlobalObject*> global)
{
// SIMD relies on having the TypedObject module initialized.
// SIMD relies on the TypedObject module being initialized.
// In particular, the self-hosted code for array() wants
// to be able to call GetTypedObjectModule(). It is NOT necessary
// to install the TypedObjectModule global, but at the moment
// those two things are not separable.
if (!global->getOrCreateTypedObjectModule(cx))
return nullptr;
return false;
// Create SIMD Object.
RootedObject globalSimdObject(cx);
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if (!objProto)
return nullptr;
RootedObject SIMD(cx, NewObjectWithGivenProto(cx, &SIMDObject::class_, objProto,
SingletonObject));
if (!SIMD)
return nullptr;
return false;
RootedObject i8x16(cx);
i8x16 = CreateAndBindSimdClass<Int8x16Defn>(cx, global, SIMD, cx->names().int8x16);
if (!i8x16)
return nullptr;
globalSimdObject = NewObjectWithGivenProto(cx, &SIMDObject::class_, objProto, SingletonObject);
if (!globalSimdObject)
return false;
RootedObject i16x8(cx);
i16x8 = CreateAndBindSimdClass<Int16x8Defn>(cx, global, SIMD, cx->names().int16x8);
if (!i16x8)
return nullptr;
RootedObject f32x4(cx);
f32x4 = CreateAndBindSimdClass<Float32x4Defn>(cx, global, SIMD, cx->names().float32x4);
if (!f32x4)
return nullptr;
RootedObject i32x4(cx);
i32x4 = CreateAndBindSimdClass<Int32x4Defn>(cx, global, SIMD, cx->names().int32x4);
if (!i32x4)
return nullptr;
RootedObject f64x2(cx);
f64x2 = CreateAndBindSimdClass<Float64x2Defn>(cx, global, SIMD, cx->names().float64x2);
if (!f64x2)
return nullptr;
// Everything is set up, install SIMD on the global object.
RootedValue SIMDValue(cx, ObjectValue(*SIMD));
if (!DefineProperty(cx, global, cx->names().SIMD, SIMDValue, nullptr, nullptr,
RootedValue globalSimdValue(cx, ObjectValue(*globalSimdObject));
if (!DefineProperty(cx, global, cx->names().SIMD, globalSimdValue, nullptr, nullptr,
JSPROP_RESOLVING))
{
return nullptr;
return false;
}
global->setInt8x16TypeDescr(*i8x16);
global->setInt16x8TypeDescr(*i16x8);
global->setFloat32x4TypeDescr(*f32x4);
global->setInt32x4TypeDescr(*i32x4);
global->setFloat64x2TypeDescr(*f64x2);
global->setConstructor(JSProto_SIMD, SIMDValue);
return SIMD;
global->setConstructor(JSProto_SIMD, globalSimdValue);
return true;
}
JSObject*
@ -526,7 +509,37 @@ js::InitSIMDClass(JSContext* cx, HandleObject obj)
{
MOZ_ASSERT(obj->is<GlobalObject>());
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
return SIMDObject::initClass(cx, global);
RootedObject globalSimdObject(cx, global->getOrCreateSimdGlobalObject(cx));
if (!globalSimdObject)
return nullptr;
RootedObject i8x16(cx);
i8x16 = CreateAndBindSimdClass<Int8x16Defn>(cx, global, globalSimdObject, cx->names().int8x16);
if (!i8x16)
return nullptr;
RootedObject i16x8(cx);
i16x8 = CreateAndBindSimdClass<Int16x8Defn>(cx, global, globalSimdObject, cx->names().int16x8);
if (!i16x8)
return nullptr;
RootedObject f32x4(cx);
f32x4 = CreateAndBindSimdClass<Float32x4Defn>(cx, global, globalSimdObject, cx->names().float32x4);
if (!f32x4)
return nullptr;
RootedObject i32x4(cx);
i32x4 = CreateAndBindSimdClass<Int32x4Defn>(cx, global, globalSimdObject, cx->names().int32x4);
if (!i32x4)
return nullptr;
RootedObject f64x2(cx);
f64x2 = CreateAndBindSimdClass<Float64x2Defn>(cx, global, globalSimdObject, cx->names().float64x2);
if (!f64x2)
return nullptr;
return globalSimdObject;
}
template<typename V>
@ -534,8 +547,9 @@ JSObject*
js::CreateSimd(JSContext* cx, const typename V::Elem* data)
{
typedef typename V::Elem Elem;
Rooted<TypeDescr*> typeDescr(cx, &V::GetTypeDescr(*cx->global()));
MOZ_ASSERT(typeDescr);
Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
if (!typeDescr)
return nullptr;
Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, typeDescr, 0));
if (!result)
@ -1143,8 +1157,10 @@ Load(JSContext* cx, unsigned argc, Value* vp)
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
return false;
Rooted<TypeDescr*> typeDescr(cx, &V::GetTypeDescr(*cx->global()));
MOZ_ASSERT(typeDescr);
Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
if (!typeDescr)
return false;
Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, typeDescr, 0));
if (!result)
return false;

View File

@ -346,7 +346,6 @@ class SIMDObject : public JSObject
{
public:
static const Class class_;
static JSObject* initClass(JSContext* cx, Handle<GlobalObject*> global);
static bool toString(JSContext* cx, unsigned int argc, Value* vp);
};
@ -357,8 +356,6 @@ class SIMDObject : public JSObject
// of the SIMD vector.
// - requires static const SimdTypeDescr::Type type: this is the SimdTypeDescr
// enum value corresponding to the SIMD type.
// - requires static TypeDescr& GetTypeDescr(GlobalObject& global): returns the
// TypedObject type descriptor of the SIMD type.
// - requires static bool Cast(JSContext*, JS::HandleValue, Elem*): casts a
// given Value to the current scalar lane type and saves it in the Elem
// out-param.
@ -373,9 +370,6 @@ struct Float32x4 {
typedef float Elem;
static const unsigned lanes = 4;
static const SimdTypeDescr::Type type = SimdTypeDescr::Float32x4;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.float32x4TypeDescr().as<TypeDescr>();
}
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
double d;
if (!ToNumber(cx, v, &d))
@ -392,9 +386,6 @@ struct Float64x2 {
typedef double Elem;
static const unsigned lanes = 2;
static const SimdTypeDescr::Type type = SimdTypeDescr::Float64x2;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.float64x2TypeDescr().as<TypeDescr>();
}
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToNumber(cx, v, out);
}
@ -407,10 +398,6 @@ struct Int8x16 {
typedef int8_t Elem;
static const unsigned lanes = 16;
static const SimdTypeDescr::Type type = SimdTypeDescr::Int8x16;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.int8x16TypeDescr().as<TypeDescr>();
}
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToInt8(cx, v, out);
}
@ -423,10 +410,6 @@ struct Int16x8 {
typedef int16_t Elem;
static const unsigned lanes = 8;
static const SimdTypeDescr::Type type = SimdTypeDescr::Int16x8;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.int16x8TypeDescr().as<TypeDescr>();
}
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToInt16(cx, v, out);
}
@ -439,10 +422,6 @@ struct Int32x4 {
typedef int32_t Elem;
static const unsigned lanes = 4;
static const SimdTypeDescr::Type type = SimdTypeDescr::Int32x4;
static TypeDescr& GetTypeDescr(GlobalObject& global) {
return global.int32x4TypeDescr().as<TypeDescr>();
}
static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
return ToInt32(cx, v, out);
}

View File

@ -13,6 +13,7 @@
#include "jsfun.h"
#include "jsutil.h"
#include "builtin/SIMD.h"
#include "gc/Marking.h"
#include "js/Vector.h"
#include "vm/GlobalObject.h"
@ -2600,7 +2601,7 @@ js::GetFloat32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->float32x4TypeDescr());
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Float32x4>(cx));
return true;
}
@ -2610,7 +2611,7 @@ js::GetFloat64x2TypeDescr(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->float64x2TypeDescr());
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Float64x2>(cx));
return true;
}
@ -2620,7 +2621,7 @@ js::GetInt8x16TypeDescr(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->int8x16TypeDescr());
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Int8x16>(cx));
return true;
}
@ -2630,7 +2631,7 @@ js::GetInt16x8TypeDescr(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->int16x8TypeDescr());
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Int16x8>(cx));
return true;
}
@ -2640,7 +2641,7 @@ js::GetInt32x4TypeDescr(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
MOZ_ASSERT(global);
args.rval().setObject(global->int32x4TypeDescr());
args.rval().setObject(*global->getOrCreateSimdTypeDescr<Int32x4>(cx));
return true;
}

View File

@ -5698,7 +5698,7 @@ GetTemplateObjectForNative(JSContext* cx, Native native, const CallArgs& args,
COMP_COMMONX4_TO_INT32X4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_)
FOREACH_INT32X4_SIMD_OP(ADD_INT32X4_SIMD_OP_NAME_))
{
Rooted<SimdTypeDescr*> descr(cx, &cx->global()->int32x4TypeDescr().as<SimdTypeDescr>());
Rooted<SimdTypeDescr*> descr(cx, cx->global()->getOrCreateSimdTypeDescr<Int32x4>(cx));
res.set(cx->compartment()->jitCompartment()->getSimdTemplateObjectFor(cx, descr));
return !!res;
}
@ -5706,7 +5706,7 @@ GetTemplateObjectForNative(JSContext* cx, Native native, const CallArgs& args,
FOREACH_FLOAT32X4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_)
ION_COMMONX4_SIMD_OP(ADD_FLOAT32X4_SIMD_OP_NAME_))
{
Rooted<SimdTypeDescr*> descr(cx, &cx->global()->float32x4TypeDescr().as<SimdTypeDescr>());
Rooted<SimdTypeDescr*> descr(cx, cx->global()->getOrCreateSimdTypeDescr<Float32x4>(cx));
res.set(cx->compartment()->jitCompartment()->getSimdTemplateObjectFor(cx, descr));
return !!res;
}

View File

@ -30,6 +30,8 @@ class TypedObjectModuleObject;
class StaticBlockObject;
class ClonedBlockObject;
class SimdTypeDescr;
/*
* Global object slots are reserved as follows:
*
@ -110,11 +112,6 @@ class GlobalObject : public NativeObject
RUNTIME_CODEGEN_ENABLED,
DEBUGGERS,
INTRINSICS,
FLOAT32X4_TYPE_DESCR,
FLOAT64X2_TYPE_DESCR,
INT8X16_TYPE_DESCR,
INT16X8_TYPE_DESCR,
INT32X4_TYPE_DESCR,
FOR_OF_PIC_CHAIN,
MODULE_RESOLVE_HOOK,
WINDOW_PROXY,
@ -437,54 +434,18 @@ class GlobalObject : public NativeObject
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_TypedObject, initTypedObjectModule);
}
void setFloat32x4TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(FLOAT32X4_TYPE_DESCR).isUndefined());
setSlot(FLOAT32X4_TYPE_DESCR, ObjectValue(obj));
JSObject* getOrCreateSimdGlobalObject(JSContext* cx) {
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_SIMD, initSimdObject);
}
JSObject& float32x4TypeDescr() {
MOZ_ASSERT(getSlotRef(FLOAT32X4_TYPE_DESCR).isObject());
return getSlotRef(FLOAT32X4_TYPE_DESCR).toObject();
}
void setFloat64x2TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(FLOAT64X2_TYPE_DESCR).isUndefined());
setSlot(FLOAT64X2_TYPE_DESCR, ObjectValue(obj));
}
JSObject& float64x2TypeDescr() {
MOZ_ASSERT(getSlotRef(FLOAT64X2_TYPE_DESCR).isObject());
return getSlotRef(FLOAT64X2_TYPE_DESCR).toObject();
}
void setInt8x16TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT8X16_TYPE_DESCR).isUndefined());
setSlot(INT8X16_TYPE_DESCR, ObjectValue(obj));
}
JSObject& int8x16TypeDescr() {
MOZ_ASSERT(getSlotRef(INT8X16_TYPE_DESCR).isObject());
return getSlotRef(INT8X16_TYPE_DESCR).toObject();
}
void setInt16x8TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT16X8_TYPE_DESCR).isUndefined());
setSlot(INT16X8_TYPE_DESCR, ObjectValue(obj));
}
JSObject& int16x8TypeDescr() {
MOZ_ASSERT(getSlotRef(INT16X8_TYPE_DESCR).isObject());
return getSlotRef(INT16X8_TYPE_DESCR).toObject();
}
void setInt32x4TypeDescr(JSObject& obj) {
MOZ_ASSERT(getSlotRef(INT32X4_TYPE_DESCR).isUndefined());
setSlot(INT32X4_TYPE_DESCR, ObjectValue(obj));
}
JSObject& int32x4TypeDescr() {
MOZ_ASSERT(getSlotRef(INT32X4_TYPE_DESCR).isObject());
return getSlotRef(INT32X4_TYPE_DESCR).toObject();
template<class /* SimdTypeDescriptor (cf SIMD.h) */ T>
SimdTypeDescr* getOrCreateSimdTypeDescr(JSContext* cx) {
RootedObject globalSimdObject(cx, cx->global()->getOrCreateSimdGlobalObject(cx));
if (!globalSimdObject)
return nullptr;
const Value& slot = globalSimdObject->as<NativeObject>().getReservedSlot(uint32_t(T::type));
MOZ_ASSERT(slot.isObject());
return &slot.toObject().as<SimdTypeDescr>();
}
TypedObjectModuleObject& getTypedObjectModule() const;
@ -722,6 +683,9 @@ class GlobalObject : public NativeObject
// Implemented in builtin/TypedObject.cpp
static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global);
// Implemented in builtim/SIMD.cpp
static bool initSimdObject(JSContext* cx, Handle<GlobalObject*> global);
static bool initStandardClasses(JSContext* cx, Handle<GlobalObject*> global);
static bool initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> global,
const JSFunctionSpec* builtins);