зеркало из https://github.com/mozilla/gecko-dev.git
Bug 936236 - Inline allocateSlots into caller and handlify (r=jonco)
This commit is contained in:
Родитель
39507d1a49
Коммит
5ac29476e6
|
@ -843,6 +843,24 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
|||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Augment the generic Rooted<T> interface when T = JSObject* with
|
||||
* class-querying and downcasting operations.
|
||||
*
|
||||
* Given a Rooted<JSObject*> obj, one can view
|
||||
* Handle<StringObject*> h = obj.as<StringObject*>();
|
||||
* as an optimization of
|
||||
* Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
|
||||
* Handle<StringObject*> h = rooted;
|
||||
*/
|
||||
template <>
|
||||
class RootedBase<JSObject*>
|
||||
{
|
||||
public:
|
||||
template <class U>
|
||||
JS::Handle<U*> as() const;
|
||||
};
|
||||
|
||||
/*
|
||||
* Mark a stack location as a root for the rooting analysis, without actually
|
||||
* rooting it in release builds. This should only be used for stack locations
|
||||
|
|
|
@ -1210,6 +1210,15 @@ class JSObject : public js::ObjectImpl
|
|||
void operator=(const JSObject &other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template <class U>
|
||||
MOZ_ALWAYS_INLINE JS::Handle<U*>
|
||||
js::RootedBase<JSObject*>::as() const
|
||||
{
|
||||
const JS::Rooted<JSObject*> &self = *static_cast<const JS::Rooted<JSObject*>*>(this);
|
||||
JS_ASSERT(self->is<U>());
|
||||
return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address()));
|
||||
}
|
||||
|
||||
/*
|
||||
* The only sensible way to compare JSObject with == is by identity. We use
|
||||
* const& instead of * as a syntactic way to assert non-null. This leads to an
|
||||
|
|
|
@ -263,39 +263,6 @@ AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr =
|
|||
return newheader;
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::allocateSlots(JSContext *cx, uint32_t bytes, bool clear)
|
||||
{
|
||||
/*
|
||||
* ArrayBufferObjects delegate added properties to another JSObject, so
|
||||
* their internal layout can use the object's fixed slots for storage.
|
||||
* Set up the object to look like an array with an elements header.
|
||||
*/
|
||||
JS_ASSERT(!hasDynamicSlots() && !hasDynamicElements());
|
||||
|
||||
size_t usableSlots = ARRAYBUFFER_RESERVED_SLOTS - ObjectElements::VALUES_PER_HEADER;
|
||||
|
||||
if (bytes > sizeof(Value) * usableSlots) {
|
||||
ObjectElements *header = AllocateArrayBufferContents(cx, bytes);
|
||||
if (!header)
|
||||
return false;
|
||||
elements = header->elements();
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JSRuntime *rt = runtimeFromMainThread();
|
||||
rt->gcNursery.notifyNewElements(this, header);
|
||||
#endif
|
||||
} else {
|
||||
setFixedElements();
|
||||
if (clear)
|
||||
memset(dataPointer(), 0, bytes);
|
||||
}
|
||||
|
||||
initElementsHeader(getElementsHeader(), bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
PostBarrierTypedArrayObject(JSObject *obj)
|
||||
{
|
||||
|
@ -645,7 +612,7 @@ ArrayBufferObject::addView(ArrayBufferViewObject *view)
|
|||
SetViewList(this, view);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
ArrayBufferObject *
|
||||
ArrayBufferObject::create(JSContext *cx, uint32_t nbytes, bool clear /* = true */)
|
||||
{
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
|
@ -661,14 +628,37 @@ ArrayBufferObject::create(JSContext *cx, uint32_t nbytes, bool clear /* = true *
|
|||
return nullptr;
|
||||
obj->setLastPropertyInfallible(empty);
|
||||
|
||||
/*
|
||||
* The beginning stores an ObjectElements header structure holding the
|
||||
* length. The rest of it is a flat data store for the array buffer.
|
||||
*/
|
||||
if (!obj->as<ArrayBufferObject>().allocateSlots(cx, nbytes, clear))
|
||||
return nullptr;
|
||||
// ArrayBufferObjects delegate added properties to another JSObject, so
|
||||
// their internal layout can use the object's fixed slots for storage.
|
||||
// Set up the object to look like an array with an elements header.
|
||||
JS_ASSERT(!obj->hasDynamicSlots());
|
||||
JS_ASSERT(!obj->hasDynamicElements());
|
||||
|
||||
return obj;
|
||||
// The beginning stores an ObjectElements header structure holding the
|
||||
// length. The rest of it is a flat data store for the array buffer.
|
||||
size_t usableSlots = ARRAYBUFFER_RESERVED_SLOTS - ObjectElements::VALUES_PER_HEADER;
|
||||
|
||||
Handle<ArrayBufferObject*> buffer = obj.as<ArrayBufferObject>();
|
||||
|
||||
if (nbytes > sizeof(Value) * usableSlots) {
|
||||
ObjectElements *header = AllocateArrayBufferContents(cx, nbytes);
|
||||
if (!header)
|
||||
return nullptr;
|
||||
buffer->elements = header->elements();
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JSRuntime *rt = buffer->runtimeFromMainThread();
|
||||
rt->gcNursery.notifyNewElements(buffer, header);
|
||||
#endif
|
||||
} else {
|
||||
buffer->setFixedElements();
|
||||
if (clear)
|
||||
memset(buffer->dataPointer(), 0, nbytes);
|
||||
}
|
||||
|
||||
buffer->initElementsHeader(buffer->getElementsHeader(), nbytes);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -66,7 +66,7 @@ class ArrayBufferObject : public JSObject
|
|||
|
||||
static bool class_constructor(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
static JSObject *create(JSContext *cx, uint32_t nbytes, bool clear = true);
|
||||
static ArrayBufferObject *create(JSContext *cx, uint32_t nbytes, bool clear = true);
|
||||
|
||||
static JSObject *createSlice(JSContext *cx, Handle<ArrayBufferObject*> arrayBuffer,
|
||||
uint32_t begin, uint32_t end);
|
||||
|
@ -168,8 +168,6 @@ class ArrayBufferObject : public JSObject
|
|||
|
||||
void addView(ArrayBufferViewObject *view);
|
||||
|
||||
bool allocateSlots(JSContext *cx, uint32_t size, bool clear);
|
||||
|
||||
void changeContents(JSContext *cx, ObjectElements *newHeader);
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче