summaryrefslogtreecommitdiffstats
path: root/js/src/vm/UnboxedObject.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/UnboxedObject.h')
-rw-r--r--js/src/vm/UnboxedObject.h531
1 files changed, 0 insertions, 531 deletions
diff --git a/js/src/vm/UnboxedObject.h b/js/src/vm/UnboxedObject.h
deleted file mode 100644
index ecff8be5b..000000000
--- a/js/src/vm/UnboxedObject.h
+++ /dev/null
@@ -1,531 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef vm_UnboxedObject_h
-#define vm_UnboxedObject_h
-
-#include "jsgc.h"
-#include "jsobj.h"
-
-#include "vm/Runtime.h"
-#include "vm/TypeInference.h"
-
-namespace js {
-
-// Memory required for an unboxed value of a given type. Returns zero for types
-// which can't be used for unboxed objects.
-static inline size_t
-UnboxedTypeSize(JSValueType type)
-{
- switch (type) {
- case JSVAL_TYPE_BOOLEAN: return 1;
- case JSVAL_TYPE_INT32: return 4;
- case JSVAL_TYPE_DOUBLE: return 8;
- case JSVAL_TYPE_STRING: return sizeof(void*);
- case JSVAL_TYPE_OBJECT: return sizeof(void*);
- default: return 0;
- }
-}
-
-static inline bool
-UnboxedTypeNeedsPreBarrier(JSValueType type)
-{
- return type == JSVAL_TYPE_STRING || type == JSVAL_TYPE_OBJECT;
-}
-
-static inline bool
-UnboxedTypeNeedsPostBarrier(JSValueType type)
-{
- return type == JSVAL_TYPE_OBJECT;
-}
-
-// Class tracking information specific to unboxed objects.
-class UnboxedLayout : public mozilla::LinkedListElement<UnboxedLayout>
-{
- public:
- struct Property {
- PropertyName* name;
- uint32_t offset;
- JSValueType type;
-
- Property()
- : name(nullptr), offset(UINT32_MAX), type(JSVAL_TYPE_MAGIC)
- {}
- };
-
- typedef Vector<Property, 0, SystemAllocPolicy> PropertyVector;
-
- private:
- // If objects in this group have ever been converted to native objects,
- // these store the corresponding native group and initial shape for such
- // objects. Type information for this object is reflected in nativeGroup.
- GCPtrObjectGroup nativeGroup_;
- GCPtrShape nativeShape_;
-
- // Any script/pc which the associated group is created for.
- GCPtrScript allocationScript_;
- jsbytecode* allocationPc_;
-
- // If nativeGroup is set and this object originally had a TypeNewScript or
- // was keyed to an allocation site, this points to the group which replaced
- // this one. This link is only needed to keep the replacement group from
- // being GC'ed. If it were GC'ed and a new one regenerated later, that new
- // group might have a different allocation kind from this group.
- GCPtrObjectGroup replacementGroup_;
-
- // The following members are only used for unboxed plain objects.
-
- // All properties on objects with this layout, in enumeration order.
- PropertyVector properties_;
-
- // Byte size of the data for objects with this layout.
- size_t size_;
-
- // Any 'new' script information associated with this layout.
- TypeNewScript* newScript_;
-
- // List for use in tracing objects with this layout. This has the same
- // structure as the trace list on a TypeDescr.
- int32_t* traceList_;
-
- // If this layout has been used to construct script or JSON constant
- // objects, this code might be filled in to more quickly fill in objects
- // from an array of values.
- GCPtrJitCode constructorCode_;
-
- // The following members are only used for unboxed arrays.
-
- // The type of array elements.
- JSValueType elementType_;
-
- public:
- UnboxedLayout()
- : nativeGroup_(nullptr), nativeShape_(nullptr),
- allocationScript_(nullptr), allocationPc_(nullptr), replacementGroup_(nullptr),
- size_(0), newScript_(nullptr), traceList_(nullptr), constructorCode_(nullptr),
- elementType_(JSVAL_TYPE_MAGIC)
- {}
-
- bool initProperties(const PropertyVector& properties, size_t size) {
- size_ = size;
- return properties_.appendAll(properties);
- }
-
- void initArray(JSValueType elementType) {
- elementType_ = elementType;
- }
-
- ~UnboxedLayout() {
- if (newScript_)
- newScript_->clear();
- js_delete(newScript_);
- js_free(traceList_);
-
- nativeGroup_.init(nullptr);
- nativeShape_.init(nullptr);
- replacementGroup_.init(nullptr);
- constructorCode_.init(nullptr);
- }
-
- bool isArray() const {
- return elementType_ != JSVAL_TYPE_MAGIC;
- }
-
- void detachFromCompartment();
-
- const PropertyVector& properties() const {
- return properties_;
- }
-
- TypeNewScript* newScript() const {
- return newScript_;
- }
-
- void setNewScript(TypeNewScript* newScript, bool writeBarrier = true);
-
- JSScript* allocationScript() const {
- return allocationScript_;
- }
-
- jsbytecode* allocationPc() const {
- return allocationPc_;
- }
-
- void setAllocationSite(JSScript* script, jsbytecode* pc) {
- allocationScript_ = script;
- allocationPc_ = pc;
- }
-
- const int32_t* traceList() const {
- return traceList_;
- }
-
- void setTraceList(int32_t* traceList) {
- traceList_ = traceList;
- }
-
- const Property* lookup(JSAtom* atom) const {
- for (size_t i = 0; i < properties_.length(); i++) {
- if (properties_[i].name == atom)
- return &properties_[i];
- }
- return nullptr;
- }
-
- const Property* lookup(jsid id) const {
- if (JSID_IS_STRING(id))
- return lookup(JSID_TO_ATOM(id));
- return nullptr;
- }
-
- size_t size() const {
- return size_;
- }
-
- ObjectGroup* nativeGroup() const {
- return nativeGroup_;
- }
-
- Shape* nativeShape() const {
- return nativeShape_;
- }
-
- jit::JitCode* constructorCode() const {
- return constructorCode_;
- }
-
- void setConstructorCode(jit::JitCode* code) {
- constructorCode_ = code;
- }
-
- JSValueType elementType() const {
- return elementType_;
- }
-
- inline gc::AllocKind getAllocKind() const;
-
- void trace(JSTracer* trc);
-
- size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
-
- static bool makeNativeGroup(JSContext* cx, ObjectGroup* group);
- static bool makeConstructorCode(JSContext* cx, HandleObjectGroup group);
-};
-
-// Class for expando objects holding extra properties given to an unboxed plain
-// object. These objects behave identically to normal native plain objects, and
-// have a separate Class to distinguish them for memory usage reporting.
-class UnboxedExpandoObject : public NativeObject
-{
- public:
- static const Class class_;
-};
-
-// Class for a plain object using an unboxed representation. The physical
-// layout of these objects is identical to that of an InlineTypedObject, though
-// these objects use an UnboxedLayout instead of a TypeDescr to keep track of
-// how their properties are stored.
-class UnboxedPlainObject : public JSObject
-{
- // Optional object which stores extra properties on this object. This is
- // not automatically barriered to avoid problems if the object is converted
- // to a native. See ensureExpando().
- UnboxedExpandoObject* expando_;
-
- // Start of the inline data, which immediately follows the group and extra properties.
- uint8_t data_[1];
-
- public:
- static const Class class_;
-
- static bool obj_lookupProperty(JSContext* cx, HandleObject obj,
- HandleId id, MutableHandleObject objp,
- MutableHandleShape propp);
-
- static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
- Handle<PropertyDescriptor> desc,
- ObjectOpResult& result);
-
- static bool obj_hasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp);
-
- static bool obj_getProperty(JSContext* cx, HandleObject obj, HandleValue receiver,
- HandleId id, MutableHandleValue vp);
-
- static bool obj_setProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
- HandleValue receiver, ObjectOpResult& result);
-
- static bool obj_getOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
- MutableHandle<PropertyDescriptor> desc);
-
- static bool obj_deleteProperty(JSContext* cx, HandleObject obj, HandleId id,
- ObjectOpResult& result);
-
- static bool obj_enumerate(JSContext* cx, HandleObject obj, AutoIdVector& properties,
- bool enumerableOnly);
- static bool obj_watch(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable);
-
- inline const UnboxedLayout& layout() const;
-
- const UnboxedLayout& layoutDontCheckGeneration() const {
- return group()->unboxedLayoutDontCheckGeneration();
- }
-
- uint8_t* data() {
- return &data_[0];
- }
-
- UnboxedExpandoObject* maybeExpando() const {
- return expando_;
- }
-
- void initExpando() {
- expando_ = nullptr;
- }
-
- // For use during GC.
- JSObject** addressOfExpando() {
- return reinterpret_cast<JSObject**>(&expando_);
- }
-
- bool containsUnboxedOrExpandoProperty(ExclusiveContext* cx, jsid id) const;
-
- static UnboxedExpandoObject* ensureExpando(JSContext* cx, Handle<UnboxedPlainObject*> obj);
-
- bool setValue(ExclusiveContext* cx, const UnboxedLayout::Property& property, const Value& v);
- Value getValue(const UnboxedLayout::Property& property, bool maybeUninitialized = false);
-
- static bool convertToNative(JSContext* cx, JSObject* obj);
- static UnboxedPlainObject* create(ExclusiveContext* cx, HandleObjectGroup group,
- NewObjectKind newKind);
- static JSObject* createWithProperties(ExclusiveContext* cx, HandleObjectGroup group,
- NewObjectKind newKind, IdValuePair* properties);
-
- void fillAfterConvert(ExclusiveContext* cx,
- Handle<GCVector<Value>> values, size_t* valueCursor);
-
- static void trace(JSTracer* trc, JSObject* object);
-
- static size_t offsetOfExpando() {
- return offsetof(UnboxedPlainObject, expando_);
- }
-
- static size_t offsetOfData() {
- return offsetof(UnboxedPlainObject, data_[0]);
- }
-};
-
-// Try to construct an UnboxedLayout for each of the preliminary objects,
-// provided they all match the template shape. If successful, converts the
-// preliminary objects and their group to the new unboxed representation.
-bool
-TryConvertToUnboxedLayout(ExclusiveContext* cx, AutoEnterAnalysis& enter, Shape* templateShape,
- ObjectGroup* group, PreliminaryObjectArray* objects);
-
-inline gc::AllocKind
-UnboxedLayout::getAllocKind() const
-{
- MOZ_ASSERT(size());
- return gc::GetGCObjectKindForBytes(UnboxedPlainObject::offsetOfData() + size());
-}
-
-// Class for an array object using an unboxed representation.
-class UnboxedArrayObject : public JSObject
-{
- // Elements pointer for the object.
- uint8_t* elements_;
-
- // The nominal array length. This always fits in an int32_t.
- uint32_t length_;
-
- // Value indicating the allocated capacity and initialized length of the
- // array. The top CapacityBits bits are an index into CapacityArray, which
- // indicates the elements capacity. The low InitializedLengthBits store the
- // initialized length of the array.
- uint32_t capacityIndexAndInitializedLength_;
-
- // If the elements are inline, they will point here.
- uint8_t inlineElements_[1];
-
- public:
- static const uint32_t CapacityBits = 6;
- static const uint32_t CapacityShift = 26;
-
- static const uint32_t CapacityMask = uint32_t(-1) << CapacityShift;
- static const uint32_t InitializedLengthMask = (1 << CapacityShift) - 1;
-
- static const uint32_t MaximumCapacity = InitializedLengthMask;
- static const uint32_t MinimumDynamicCapacity = 8;
-
- static const uint32_t CapacityArray[];
-
- // Capacity index which indicates the array's length is also its capacity.
- static const uint32_t CapacityMatchesLengthIndex = 0;
-
- private:
- static inline uint32_t computeCapacity(uint32_t index, uint32_t length) {
- if (index == CapacityMatchesLengthIndex)
- return length;
- return CapacityArray[index];
- }
-
- static uint32_t chooseCapacityIndex(uint32_t capacity, uint32_t length);
- static uint32_t exactCapacityIndex(uint32_t capacity);
-
- public:
- static const Class class_;
-
- static bool obj_lookupProperty(JSContext* cx, HandleObject obj,
- HandleId id, MutableHandleObject objp,
- MutableHandleShape propp);
-
- static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
- Handle<PropertyDescriptor> desc,
- ObjectOpResult& result);
-
- static bool obj_hasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp);
-
- static bool obj_getProperty(JSContext* cx, HandleObject obj, HandleValue receiver,
- HandleId id, MutableHandleValue vp);
-
- static bool obj_setProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
- HandleValue receiver, ObjectOpResult& result);
-
- static bool obj_getOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
- MutableHandle<PropertyDescriptor> desc);
-
- static bool obj_deleteProperty(JSContext* cx, HandleObject obj, HandleId id,
- ObjectOpResult& result);
-
- static bool obj_enumerate(JSContext* cx, HandleObject obj, AutoIdVector& properties,
- bool enumerableOnly);
- static bool obj_watch(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable);
-
- inline const UnboxedLayout& layout() const;
-
- const UnboxedLayout& layoutDontCheckGeneration() const {
- return group()->unboxedLayoutDontCheckGeneration();
- }
-
- JSValueType elementType() const {
- return layoutDontCheckGeneration().elementType();
- }
-
- uint32_t elementSize() const {
- return UnboxedTypeSize(elementType());
- }
-
- static bool convertToNative(JSContext* cx, JSObject* obj);
- static UnboxedArrayObject* create(ExclusiveContext* cx, HandleObjectGroup group,
- uint32_t length, NewObjectKind newKind,
- uint32_t maxLength = MaximumCapacity);
-
- static bool convertToNativeWithGroup(ExclusiveContext* cx, JSObject* obj,
- ObjectGroup* group, Shape* shape);
- bool convertInt32ToDouble(ExclusiveContext* cx, ObjectGroup* group);
-
- void fillAfterConvert(ExclusiveContext* cx,
- Handle<GCVector<Value>> values, size_t* valueCursor);
-
- static void trace(JSTracer* trc, JSObject* object);
- static void objectMoved(JSObject* obj, const JSObject* old);
- static void finalize(FreeOp* fop, JSObject* obj);
-
- static size_t objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src,
- gc::AllocKind allocKind);
-
- uint8_t* elements() {
- return elements_;
- }
-
- bool hasInlineElements() const {
- return elements_ == &inlineElements_[0];
- }
-
- uint32_t length() const {
- return length_;
- }
-
- uint32_t initializedLength() const {
- return capacityIndexAndInitializedLength_ & InitializedLengthMask;
- }
-
- uint32_t capacityIndex() const {
- return (capacityIndexAndInitializedLength_ & CapacityMask) >> CapacityShift;
- }
-
- uint32_t capacity() const {
- return computeCapacity(capacityIndex(), length());
- }
-
- bool containsProperty(ExclusiveContext* cx, jsid id);
-
- bool setElement(ExclusiveContext* cx, size_t index, const Value& v);
- bool initElement(ExclusiveContext* cx, size_t index, const Value& v);
- void initElementNoTypeChange(size_t index, const Value& v);
- Value getElement(size_t index);
-
- template <JSValueType Type> inline bool setElementSpecific(ExclusiveContext* cx, size_t index,
- const Value& v);
- template <JSValueType Type> inline void setElementNoTypeChangeSpecific(size_t index, const Value& v);
- template <JSValueType Type> inline bool initElementSpecific(ExclusiveContext* cx, size_t index,
- const Value& v);
- template <JSValueType Type> inline void initElementNoTypeChangeSpecific(size_t index, const Value& v);
- template <JSValueType Type> inline Value getElementSpecific(size_t index);
- template <JSValueType Type> inline void triggerPreBarrier(size_t index);
-
- bool growElements(ExclusiveContext* cx, size_t cap);
- void shrinkElements(ExclusiveContext* cx, size_t cap);
-
- static uint32_t offsetOfElements() {
- return offsetof(UnboxedArrayObject, elements_);
- }
- static uint32_t offsetOfLength() {
- return offsetof(UnboxedArrayObject, length_);
- }
- static uint32_t offsetOfCapacityIndexAndInitializedLength() {
- return offsetof(UnboxedArrayObject, capacityIndexAndInitializedLength_);
- }
- static uint32_t offsetOfInlineElements() {
- return offsetof(UnboxedArrayObject, inlineElements_);
- }
-
- void setLengthInt32(uint32_t length) {
- MOZ_ASSERT(length <= INT32_MAX);
- length_ = length;
- }
-
- inline void setLength(ExclusiveContext* cx, uint32_t len);
- inline void setInitializedLength(uint32_t initlen);
-
- inline void setInitializedLengthNoBarrier(uint32_t initlen) {
- MOZ_ASSERT(initlen <= InitializedLengthMask);
- capacityIndexAndInitializedLength_ =
- (capacityIndexAndInitializedLength_ & CapacityMask) | initlen;
- }
-
- private:
- void setInlineElements() {
- elements_ = &inlineElements_[0];
- }
-
- void setCapacityIndex(uint32_t index) {
- MOZ_ASSERT(index <= (CapacityMask >> CapacityShift));
- capacityIndexAndInitializedLength_ =
- (index << CapacityShift) | initializedLength();
- }
-};
-
-} // namespace js
-
-namespace JS {
-
-template <>
-struct DeletePolicy<js::UnboxedLayout> : public js::GCManagedDeletePolicy<js::UnboxedLayout>
-{};
-
-} /* namespace JS */
-
-#endif /* vm_UnboxedObject_h */