mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 728411 - Move slot range operations into ObjectImpl. r=bhackett
--HG-- extra : rebase_source : 704d67267923e019df82de7f77f60b48c6c62128
This commit is contained in:
parent
e6976ebef4
commit
8b9d875ceb
@ -37,12 +37,15 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef jsgc_barrier_inl_h___
|
||||
#define jsgc_barrier_inl_h___
|
||||
|
||||
#include "jsgcmark.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
|
||||
#ifndef jsgc_barrier_inl_h___
|
||||
#define jsgc_barrier_inl_h___
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -101,6 +101,7 @@
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
#include "vm/RegExpObject-inl.h"
|
||||
#include "vm/RegExpStatics-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
@ -139,6 +139,7 @@
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
#include "vm/ArgumentsObject-inl.h"
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -374,22 +374,6 @@ Debug_SetValueRangeToCrashOnTouch(HeapValue *vec, size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *vec, size_t len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug_SetValueRangeToCrashOnTouch((Value *) vec, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *begin, HeapSlot *end)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug_SetValueRangeToCrashOnTouch((Value *) begin, end - begin);
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsinterp_h___ */
|
||||
|
@ -3808,43 +3808,6 @@ js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto,
|
||||
ps, fs, static_ps, static_fs, ctorp, ctorKind);
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::initSlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
|
||||
sp->init(comp, this, start++, *vector++);
|
||||
for (HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
|
||||
sp->init(comp, this, start++, *vector++);
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::copySlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
|
||||
sp->set(comp, this, start++, *vector++);
|
||||
for (HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
|
||||
sp->set(comp, this, start++, *vector++);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::invalidateSlotRange(size_t start, size_t length)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!isDenseArray());
|
||||
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
Debug_SetSlotRangeToCrashOnTouch(fixedStart, fixedEnd);
|
||||
Debug_SetSlotRangeToCrashOnTouch(slotsStart, slotsEnd);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan)
|
||||
{
|
||||
@ -4129,17 +4092,6 @@ JSObject::shrinkElements(JSContext *cx, unsigned newcap)
|
||||
Probes::resizeObject(cx, this, oldSize, computedSizeOfThisSlotsElements());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
JSObject::slotInRange(unsigned slot, SentinelAllowed sentinel) const
|
||||
{
|
||||
size_t capacity = numFixedSlots() + numDynamicSlots();
|
||||
if (sentinel == SENTINEL_ALLOWED)
|
||||
return slot <= capacity;
|
||||
return slot < capacity;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
static JSObject *
|
||||
js_InitNullClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
|
@ -541,17 +541,6 @@ struct JSObject : public js::ObjectImpl
|
||||
|
||||
static const uint32_t MAX_FIXED_SLOTS = 16;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Get internal pointers to the range of values starting at start and
|
||||
* running for length.
|
||||
*/
|
||||
inline void getSlotRangeUnchecked(size_t start, size_t length,
|
||||
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
|
||||
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd);
|
||||
inline void getSlotRange(size_t start, size_t length,
|
||||
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
|
||||
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd);
|
||||
public:
|
||||
|
||||
/* Accessors for properties. */
|
||||
@ -575,15 +564,9 @@ struct JSObject : public js::ObjectImpl
|
||||
|
||||
bool hasDynamicSlots() const { return slots != NULL; }
|
||||
|
||||
/* Compute dynamicSlotsCount() for this object. */
|
||||
inline size_t numDynamicSlots() const;
|
||||
|
||||
protected:
|
||||
inline bool hasContiguousSlots(size_t start, size_t count) const;
|
||||
|
||||
inline void initializeSlotRange(size_t start, size_t count);
|
||||
inline void invalidateSlotRange(size_t start, size_t count);
|
||||
|
||||
inline bool updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan);
|
||||
|
||||
public:
|
||||
@ -594,35 +577,8 @@ struct JSObject : public js::ObjectImpl
|
||||
inline void prepareSlotRangeForOverwrite(size_t start, size_t end);
|
||||
inline void prepareElementRangeForOverwrite(size_t start, size_t end);
|
||||
|
||||
/*
|
||||
* Initialize a flat array of slots to this object at a start slot. The
|
||||
* caller must ensure that are enough slots.
|
||||
*/
|
||||
void initSlotRange(size_t start, const js::Value *vector, size_t length);
|
||||
|
||||
/*
|
||||
* Copy a flat array of slots to this object at a start slot. Caller must
|
||||
* ensure there are enough slots in this object.
|
||||
*/
|
||||
void copySlotRange(size_t start, const js::Value *vector, size_t length);
|
||||
|
||||
inline uint32_t slotSpan() const;
|
||||
|
||||
void rollbackProperties(JSContext *cx, uint32_t slotSpan);
|
||||
|
||||
#ifdef DEBUG
|
||||
enum SentinelAllowed {
|
||||
SENTINEL_NOT_ALLOWED,
|
||||
SENTINEL_ALLOWED
|
||||
};
|
||||
|
||||
/*
|
||||
* Check that slot is in range for the object's allocated slots.
|
||||
* If sentinelAllowed then slot may equal the slot capacity.
|
||||
*/
|
||||
bool slotInRange(unsigned slot, SentinelAllowed sentinel = SENTINEL_NOT_ALLOWED) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
js::HeapSlot *getSlotAddressUnchecked(unsigned slot) {
|
||||
size_t fixed = numFixedSlots();
|
||||
@ -837,12 +793,9 @@ struct JSObject : public js::ObjectImpl
|
||||
inline void setArrayLength(JSContext *cx, uint32_t length);
|
||||
|
||||
inline uint32_t getDenseArrayCapacity();
|
||||
inline uint32_t getDenseArrayInitializedLength();
|
||||
inline void setDenseArrayLength(uint32_t length);
|
||||
inline void setDenseArrayInitializedLength(uint32_t length);
|
||||
inline void ensureDenseArrayInitializedLength(JSContext *cx, unsigned index, unsigned extra);
|
||||
inline js::HeapSlotArray getDenseArrayElements();
|
||||
inline const js::Value &getDenseArrayElement(unsigned idx);
|
||||
inline void setDenseArrayElement(unsigned idx, const js::Value &val);
|
||||
inline void initDenseArrayElement(unsigned idx, const js::Value &val);
|
||||
inline void setDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val);
|
||||
@ -1176,9 +1129,7 @@ struct JSObject : public js::ObjectImpl
|
||||
/* Direct subtypes of JSObject: */
|
||||
inline bool isArguments() const;
|
||||
inline bool isArrayBuffer() const;
|
||||
inline bool isArray() const;
|
||||
inline bool isDate() const;
|
||||
inline bool isDenseArray() const;
|
||||
inline bool isElementIterator() const;
|
||||
inline bool isError() const;
|
||||
inline bool isFunction() const;
|
||||
@ -1194,7 +1145,6 @@ struct JSObject : public js::ObjectImpl
|
||||
inline bool isRegExpStatics() const;
|
||||
inline bool isScope() const;
|
||||
inline bool isScript() const;
|
||||
inline bool isSlowArray() const;
|
||||
inline bool isStopIteration() const;
|
||||
inline bool isWeakMap() const;
|
||||
inline bool isXML() const;
|
||||
|
@ -372,12 +372,6 @@ JSObject::dynamicSlotIndex(size_t slot)
|
||||
return slot - numFixedSlots();
|
||||
}
|
||||
|
||||
inline size_t
|
||||
JSObject::numDynamicSlots() const
|
||||
{
|
||||
return dynamicSlotsCount(numFixedSlots(), slotSpan());
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setLastPropertyInfallible(const js::Shape *shape)
|
||||
{
|
||||
@ -512,13 +506,6 @@ JSObject::setDenseArrayLength(uint32_t length)
|
||||
getElementsHeader()->length = length;
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
JSObject::getDenseArrayInitializedLength()
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
return getElementsHeader()->initializedLength;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setDenseArrayInitializedLength(uint32_t length)
|
||||
{
|
||||
@ -543,20 +530,6 @@ JSObject::ensureElements(JSContext *cx, uint32_t capacity)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline js::HeapSlotArray
|
||||
JSObject::getDenseArrayElements()
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
return js::HeapSlotArray(elements);
|
||||
}
|
||||
|
||||
inline const js::Value &
|
||||
JSObject::getDenseArrayElement(unsigned idx)
|
||||
{
|
||||
JS_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
|
||||
return elements[idx];
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setDenseArrayElement(unsigned idx, const js::Value &val)
|
||||
{
|
||||
@ -932,25 +905,6 @@ inline bool JSObject::isWeakMap() const { return hasClass(&js::WeakMapClass); }
|
||||
inline bool JSObject::isWith() const { return hasClass(&js::WithClass); }
|
||||
inline bool JSObject::isXML() const { return hasClass(&js::XMLClass); }
|
||||
|
||||
inline bool JSObject::isArray() const
|
||||
{
|
||||
return isSlowArray() || isDenseArray();
|
||||
}
|
||||
|
||||
inline bool JSObject::isDenseArray() const
|
||||
{
|
||||
bool result = hasClass(&js::ArrayClass);
|
||||
JS_ASSERT_IF(result, elements != js::emptyObjectElements);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool JSObject::isSlowArray() const
|
||||
{
|
||||
bool result = hasClass(&js::SlowArrayClass);
|
||||
JS_ASSERT_IF(result, elements != js::emptyObjectElements);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::isXMLId() const
|
||||
{
|
||||
@ -967,60 +921,6 @@ JSObject::isQName() const
|
||||
|| hasClass(&js::AnyNameClass);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::getSlotRangeUnchecked(size_t start, size_t length,
|
||||
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
|
||||
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd)
|
||||
{
|
||||
JS_ASSERT(!isDenseArray());
|
||||
|
||||
size_t fixed = numFixedSlots();
|
||||
if (start < fixed) {
|
||||
if (start + length < fixed) {
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + length];
|
||||
*slotsStart = *slotsEnd = NULL;
|
||||
} else {
|
||||
size_t localCopy = fixed - start;
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + localCopy];
|
||||
*slotsStart = &slots[0];
|
||||
*slotsEnd = &slots[length - localCopy];
|
||||
}
|
||||
} else {
|
||||
*fixedStart = *fixedEnd = NULL;
|
||||
*slotsStart = &slots[start - fixed];
|
||||
*slotsEnd = &slots[start - fixed + length];
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::getSlotRange(size_t start, size_t length,
|
||||
js::HeapSlot **fixedStart, js::HeapSlot **fixedEnd,
|
||||
js::HeapSlot **slotsStart, js::HeapSlot **slotsEnd)
|
||||
{
|
||||
JS_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
|
||||
getSlotRangeUnchecked(start, length, fixedStart, fixedEnd, slotsStart, slotsEnd);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::initializeSlotRange(size_t start, size_t length)
|
||||
{
|
||||
/*
|
||||
* No bounds check, as this is used when the object's shape does not
|
||||
* reflect its allocated slots (updateSlotsForSpan).
|
||||
*/
|
||||
js::HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRangeUnchecked(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
|
||||
JSCompartment *comp = compartment();
|
||||
size_t offset = start;
|
||||
for (js::HeapSlot *sp = fixedStart; sp != fixedEnd; sp++)
|
||||
sp->init(comp, this, offset++, js::UndefinedValue());
|
||||
for (js::HeapSlot *sp = slotsStart; sp != slotsEnd; sp++)
|
||||
sp->init(comp, this, offset++, js::UndefinedValue());
|
||||
}
|
||||
|
||||
/* static */ inline JSObject *
|
||||
JSObject::create(JSContext *cx, js::gc::AllocKind kind,
|
||||
js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
|
||||
@ -1124,14 +1024,6 @@ JSObject::principals(JSContext *cx)
|
||||
return cx->compartment ? cx->compartment->principals : NULL;
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
JSObject::slotSpan() const
|
||||
{
|
||||
if (inDictionaryMode())
|
||||
return lastProperty()->base()->slotSpan();
|
||||
return lastProperty()->slotSpan();
|
||||
}
|
||||
|
||||
inline js::HeapSlot &
|
||||
JSObject::nativeGetSlotRef(unsigned slot)
|
||||
{
|
||||
|
@ -14,11 +14,163 @@
|
||||
#include "jscompartment.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsgcmark.h"
|
||||
#include "jsinterp.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
#include "ObjectImpl.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *vec, size_t len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug_SetValueRangeToCrashOnTouch((Value *) vec, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
Debug_SetSlotRangeToCrashOnTouch(HeapSlot *begin, HeapSlot *end)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug_SetValueRangeToCrashOnTouch((Value *) begin, end - begin);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isExtensible() const
|
||||
{
|
||||
return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isDenseArray() const
|
||||
{
|
||||
bool result = hasClass(&ArrayClass);
|
||||
MOZ_ASSERT_IF(result, elements != emptyObjectElements);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isSlowArray() const
|
||||
{
|
||||
bool result = hasClass(&SlowArrayClass);
|
||||
MOZ_ASSERT_IF(result, elements != emptyObjectElements);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isArray() const
|
||||
{
|
||||
return isSlowArray() || isDenseArray();
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
js::ObjectImpl::getDenseArrayInitializedLength()
|
||||
{
|
||||
MOZ_ASSERT(isDenseArray());
|
||||
return getElementsHeader()->initializedLength;
|
||||
}
|
||||
|
||||
inline js::HeapSlotArray
|
||||
js::ObjectImpl::getDenseArrayElements()
|
||||
{
|
||||
MOZ_ASSERT(isDenseArray());
|
||||
return HeapSlotArray(elements);
|
||||
}
|
||||
|
||||
inline const js::Value &
|
||||
js::ObjectImpl::getDenseArrayElement(unsigned idx)
|
||||
{
|
||||
MOZ_ASSERT(isDenseArray() && idx < getDenseArrayInitializedLength());
|
||||
return elements[idx];
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ObjectImpl::getSlotRangeUnchecked(size_t start, size_t length,
|
||||
HeapSlot **fixedStart, HeapSlot **fixedEnd,
|
||||
HeapSlot **slotsStart, HeapSlot **slotsEnd)
|
||||
{
|
||||
MOZ_ASSERT(!isDenseArray());
|
||||
MOZ_ASSERT(start + length >= start);
|
||||
|
||||
size_t fixed = numFixedSlots();
|
||||
if (start < fixed) {
|
||||
if (start + length < fixed) {
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + length];
|
||||
*slotsStart = *slotsEnd = NULL;
|
||||
} else {
|
||||
size_t localCopy = fixed - start;
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + localCopy];
|
||||
*slotsStart = &slots[0];
|
||||
*slotsEnd = &slots[length - localCopy];
|
||||
}
|
||||
} else {
|
||||
*fixedStart = *fixedEnd = NULL;
|
||||
*slotsStart = &slots[start - fixed];
|
||||
*slotsEnd = &slots[start - fixed + length];
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ObjectImpl::getSlotRange(size_t start, size_t length,
|
||||
HeapSlot **fixedStart, HeapSlot **fixedEnd,
|
||||
HeapSlot **slotsStart, HeapSlot **slotsEnd)
|
||||
{
|
||||
MOZ_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
|
||||
getSlotRangeUnchecked(start, length, fixedStart, fixedEnd, slotsStart, slotsEnd);
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ObjectImpl::invalidateSlotRange(size_t start, size_t length)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!isDenseArray());
|
||||
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
Debug_SetSlotRangeToCrashOnTouch(fixedStart, fixedEnd);
|
||||
Debug_SetSlotRangeToCrashOnTouch(slotsStart, slotsEnd);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ObjectImpl::initializeSlotRange(size_t start, size_t length)
|
||||
{
|
||||
/*
|
||||
* No bounds check, as this is used when the object's shape does not
|
||||
* reflect its allocated slots (updateSlotsForSpan).
|
||||
*/
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRangeUnchecked(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
|
||||
JSCompartment *comp = compartment();
|
||||
size_t offset = start;
|
||||
for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
|
||||
sp->init(comp, this->asObjectPtr(), offset++, UndefinedValue());
|
||||
for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
|
||||
sp->init(comp, this->asObjectPtr(), offset++, UndefinedValue());
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
js::ObjectImpl::slotSpan() const
|
||||
{
|
||||
if (inDictionaryMode())
|
||||
return lastProperty()->base()->slotSpan();
|
||||
return lastProperty()->slotSpan();
|
||||
}
|
||||
|
||||
inline size_t
|
||||
js::ObjectImpl::numDynamicSlots() const
|
||||
{
|
||||
return dynamicSlotsCount(numFixedSlots(), slotSpan());
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isNative() const
|
||||
{
|
||||
@ -138,10 +290,4 @@ js::ObjectImpl::writeBarrierPost(ObjectImpl *obj, void *addr)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::isExtensible() const
|
||||
{
|
||||
return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
|
||||
}
|
||||
|
||||
#endif /* ObjectImpl_inl_h__ */
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "ObjectImpl.h"
|
||||
|
||||
#include "gc/Barrier-inl.h"
|
||||
|
||||
#include "ObjectImpl-inl.h"
|
||||
|
||||
using namespace js;
|
||||
@ -23,6 +25,41 @@ static ObjectElements emptyElementsHeader(0, 0);
|
||||
HeapSlot *js::emptyObjectElements =
|
||||
reinterpret_cast<HeapSlot *>(uintptr_t(&emptyElementsHeader) + sizeof(ObjectElements));
|
||||
|
||||
void
|
||||
js::ObjectImpl::initSlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
|
||||
sp->init(comp, this->asObjectPtr(), start++, *vector++);
|
||||
for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
|
||||
sp->init(comp, this->asObjectPtr(), start++, *vector++);
|
||||
}
|
||||
|
||||
void
|
||||
js::ObjectImpl::copySlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
|
||||
sp->set(comp, this->asObjectPtr(), start++, *vector++);
|
||||
for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
|
||||
sp->set(comp, this->asObjectPtr(), start++, *vector++);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
js::ObjectImpl::slotInRange(unsigned slot, SentinelAllowed sentinel) const
|
||||
{
|
||||
size_t capacity = numFixedSlots() + numDynamicSlots();
|
||||
if (sentinel == SENTINEL_ALLOWED)
|
||||
return slot <= capacity;
|
||||
return slot < capacity;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
/*
|
||||
* Work around a compiler bug in MSVC9 and above, where inlining this function
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
class ObjectImpl;
|
||||
|
||||
/*
|
||||
* Header structure for object element arrays. This structure is immediately
|
||||
* followed by an array of elements, with the elements member in an object
|
||||
@ -28,6 +30,7 @@ namespace js {
|
||||
class ObjectElements
|
||||
{
|
||||
friend struct ::JSObject;
|
||||
friend class ObjectImpl;
|
||||
|
||||
/* Number of allocated slots. */
|
||||
uint32_t capacity;
|
||||
@ -171,11 +174,72 @@ class ObjectImpl : public gc::Cell
|
||||
|
||||
JSObject * asObjectPtr() { return reinterpret_cast<JSObject *>(this); }
|
||||
|
||||
/* These functions are public, and they should remain public. */
|
||||
|
||||
public:
|
||||
JSObject * getProto() const {
|
||||
return type_->proto;
|
||||
}
|
||||
|
||||
inline bool isExtensible() const;
|
||||
|
||||
/*
|
||||
* XXX Once the property/element split of bug 586842 is complete, these
|
||||
* methods should move back to JSObject.
|
||||
*/
|
||||
inline bool isDenseArray() const;
|
||||
inline bool isSlowArray() const;
|
||||
inline bool isArray() const;
|
||||
|
||||
inline HeapSlotArray getDenseArrayElements();
|
||||
inline const Value & getDenseArrayElement(unsigned idx);
|
||||
inline uint32_t getDenseArrayInitializedLength();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Get internal pointers to the range of values starting at start and
|
||||
* running for length.
|
||||
*/
|
||||
inline void getSlotRangeUnchecked(size_t start, size_t length,
|
||||
HeapSlot **fixedStart, HeapSlot **fixedEnd,
|
||||
HeapSlot **slotsStart, HeapSlot **slotsEnd);
|
||||
inline void getSlotRange(size_t start, size_t length,
|
||||
HeapSlot **fixedStart, HeapSlot **fixedEnd,
|
||||
HeapSlot **slotsStart, HeapSlot **slotsEnd);
|
||||
|
||||
protected:
|
||||
friend struct GCMarker;
|
||||
friend struct Shape;
|
||||
friend class NewObjectCache;
|
||||
|
||||
inline void invalidateSlotRange(size_t start, size_t count);
|
||||
inline void initializeSlotRange(size_t start, size_t count);
|
||||
|
||||
/*
|
||||
* Initialize a flat array of slots to this object at a start slot. The
|
||||
* caller must ensure that are enough slots.
|
||||
*/
|
||||
void initSlotRange(size_t start, const Value *vector, size_t length);
|
||||
|
||||
/*
|
||||
* Copy a flat array of slots to this object at a start slot. Caller must
|
||||
* ensure there are enough slots in this object.
|
||||
*/
|
||||
void copySlotRange(size_t start, const Value *vector, size_t length);
|
||||
|
||||
#ifdef DEBUG
|
||||
enum SentinelAllowed {
|
||||
SENTINEL_NOT_ALLOWED,
|
||||
SENTINEL_ALLOWED
|
||||
};
|
||||
|
||||
/*
|
||||
* Check that slot is in range for the object's allocated slots.
|
||||
* If sentinelAllowed then slot may equal the slot capacity.
|
||||
*/
|
||||
bool slotInRange(unsigned slot, SentinelAllowed sentinel = SENTINEL_NOT_ALLOWED) const;
|
||||
#endif
|
||||
|
||||
/* Minimum size for dynamically allocated slots. */
|
||||
static const uint32_t SLOT_CAPACITY_MIN = 8;
|
||||
|
||||
@ -215,6 +279,11 @@ class ObjectImpl : public gc::Cell
|
||||
*/
|
||||
bool hasLazyType() const { return type_->lazy(); }
|
||||
|
||||
inline uint32_t slotSpan() const;
|
||||
|
||||
/* Compute dynamicSlotsCount() for this object. */
|
||||
inline size_t numDynamicSlots() const;
|
||||
|
||||
inline bool isNative() const;
|
||||
|
||||
const Shape * nativeLookup(JSContext *cx, jsid id);
|
||||
@ -304,15 +373,6 @@ class ObjectImpl : public gc::Cell
|
||||
}
|
||||
static size_t getPrivateDataOffset(size_t nfixed) { return getFixedSlotOffset(nfixed); }
|
||||
static size_t offsetOfSlots() { return offsetof(ObjectImpl, slots); }
|
||||
|
||||
/* These functions are public, and they should remain public. */
|
||||
|
||||
public:
|
||||
JSObject * getProto() const {
|
||||
return type_->proto;
|
||||
}
|
||||
|
||||
inline bool isExtensible() const;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
Loading…
Reference in New Issue
Block a user