Bug 1073842 - Add NativeObject subclass of JSObject, remove ObjectImpl, r=luke.

This commit is contained in:
Brian Hackett 2014-10-02 19:32:39 -07:00
Родитель 4e2581f465
Коммит b6419e9f3a
152 изменённых файлов: 3671 добавлений и 3187 удалений

Просмотреть файл

@ -885,6 +885,24 @@ class RootedBase<JSObject*>
JS::Handle<U*> as() const;
};
/*
* Augment the generic Handle<T> interface when T = JSObject* with
* downcasting operations.
*
* Given a Handle<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 HandleBase<JSObject*>
{
public:
template <class U>
JS::Handle<U*> as() const;
};
/* Interface substitute for Rooted<T> which does not root the variable's memory. */
template <typename T>
class FakeRooted : public RootedBase<T>
@ -1003,6 +1021,11 @@ template <typename T> class MaybeRooted<T, CanGC>
static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
return v;
}
template <typename T2>
static inline JS::Handle<T2*> downcastHandle(HandleType v) {
return v.template as<T2>();
}
};
template <typename T> class MaybeRooted<T, NoGC>
@ -1019,6 +1042,11 @@ template <typename T> class MaybeRooted<T, NoGC>
static JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
MOZ_CRASH("Bad conversion");
}
template <typename T2>
static inline T2* downcastHandle(HandleType v) {
return &v->template as<T2>();
}
};
} /* namespace js */

Просмотреть файл

@ -44,6 +44,7 @@
#include "jsobjinlines.h"
#include "vm/ArrayBufferObject-inl.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::jit;
@ -117,7 +118,7 @@ HasPureCoercion(JSContext *cx, HandleValue v)
jsid toString = NameToId(cx->names().toString);
if (v.toObject().is<JSFunction>() &&
HasObjectValueOf(&v.toObject(), cx) &&
ClassMethodIsNative(cx, &v.toObject(), &JSFunction::class_, toString, fun_toString))
ClassMethodIsNative(cx, &v.toObject().as<JSFunction>(), &JSFunction::class_, toString, fun_toString))
{
return true;
}
@ -897,7 +898,7 @@ CreateExportObject(JSContext *cx, Handle<AsmJSModuleObject*> moduleObj)
}
gc::AllocKind allocKind = gc::GetGCObjectKind(module.numExportedFunctions());
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
if (!obj)
return nullptr;

Просмотреть файл

@ -868,9 +868,10 @@ AsmJSModuleObject::create(ExclusiveContext *cx, ScopedJSDeletePtr<AsmJSModule> *
JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleObject::class_, nullptr, nullptr);
if (!obj)
return nullptr;
AsmJSModuleObject *nobj = &obj->as<AsmJSModuleObject>();
obj->setReservedSlot(MODULE_SLOT, PrivateValue(module->forget()));
return &obj->as<AsmJSModuleObject>();
nobj->setReservedSlot(MODULE_SLOT, PrivateValue(module->forget()));
return nobj;
}
AsmJSModule &

Просмотреть файл

@ -1437,7 +1437,7 @@ LookupAsmJSModuleInCache(ExclusiveContext *cx,
// directly to user script) which manages the lifetime of an AsmJSModule. A
// JSObject is necessary since we want LinkAsmJS/CallAsmJS JSFunctions to be
// able to point to their module via their extended slots.
class AsmJSModuleObject : public JSObject
class AsmJSModuleObject : public NativeObject
{
static const unsigned MODULE_SLOT = 0;

Просмотреть файл

@ -633,7 +633,7 @@ Collator(JSContext *cx, CallArgs args, bool construct)
if (!obj)
return false;
obj->setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
obj->as<NativeObject>().setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
}
// 10.1.2.1 steps 1 and 2; 10.1.3.1 steps 1 and 2
@ -669,7 +669,7 @@ js::intl_Collator(JSContext *cx, unsigned argc, Value *vp)
static void
collator_finalize(FreeOp *fop, JSObject *obj)
{
UCollator *coll = static_cast<UCollator*>(obj->getReservedSlot(UCOLLATOR_SLOT).toPrivate());
UCollator *coll = static_cast<UCollator*>(obj->as<NativeObject>().getReservedSlot(UCOLLATOR_SLOT).toPrivate());
if (coll)
ucol_close(coll);
}
@ -732,7 +732,7 @@ InitCollatorClass(JSContext *cx, HandleObject Intl, Handle<GlobalObject*> global
bool
GlobalObject::initCollatorProto(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject proto(cx, global->createBlankPrototype(cx, &CollatorClass));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &CollatorClass));
if (!proto)
return false;
proto->setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
@ -1006,12 +1006,12 @@ js::intl_CompareStrings(JSContext *cx, unsigned argc, Value *vp)
bool isCollatorInstance = collator->getClass() == &CollatorClass;
UCollator *coll;
if (isCollatorInstance) {
coll = static_cast<UCollator *>(collator->getReservedSlot(UCOLLATOR_SLOT).toPrivate());
coll = static_cast<UCollator *>(collator->as<NativeObject>().getReservedSlot(UCOLLATOR_SLOT).toPrivate());
if (!coll) {
coll = NewUCollator(cx, collator);
if (!coll)
return false;
collator->setReservedSlot(UCOLLATOR_SLOT, PrivateValue(coll));
collator->as<NativeObject>().setReservedSlot(UCOLLATOR_SLOT, PrivateValue(coll));
}
} else {
// There's no good place to cache the ICU collator for an object
@ -1122,7 +1122,7 @@ NumberFormat(JSContext *cx, CallArgs args, bool construct)
if (!obj)
return false;
obj->setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
obj->as<NativeObject>().setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
}
// 11.1.2.1 steps 1 and 2; 11.1.3.1 steps 1 and 2
@ -1160,7 +1160,7 @@ static void
numberFormat_finalize(FreeOp *fop, JSObject *obj)
{
UNumberFormat *nf =
static_cast<UNumberFormat*>(obj->getReservedSlot(UNUMBER_FORMAT_SLOT).toPrivate());
static_cast<UNumberFormat*>(obj->as<NativeObject>().getReservedSlot(UNUMBER_FORMAT_SLOT).toPrivate());
if (nf)
unum_close(nf);
}
@ -1223,7 +1223,7 @@ InitNumberFormatClass(JSContext *cx, HandleObject Intl, Handle<GlobalObject*> gl
bool
GlobalObject::initNumberFormatProto(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject proto(cx, global->createBlankPrototype(cx, &NumberFormatClass));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &NumberFormatClass));
if (!proto)
return false;
proto->setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
@ -1465,12 +1465,12 @@ js::intl_FormatNumber(JSContext *cx, unsigned argc, Value *vp)
bool isNumberFormatInstance = numberFormat->getClass() == &NumberFormatClass;
UNumberFormat *nf;
if (isNumberFormatInstance) {
nf = static_cast<UNumberFormat*>(numberFormat->getReservedSlot(UNUMBER_FORMAT_SLOT).toPrivate());
nf = static_cast<UNumberFormat*>(numberFormat->as<NativeObject>().getReservedSlot(UNUMBER_FORMAT_SLOT).toPrivate());
if (!nf) {
nf = NewUNumberFormat(cx, numberFormat);
if (!nf)
return false;
numberFormat->setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nf));
numberFormat->as<NativeObject>().setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nf));
}
} else {
// There's no good place to cache the ICU number format for an object
@ -1579,7 +1579,7 @@ DateTimeFormat(JSContext *cx, CallArgs args, bool construct)
if (!obj)
return false;
obj->setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
obj->as<NativeObject>().setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
}
// 12.1.2.1 steps 1 and 2; 12.1.3.1 steps 1 and 2
@ -1616,7 +1616,7 @@ js::intl_DateTimeFormat(JSContext *cx, unsigned argc, Value *vp)
static void
dateTimeFormat_finalize(FreeOp *fop, JSObject *obj)
{
UDateFormat *df = static_cast<UDateFormat*>(obj->getReservedSlot(UDATE_FORMAT_SLOT).toPrivate());
UDateFormat *df = static_cast<UDateFormat*>(obj->as<NativeObject>().getReservedSlot(UDATE_FORMAT_SLOT).toPrivate());
if (df)
udat_close(df);
}
@ -1679,7 +1679,7 @@ InitDateTimeFormatClass(JSContext *cx, HandleObject Intl, Handle<GlobalObject*>
bool
GlobalObject::initDateTimeFormatProto(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject proto(cx, global->createBlankPrototype(cx, &DateTimeFormatClass));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &DateTimeFormatClass));
if (!proto)
return false;
proto->setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
@ -1966,12 +1966,12 @@ js::intl_FormatDateTime(JSContext *cx, unsigned argc, Value *vp)
bool isDateTimeFormatInstance = dateTimeFormat->getClass() == &DateTimeFormatClass;
UDateFormat *df;
if (isDateTimeFormatInstance) {
df = static_cast<UDateFormat*>(dateTimeFormat->getReservedSlot(UDATE_FORMAT_SLOT).toPrivate());
df = static_cast<UDateFormat*>(dateTimeFormat->as<NativeObject>().getReservedSlot(UDATE_FORMAT_SLOT).toPrivate());
if (!df) {
df = NewUDateFormat(cx, dateTimeFormat);
if (!df)
return false;
dateTimeFormat->setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(df));
dateTimeFormat->as<NativeObject>().setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(df));
}
} else {
// There's no good place to cache the ICU date-time format for an object

Просмотреть файл

@ -19,6 +19,8 @@
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using mozilla::ArrayLength;
@ -840,7 +842,7 @@ HashableValue::mark(JSTracer *trc) const
namespace {
class MapIteratorObject : public JSObject
class MapIteratorObject : public NativeObject
{
public:
static const Class class_;
@ -901,8 +903,8 @@ GlobalObject::initMapIteratorProto(JSContext *cx, Handle<GlobalObject *> global)
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
if (!base)
return false;
Rooted<JSObject*> proto(cx,
NewObjectWithGivenProto(cx, &MapIteratorObject::class_, base, global));
RootedNativeObject proto(cx,
NewNativeObjectWithGivenProto(cx, &MapIteratorObject::class_, base, global));
if (!proto)
return false;
proto->setSlot(MapIteratorObject::RangeSlot, PrivateValue(nullptr));
@ -925,7 +927,7 @@ MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data,
if (!range)
return nullptr;
JSObject *iterobj = NewObjectWithGivenProto(cx, &class_, proto, global);
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
if (!iterobj) {
js_delete(range);
return nullptr;
@ -1044,7 +1046,7 @@ static JSObject *
InitClass(JSContext *cx, Handle<GlobalObject*> global, const Class *clasp, JSProtoKey key, Native construct,
const JSPropertySpec *properties, const JSFunctionSpec *methods)
{
Rooted<JSObject*> proto(cx, global->createBlankPrototype(cx, clasp));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, clasp));
if (!proto)
return nullptr;
proto->setPrivate(nullptr);
@ -1198,7 +1200,7 @@ MapObject::set(JSContext *cx, HandleObject obj, HandleValue k, HandleValue v)
MapObject*
MapObject::create(JSContext *cx)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
if (!obj)
return nullptr;
@ -1278,7 +1280,7 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
bool
MapObject::is(HandleValue v)
{
return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().getPrivate();
return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().as<MapObject>().getPrivate();
}
#define ARG0_KEY(cx, args, key) \
@ -1489,7 +1491,7 @@ js_InitMapClass(JSContext *cx, HandleObject obj)
namespace {
class SetIteratorObject : public JSObject
class SetIteratorObject : public NativeObject
{
public:
static const Class class_;
@ -1550,7 +1552,8 @@ GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
if (!base)
return false;
RootedObject proto(cx, NewObjectWithGivenProto(cx, &SetIteratorObject::class_, base, global));
RootedNativeObject proto(cx, NewNativeObjectWithGivenProto(cx, &SetIteratorObject::class_,
base, global));
if (!proto)
return false;
proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(nullptr));
@ -1573,7 +1576,7 @@ SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
if (!range)
return nullptr;
JSObject *iterobj = NewObjectWithGivenProto(cx, &class_, proto, global);
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
if (!iterobj) {
js_delete(range);
return nullptr;
@ -1742,7 +1745,7 @@ SetObject::add(JSContext *cx, HandleObject obj, HandleValue k)
SetObject*
SetObject::create(JSContext *cx)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
if (!obj)
return nullptr;
@ -1812,7 +1815,7 @@ SetObject::construct(JSContext *cx, unsigned argc, Value *vp)
bool
SetObject::is(HandleValue v)
{
return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().getPrivate();
return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().as<SetObject>().getPrivate();
}
ValueSet &

Просмотреть файл

@ -85,7 +85,7 @@ typedef OrderedHashSet<HashableValue,
HashableValue::Hasher,
RuntimeAllocPolicy> ValueSet;
class MapObject : public JSObject {
class MapObject : public NativeObject {
public:
enum IteratorKind { Keys, Values, Entries };
@ -130,7 +130,7 @@ class MapObject : public JSObject {
static bool clear(JSContext *cx, unsigned argc, Value *vp);
};
class SetObject : public JSObject {
class SetObject : public NativeObject {
public:
enum IteratorKind { Values, Entries };
static JSObject *initClass(JSContext *cx, JSObject *obj);

Просмотреть файл

@ -16,6 +16,8 @@
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::types;
@ -46,7 +48,7 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input, const MatchPairs
size_t numPairs = matches.length();
MOZ_ASSERT(numPairs > 0);
RootedObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(cx, numPairs, templateObject));
RootedArrayObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(cx, numPairs, templateObject));
if (!arr)
return false;
@ -71,21 +73,21 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input, const MatchPairs
}
/* Set the |index| property. (TemplateObject positions it in slot 0) */
arr->nativeSetSlot(0, Int32Value(matches[0].start));
arr->setSlot(0, Int32Value(matches[0].start));
/* Set the |input| property. (TemplateObject positions it in slot 1) */
arr->nativeSetSlot(1, StringValue(input));
arr->setSlot(1, StringValue(input));
#ifdef DEBUG
RootedValue test(cx);
RootedId id(cx, NameToId(cx->names().index));
if (!baseops::GetProperty(cx, arr, id, &test))
return false;
MOZ_ASSERT(test == arr->nativeGetSlot(0));
MOZ_ASSERT(test == arr->getSlot(0));
id = NameToId(cx->names().input);
if (!baseops::GetProperty(cx, arr, id, &test))
return false;
MOZ_ASSERT(test == arr->nativeGetSlot(1));
MOZ_ASSERT(test == arr->getSlot(1));
#endif
rval.setObject(*arr);
@ -508,7 +510,7 @@ js_InitRegExpClass(JSContext *cx, HandleObject obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedObject proto(cx, global->createBlankPrototype(cx, &RegExpObject::class_));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &RegExpObject::class_));
if (!proto)
return nullptr;
proto->setPrivate(nullptr);

Просмотреть файл

@ -7,13 +7,12 @@
#ifndef builtin_SymbolObject_h
#define builtin_SymbolObject_h
#include "jsobj.h"
#include "vm/ObjectImpl.h"
#include "vm/Symbol.h"
namespace js {
class SymbolObject : public JSObject
class SymbolObject : public NativeObject
{
/* Stores this Symbol object's [[PrimitiveValue]]. */
static const unsigned PRIMITIVE_VALUE_SLOT = 0;

Просмотреть файл

@ -36,6 +36,8 @@
#include "jscntxtinlines.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace JS;
@ -1369,7 +1371,7 @@ SetIonCheckGraphCoherency(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
class CloneBufferObject : public JSObject {
class CloneBufferObject : public NativeObject {
static const JSPropertySpec props_[2];
static const size_t DATA_SLOT = 0;
static const size_t LENGTH_SLOT = 1;
@ -1382,8 +1384,8 @@ class CloneBufferObject : public JSObject {
RootedObject obj(cx, JS_NewObject(cx, Jsvalify(&class_), JS::NullPtr(), JS::NullPtr()));
if (!obj)
return nullptr;
obj->setReservedSlot(DATA_SLOT, PrivateValue(nullptr));
obj->setReservedSlot(LENGTH_SLOT, Int32Value(0));
obj->as<CloneBufferObject>().setReservedSlot(DATA_SLOT, PrivateValue(nullptr));
obj->as<CloneBufferObject>().setReservedSlot(LENGTH_SLOT, Int32Value(0));
if (!JS_DefineProperties(cx, obj, props_))
return nullptr;
@ -1976,7 +1978,7 @@ FindPath(JSContext *cx, unsigned argc, jsval *vp)
//
// { node: undefined, edge: <string> }
size_t length = nodes.length();
RootedObject result(cx, NewDenseFullyAllocatedArray(cx, length));
RootedArrayObject result(cx, NewDenseFullyAllocatedArray(cx, length));
if (!result)
return false;
result->ensureDenseInitializedLength(cx, 0, length);

Просмотреть файл

@ -25,6 +25,7 @@
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Shape-inl.h"
using mozilla::AssertedCast;
@ -1123,21 +1124,19 @@ StructMetaTypeDescr::construct(JSContext *cx, unsigned int argc, Value *vp)
size_t
StructTypeDescr::fieldCount() const
{
return getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).toObject().getDenseInitializedLength();
return fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).getDenseInitializedLength();
}
size_t
StructTypeDescr::maybeForwardedFieldCount() const
{
JSObject *fieldNames =
MaybeForwarded(&getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).toObject());
return fieldNames->getDenseInitializedLength();
return maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).getDenseInitializedLength();
}
bool
StructTypeDescr::fieldIndex(jsid id, size_t *out) const
{
JSObject &fieldNames = getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).toObject();
NativeObject &fieldNames = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES);
size_t l = fieldNames.getDenseInitializedLength();
for (size_t i = 0; i < l; i++) {
JSAtom &a = fieldNames.getDenseElement(i).toString()->asAtom();
@ -1152,15 +1151,13 @@ StructTypeDescr::fieldIndex(jsid id, size_t *out) const
JSAtom &
StructTypeDescr::fieldName(size_t index) const
{
JSObject &fieldNames = getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).toObject();
return fieldNames.getDenseElement(index).toString()->asAtom();
return fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES).getDenseElement(index).toString()->asAtom();
}
size_t
StructTypeDescr::fieldOffset(size_t index) const
{
JSObject &fieldOffsets =
getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS).toObject();
NativeObject &fieldOffsets = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
}
@ -1168,8 +1165,7 @@ StructTypeDescr::fieldOffset(size_t index) const
size_t
StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
{
JSObject &fieldOffsets =
*MaybeForwarded(&getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS).toObject());
NativeObject &fieldOffsets = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
}
@ -1177,8 +1173,7 @@ StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
SizedTypeDescr&
StructTypeDescr::fieldDescr(size_t index) const
{
JSObject &fieldDescrs =
getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_TYPES).toObject();
NativeObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
return fieldDescrs.getDenseElement(index).toObject().as<SizedTypeDescr>();
}
@ -1186,8 +1181,7 @@ StructTypeDescr::fieldDescr(size_t index) const
SizedTypeDescr&
StructTypeDescr::maybeForwardedFieldDescr(size_t index) const
{
JSObject &fieldDescrs =
*MaybeForwarded(&getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_TYPES).toObject());
NativeObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
JSObject &descr =
*MaybeForwarded(&fieldDescrs.getDenseElement(index).toObject());
@ -1301,7 +1295,7 @@ template<typename T>
static JSObject *
DefineMetaTypeDescr(JSContext *cx,
Handle<GlobalObject*> global,
HandleObject module,
HandleNativeObject module,
TypedObjectModuleObject::Slot protoSlot)
{
RootedAtom className(cx, Atomize(cx, T::class_.name,
@ -1470,7 +1464,7 @@ TypedObject::offset() const
{
if (is<InlineOpaqueTypedObject>())
return 0;
return getReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET).toInt32();
return fakeNativeGetReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET).toInt32();
}
int32_t
@ -1586,10 +1580,10 @@ OutlineTypedObject::createUnattachedWithClass(JSContext *cx,
if (!obj)
return nullptr;
obj->initPrivate(nullptr);
obj->initReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0));
obj->initReservedSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(length));
obj->initReservedSlot(JS_BUFVIEW_SLOT_OWNER, NullValue());
obj->fakeNativeInitPrivate(nullptr);
obj->fakeNativeInitReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0));
obj->fakeNativeInitReservedSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(length));
obj->fakeNativeInitReservedSlot(JS_BUFVIEW_SLOT_OWNER, NullValue());
return &obj->as<OutlineTypedObject>();
}
@ -1603,9 +1597,9 @@ OutlineTypedObject::attach(JSContext *cx, ArrayBufferObject &buffer, int32_t off
if (!buffer.addView(cx, this))
CrashAtUnhandlableOOM("TypedObject::attach");
InitArrayBufferViewDataPointer(this, &buffer, offset);
setReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
setReservedSlot(JS_BUFVIEW_SLOT_OWNER, ObjectValue(buffer));
fakeNativeInitPrivate(buffer.dataPointer() + offset);
fakeNativeSetReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
fakeNativeSetReservedSlot(JS_BUFVIEW_SLOT_OWNER, ObjectValue(buffer));
}
void
@ -1623,11 +1617,11 @@ OutlineTypedObject::attach(JSContext *cx, TypedObject &typedObj, int32_t offset)
attach(cx, owner->as<ArrayBufferObject>(), offset);
} else {
MOZ_ASSERT(owner->is<InlineOpaqueTypedObject>());
initPrivate(owner->as<InlineOpaqueTypedObject>().inlineTypedMem() + offset);
fakeNativeInitPrivate(owner->as<InlineOpaqueTypedObject>().inlineTypedMem() + offset);
PostBarrierTypedArrayObject(this);
setReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
setReservedSlot(JS_BUFVIEW_SLOT_OWNER, ObjectValue(*owner));
fakeNativeSetReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
fakeNativeSetReservedSlot(JS_BUFVIEW_SLOT_OWNER, ObjectValue(*owner));
}
}
@ -1767,7 +1761,7 @@ OutlineTypedObject::obj_trace(JSTracer *trc, JSObject *object)
// Mark the owner, watching in case it is moved by the tracer.
JSObject *oldOwner = typedObj.maybeOwner();
gc::MarkSlot(trc, &typedObj.getFixedSlotRef(JS_BUFVIEW_SLOT_OWNER), "typed object owner");
gc::MarkSlot(trc, &typedObj.fakeNativeGetSlotRef(JS_BUFVIEW_SLOT_OWNER), "typed object owner");
JSObject *owner = typedObj.maybeOwner();
uint8_t *mem = typedObj.outOfLineTypedMem();
@ -1779,7 +1773,7 @@ OutlineTypedObject::obj_trace(JSTracer *trc, JSObject *object)
owner->as<ArrayBufferObject>().hasInlineData()))
{
mem += reinterpret_cast<uint8_t *>(owner) - reinterpret_cast<uint8_t *>(oldOwner);
typedObj.setPrivate(mem);
typedObj.fakeNativeSetPrivate(mem);
}
if (!descr.opaque() || !typedObj.maybeForwardedIsAttached())
@ -2328,7 +2322,7 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
/* static */ size_t
OutlineTypedObject::offsetOfOwnerSlot()
{
return JSObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_OWNER);
return NativeObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_OWNER);
}
/* static */ size_t
@ -2343,21 +2337,21 @@ OutlineTypedObject::offsetOfDataSlot()
MOZ_ASSERT(DATA_SLOT == nfixed - 1);
#endif
return JSObject::getPrivateDataOffset(DATA_SLOT);
return NativeObject::getPrivateDataOffset(DATA_SLOT);
}
/* static */ size_t
OutlineTypedObject::offsetOfByteOffsetSlot()
{
return JSObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_BYTEOFFSET);
return NativeObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_BYTEOFFSET);
}
void
OutlineTypedObject::neuter(void *newData)
{
setSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(0));
setSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0));
setPrivate(newData);
fakeNativeSetSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(0));
fakeNativeSetSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0));
fakeNativeSetPrivate(newData);
}
/******************************************************************************
@ -2383,14 +2377,14 @@ InlineOpaqueTypedObject::create(JSContext *cx, HandleTypeDescr descr)
uint8_t *
InlineOpaqueTypedObject::inlineTypedMem() const
{
return fixedData(0);
return fakeNativeFixedData(0);
}
/* static */
size_t
InlineOpaqueTypedObject::offsetOfDataStart()
{
return getFixedSlotOffset(0);
return NativeObject::getFixedSlotOffset(0);
}
/* static */ void
@ -2843,8 +2837,8 @@ js::SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp)
MOZ_ASSERT(typedObj.isAttached());
int32_t oldOffset = typedObj.offset();
typedObj.setPrivate((typedObj.typedMem() - oldOffset) + offset);
typedObj.setReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
typedObj.fakeNativeSetPrivate((typedObj.typedMem() - oldOffset) + offset);
typedObj.fakeNativeSetReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset));
args.rval().setUndefined();
return true;
}

Просмотреть файл

@ -144,7 +144,7 @@ class SizedTypedProto;
* type descriptor. Eventually will carry most of the type information
* we want.
*/
class TypedProto : public JSObject
class TypedProto : public NativeObject
{
public:
static const Class class_;
@ -162,7 +162,7 @@ class TypedProto : public JSObject
inline type::Kind kind() const;
};
class TypeDescr : public JSObject
class TypeDescr : public NativeObject
{
public:
// This is *intentionally* not defined so as to produce link
@ -509,6 +509,15 @@ class StructTypeDescr : public ComplexTypeDescr
// Return the offset of the field at index `index`.
size_t fieldOffset(size_t index) const;
size_t maybeForwardedFieldOffset(size_t index) const;
private:
NativeObject &fieldInfoObject(size_t slot) const {
return getReservedSlot(slot).toObject().as<NativeObject>();
}
NativeObject &maybeForwardedFieldInfoObject(size_t slot) const {
return *MaybeForwarded(&fieldInfoObject(slot));
}
};
typedef Handle<StructTypeDescr*> HandleStructTypeDescr;
@ -518,7 +527,7 @@ typedef Handle<StructTypeDescr*> HandleStructTypeDescr;
* somewhat, rather than sticking them all into the global object.
* Eventually it will go away and become a module.
*/
class TypedObjectModuleObject : public JSObject {
class TypedObjectModuleObject : public NativeObject {
public:
enum Slot {
ArrayTypePrototype,
@ -530,7 +539,7 @@ class TypedObjectModuleObject : public JSObject {
};
/* Base type for transparent and opaque typed objects. */
class TypedObject : public ArrayBufferViewObject
class TypedObject : public JSObject
{
private:
static const bool IsTypedObjectClass = true;
@ -690,19 +699,19 @@ class OutlineTypedObject : public TypedObject
static size_t offsetOfByteOffsetSlot();
JSObject &owner() const {
return getReservedSlot(JS_BUFVIEW_SLOT_OWNER).toObject();
return fakeNativeGetReservedSlot(JS_BUFVIEW_SLOT_OWNER).toObject();
}
JSObject *maybeOwner() const {
return getReservedSlot(JS_BUFVIEW_SLOT_OWNER).toObjectOrNull();
return fakeNativeGetReservedSlot(JS_BUFVIEW_SLOT_OWNER).toObjectOrNull();
}
uint8_t *outOfLineTypedMem() const {
return static_cast<uint8_t *>(getPrivate(DATA_SLOT));
return static_cast<uint8_t *>(fakeNativeGetPrivate(DATA_SLOT));
}
int32_t length() const {
return getReservedSlot(JS_BUFVIEW_SLOT_LENGTH).toInt32();
return fakeNativeGetReservedSlot(JS_BUFVIEW_SLOT_LENGTH).toInt32();
}
// Helper for createUnattached()
@ -763,7 +772,7 @@ class InlineOpaqueTypedObject : public TypedObject
public:
static const Class class_;
static const size_t MaximumSize = JSObject::MAX_FIXED_SLOTS * sizeof(Value);
static const size_t MaximumSize = NativeObject::MAX_FIXED_SLOTS * sizeof(Value);
static gc::AllocKind allocKindForTypeDescriptor(TypeDescr *descr) {
size_t nbytes = descr->as<SizedTypeDescr>().size();

Просмотреть файл

@ -15,6 +15,8 @@
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace JS;
@ -48,7 +50,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
{
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
// Todo: WeakSet.prototype should not be a WeakSet!
Rooted<JSObject*> proto(cx, global->createBlankPrototype(cx, &class_));
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &class_));
if (!proto)
return nullptr;
proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue());
@ -67,7 +69,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
WeakSetObject*
WeakSetObject::create(JSContext *cx)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, &class_));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
if (!obj)
return nullptr;

Просмотреть файл

@ -7,11 +7,11 @@
#ifndef builtin_WeakSetObject_h
#define builtin_WeakSetObject_h
#include "jsobj.h"
#include "vm/ObjectImpl.h"
namespace js {
class WeakSetObject : public JSObject
class WeakSetObject : public NativeObject
{
public:
static const unsigned RESERVED_SLOTS = 1;

Просмотреть файл

@ -3393,14 +3393,14 @@ void
CType::Trace(JSTracer* trc, JSObject* obj)
{
// Make sure our TypeCode slot is legit. If it's not, bail.
jsval slot = obj->getSlot(SLOT_TYPECODE);
jsval slot = obj->as<NativeObject>().getSlot(SLOT_TYPECODE);
if (slot.isUndefined())
return;
// The contents of our slots depends on what kind of type we are.
switch (TypeCode(slot.toInt32())) {
case TYPE_struct: {
slot = obj->getReservedSlot(SLOT_FIELDINFO);
slot = obj->as<NativeObject>().getReservedSlot(SLOT_FIELDINFO);
if (slot.isUndefined())
return;
@ -3417,7 +3417,7 @@ CType::Trace(JSTracer* trc, JSObject* obj)
}
case TYPE_function: {
// Check if we have a FunctionInfo.
slot = obj->getReservedSlot(SLOT_FNINFO);
slot = obj->as<NativeObject>().getReservedSlot(SLOT_FNINFO);
if (slot.isUndefined())
return;

Просмотреть файл

@ -39,6 +39,7 @@
#include "frontend/ParseMaps-inl.h"
#include "frontend/ParseNode-inl.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/ScopeObject-inl.h"
using namespace js;
@ -2166,9 +2167,9 @@ IteratorResultShape(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned *shape)
{
MOZ_ASSERT(bce->script->compileAndGo());
RootedObject obj(cx);
RootedNativeObject obj(cx);
gc::AllocKind kind = GuessObjectGCKind(2);
obj = NewBuiltinClassInstance(cx, &JSObject::class_, kind);
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind);
if (!obj)
return false;
@ -4065,7 +4066,7 @@ ParseNode::getConstantValue(ExclusiveContext *cx, AllowConstantObjects allowObje
pn = pn_head;
}
RootedObject obj(cx, NewDenseFullyAllocatedArray(cx, count, nullptr, MaybeSingletonObject));
RootedArrayObject obj(cx, NewDenseFullyAllocatedArray(cx, count, nullptr, MaybeSingletonObject));
if (!obj)
return false;
@ -4094,7 +4095,8 @@ ParseNode::getConstantValue(ExclusiveContext *cx, AllowConstantObjects allowObje
allowObjects = DontAllowObjects;
gc::AllocKind kind = GuessObjectGCKind(pn_count);
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, kind, MaybeSingletonObject));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_,
kind, MaybeSingletonObject));
if (!obj)
return false;
@ -4157,7 +4159,7 @@ EmitSingletonInitialiser(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *
if (!pn->getConstantValue(cx, ParseNode::AllowObjects, &value))
return false;
RootedObject obj(cx, &value.toObject());
RootedNativeObject obj(cx, &value.toObject().as<NativeObject>());
if (!obj->is<ArrayObject>() && !JSObject::setSingletonType(cx, obj))
return false;
@ -4177,7 +4179,7 @@ EmitCallSiteObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
MOZ_ASSERT(value.isObject());
ObjectBox *objbox1 = bce->parser->newObjectBox(&value.toObject());
ObjectBox *objbox1 = bce->parser->newObjectBox(&value.toObject().as<NativeObject>());
if (!objbox1)
return false;
@ -4186,7 +4188,7 @@ EmitCallSiteObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
MOZ_ASSERT(value.isObject());
ObjectBox *objbox2 = bce->parser->newObjectBox(&value.toObject());
ObjectBox *objbox2 = bce->parser->newObjectBox(&value.toObject().as<NativeObject>());
if (!objbox2)
return false;
@ -6219,10 +6221,10 @@ EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* Try to construct the shape of the object as we go, so we can emit a
* JSOP_NEWOBJECT with the final shape instead.
*/
RootedObject obj(cx);
RootedNativeObject obj(cx);
if (bce->script->compileAndGo()) {
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count);
obj = NewBuiltinClassInstance(cx, &JSObject::class_, kind, TenuredObject);
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind, TenuredObject);
if (!obj)
return false;
}
@ -6904,7 +6906,7 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
// for the template is accurate. We don't do this here as we
// want to use types::InitObject, which requires a finished
// script.
JSObject *obj = &value.toObject();
NativeObject *obj = &value.toObject().as<NativeObject>();
if (!ObjectElements::MakeElementsCopyOnWrite(cx, obj))
return false;
@ -7278,7 +7280,7 @@ CGObjectList::finish(ObjectArray *array)
MOZ_ASSERT(length <= INDEX_LIMIT);
MOZ_ASSERT(length == array->length);
js::HeapPtrObject *cursor = array->vector + array->length;
js::HeapPtrNativeObject *cursor = array->vector + array->length;
ObjectBox *objbox = lastbox;
do {
--cursor;

Просмотреть файл

@ -172,7 +172,7 @@ class FullParseHandler
// Specifically, a Boxer has a .newObjectBox(T) method that accepts a
// Rooted<RegExpObject*> argument and returns an ObjectBox*.
template <class Boxer>
ParseNode *newRegExp(HandleObject reobj, const TokenPos &pos, Boxer &boxer) {
ParseNode *newRegExp(RegExpObject *reobj, const TokenPos &pos, Boxer &boxer) {
ObjectBox *objbox = boxer.newObjectBox(reobj);
if (!objbox)
return null();

Просмотреть файл

@ -754,7 +754,7 @@ NameNode::dump(int indent)
}
#endif
ObjectBox::ObjectBox(JSObject *object, ObjectBox* traceLink)
ObjectBox::ObjectBox(NativeObject *object, ObjectBox* traceLink)
: object(object),
traceLink(traceLink),
emitLink(nullptr)

Просмотреть файл

@ -1498,9 +1498,9 @@ ParseNode::isConstant()
class ObjectBox
{
public:
JSObject *object;
NativeObject *object;
ObjectBox(JSObject *object, ObjectBox *traceLink);
ObjectBox(NativeObject *object, ObjectBox *traceLink);
bool isFunctionBox() { return object->is<JSFunction>(); }
FunctionBox *asFunctionBox();
void trace(JSTracer *trc);

Просмотреть файл

@ -537,7 +537,7 @@ Parser<ParseHandler>::~Parser()
template <typename ParseHandler>
ObjectBox *
Parser<ParseHandler>::newObjectBox(JSObject *obj)
Parser<ParseHandler>::newObjectBox(NativeObject *obj)
{
MOZ_ASSERT(obj && !IsPoisonedPtr(obj));
@ -2961,7 +2961,7 @@ LexicalLookup(ContextT *ct, HandleAtom atom, int *slotp, typename ContextT::Stmt
continue;
StaticBlockObject &blockObj = stmt->staticBlock();
Shape *shape = blockObj.nativeLookup(ct->sc->context, id);
Shape *shape = blockObj.lookup(ct->sc->context, id);
if (shape) {
if (slotp)
*slotp = blockObj.shapeToIndex(*shape);
@ -7219,7 +7219,7 @@ Parser<ParseHandler>::arrayInitializer()
bool spread = false, missingTrailingComma = false;
uint32_t index = 0;
for (; ; index++) {
if (index == JSObject::NELEMENTS_LIMIT) {
if (index == NativeObject::NELEMENTS_LIMIT) {
report(ParseError, false, null(), JSMSG_ARRAY_INIT_TOO_BIG);
return null();
}

Просмотреть файл

@ -429,7 +429,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
* Allocate a new parsed object or function container from
* cx->tempLifoAlloc.
*/
ObjectBox *newObjectBox(JSObject *obj);
ObjectBox *newObjectBox(NativeObject *obj);
FunctionBox *newFunctionBox(Node fn, JSFunction *fun, ParseContext<ParseHandler> *pc,
Directives directives, GeneratorKind generatorKind);

Просмотреть файл

@ -95,7 +95,7 @@ class SyntaxParseHandler
Node newNullLiteral(const TokenPos &pos) { return NodeGeneric; }
template <class Boxer>
Node newRegExp(JSObject *reobj, const TokenPos &pos, Boxer &boxer) { return NodeGeneric; }
Node newRegExp(RegExpObject *reobj, const TokenPos &pos, Boxer &boxer) { return NodeGeneric; }
Node newConditional(Node cond, Node thenExpr, Node elseExpr) { return NodeGeneric; }

Просмотреть файл

@ -34,16 +34,16 @@ bool
HeapSlot::preconditionForSet(JSObject *owner, Kind kind, uint32_t slot)
{
return kind == Slot
? &owner->getSlotRef(slot) == this
: &owner->getDenseElement(slot) == (const Value *)this;
? &owner->fakeNativeGetSlotRef(slot) == this
: &owner->fakeNativeGetDenseElement(slot) == (const Value *)this;
}
bool
HeapSlot::preconditionForSet(Zone *zone, JSObject *owner, Kind kind, uint32_t slot)
{
bool ok = kind == Slot
? &owner->getSlotRef(slot) == this
: &owner->getDenseElement(slot) == (const Value *)this;
? &owner->fakeNativeGetSlotRef(slot) == this
: &owner->fakeNativeGetDenseElement(slot) == (const Value *)this;
return ok && owner->zone() == zone;
}
@ -51,8 +51,8 @@ bool
HeapSlot::preconditionForWriteBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target) const
{
return kind == Slot
? obj->getSlotAddressUnchecked(slot)->get() == target
: static_cast<HeapSlot *>(obj->getDenseElements() + slot)->get() == target;
? obj->fakeNativeGetSlotAddressUnchecked(slot)->get() == target
: static_cast<HeapSlot *>(obj->fakeNativeGetDenseElements() + slot)->get() == target;
}
bool

Просмотреть файл

@ -161,6 +161,8 @@ class Symbol;
namespace js {
class NativeObject;
class ArrayObject;
class ArgumentsObject;
class ArrayBufferObjectMaybeShared;
class ArrayBufferObject;
@ -173,7 +175,6 @@ class GlobalObject;
class LazyScript;
class NestedScopeObject;
class Nursery;
class ObjectImpl;
class PropertyName;
class SavedFrame;
class ScopeObject;
@ -202,6 +203,8 @@ StringIsPermanentAtom(JSString *str);
namespace gc {
template <typename T> struct MapTypeToTraceKind {};
template <> struct MapTypeToTraceKind<NativeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ArrayObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ArgumentsObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ArrayBufferObjectMaybeShared>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
@ -219,7 +222,6 @@ template <> struct MapTypeToTraceKind<JSScript> { static const JSGCTrace
template <> struct MapTypeToTraceKind<JSString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
template <> struct MapTypeToTraceKind<LazyScript> { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
template <> struct MapTypeToTraceKind<NestedScopeObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ObjectImpl> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
template <> struct MapTypeToTraceKind<SavedFrame> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
@ -778,6 +780,7 @@ class ReadBarriered
void set(T v) { value = v; }
};
class ArrayObject;
class ArrayBufferObject;
class NestedScopeObject;
class DebugScopeObject;
@ -801,8 +804,11 @@ typedef PreBarriered<JSAtom*> PreBarrieredAtom;
typedef RelocatablePtr<JSObject*> RelocatablePtrObject;
typedef RelocatablePtr<JSScript*> RelocatablePtrScript;
typedef RelocatablePtr<NativeObject*> RelocatablePtrNativeObject;
typedef RelocatablePtr<NestedScopeObject*> RelocatablePtrNestedScopeObject;
typedef HeapPtr<NativeObject*> HeapPtrNativeObject;
typedef HeapPtr<ArrayObject*> HeapPtrArrayObject;
typedef HeapPtr<ArrayBufferObjectMaybeShared*> HeapPtrArrayBufferObjectMaybeShared;
typedef HeapPtr<ArrayBufferObject*> HeapPtrArrayBufferObject;
typedef HeapPtr<BaseShape*> HeapPtrBaseShape;

Просмотреть файл

@ -538,9 +538,9 @@ ForkJoinNursery::allocateObject(size_t baseSize, size_t numDynamic, bool& tooLar
tooLarge = false;
return nullptr;
}
obj->setInitialSlots(numDynamic
? reinterpret_cast<HeapSlot *>(size_t(obj) + baseSize)
: nullptr);
obj->fakeNativeSetInitialSlots(numDynamic
? reinterpret_cast<HeapSlot *>(size_t(obj) + baseSize)
: nullptr);
return obj;
}
@ -668,12 +668,13 @@ ForkJoinNursery::traceObject(ForkJoinNurseryCollectionTracer *trc, JSObject *obj
if (!obj->isNative())
return;
NativeObject *nobj = &obj->as<NativeObject>();
if (!obj->hasEmptyElements())
markSlots(obj->getDenseElements(), obj->getDenseInitializedLength());
if (!nobj->hasEmptyElements())
markSlots(nobj->getDenseElements(), nobj->getDenseInitializedLength());
HeapSlot *fixedStart, *fixedEnd, *dynStart, *dynEnd;
obj->getSlotRange(0, obj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd);
nobj->getSlotRange(0, nobj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd);
markSlots(fixedStart, fixedEnd);
markSlots(dynStart, dynEnd);
}
@ -714,20 +715,21 @@ AllocKind
ForkJoinNursery::getObjectAllocKind(JSObject *obj)
{
if (obj->is<ArrayObject>()) {
MOZ_ASSERT(obj->numFixedSlots() == 0);
ArrayObject *aobj = &obj->as<ArrayObject>();
MOZ_ASSERT(aobj->numFixedSlots() == 0);
// Use minimal size object if we are just going to copy the pointer.
if (!isInsideFromspace((void *)obj->getElementsHeader()))
if (!isInsideFromspace((void *)aobj->getElementsHeader()))
return FINALIZE_OBJECT0_BACKGROUND;
size_t nelements = obj->getDenseCapacity();
size_t nelements = aobj->getDenseCapacity();
return GetBackgroundAllocKind(GetGCArrayKind(nelements));
}
if (obj->is<JSFunction>())
return obj->as<JSFunction>().getAllocKind();
AllocKind kind = GetGCObjectFixedSlotsKind(obj->numFixedSlots());
AllocKind kind = GetGCObjectFixedSlotsKind(obj->fakeNativeNumFixedSlots());
MOZ_ASSERT(!IsBackgroundFinalized(kind));
MOZ_ASSERT(CanBeFinalizedInBackground(kind, obj->getClass()));
return GetBackgroundAllocKind(kind);
@ -808,7 +810,7 @@ ForkJoinNursery::copyObjectToTospace(JSObject *dst, JSObject *src, AllocKind dst
// We deal with this by copying elements manually, possibly re-inlining
// them if there is adequate room inline in dst.
if (src->is<ArrayObject>())
srcSize = movedSize = sizeof(ObjectImpl);
srcSize = movedSize = sizeof(NativeObject);
js_memcpy(dst, src, srcSize);
movedSize += copySlotsToTospace(dst, src, dstKind);
@ -827,38 +829,38 @@ size_t
ForkJoinNursery::copySlotsToTospace(JSObject *dst, JSObject *src, AllocKind dstKind)
{
// Fixed slots have already been copied over.
if (!src->hasDynamicSlots())
if (!src->fakeNativeHasDynamicSlots())
return 0;
if (!isInsideFromspace(src->slots)) {
hugeSlots[hugeSlotsFrom].remove(src->slots);
if (!isInsideFromspace(src->fakeNativeSlots())) {
hugeSlots[hugeSlotsFrom].remove(src->fakeNativeSlots());
if (!isEvacuating_)
hugeSlots[hugeSlotsNew].put(src->slots);
hugeSlots[hugeSlotsNew].put(src->fakeNativeSlots());
return 0;
}
size_t count = src->numDynamicSlots();
dst->slots = allocateInTospace<HeapSlot>(count);
if (!dst->slots)
size_t count = src->fakeNativeNumDynamicSlots();
dst->fakeNativeSlots() = allocateInTospace<HeapSlot>(count);
if (!dst->fakeNativeSlots())
CrashAtUnhandlableOOM("Failed to allocate slots while moving object.");
js_memcpy(dst->slots, src->slots, count * sizeof(HeapSlot));
setSlotsForwardingPointer(src->slots, dst->slots, count);
js_memcpy(dst->fakeNativeSlots(), src->fakeNativeSlots(), count * sizeof(HeapSlot));
setSlotsForwardingPointer(src->fakeNativeSlots(), dst->fakeNativeSlots(), count);
return count * sizeof(HeapSlot);
}
size_t
ForkJoinNursery::copyElementsToTospace(JSObject *dst, JSObject *src, AllocKind dstKind)
{
if (src->hasEmptyElements() || src->denseElementsAreCopyOnWrite())
if (src->fakeNativeHasEmptyElements() || src->fakeNativeDenseElementsAreCopyOnWrite())
return 0;
ObjectElements *srcHeader = src->getElementsHeader();
ObjectElements *srcHeader = src->fakeNativeGetElementsHeader();
ObjectElements *dstHeader;
// TODO Bug 874151: Prefer to put element data inline if we have space.
// (Note, not a correctness issue.)
if (!isInsideFromspace(srcHeader)) {
MOZ_ASSERT(src->elements == dst->elements);
MOZ_ASSERT(src->fakeNativeElements() == dst->fakeNativeElements());
hugeSlots[hugeSlotsFrom].remove(reinterpret_cast<HeapSlot*>(srcHeader));
if (!isEvacuating_)
hugeSlots[hugeSlotsNew].put(reinterpret_cast<HeapSlot*>(srcHeader));
@ -869,8 +871,8 @@ ForkJoinNursery::copyElementsToTospace(JSObject *dst, JSObject *src, AllocKind d
// Unlike other objects, Arrays can have fixed elements.
if (src->is<ArrayObject>() && nslots <= GetGCKindSlots(dstKind)) {
dst->setFixedElements();
dstHeader = dst->getElementsHeader();
dst->as<ArrayObject>().setFixedElements();
dstHeader = dst->as<ArrayObject>().getElementsHeader();
js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
setElementsForwardingPointer(srcHeader, dstHeader, nslots);
return nslots * sizeof(HeapSlot);
@ -882,7 +884,7 @@ ForkJoinNursery::copyElementsToTospace(JSObject *dst, JSObject *src, AllocKind d
CrashAtUnhandlableOOM("Failed to allocate elements while moving object.");
js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
setElementsForwardingPointer(srcHeader, dstHeader, nslots);
dst->elements = dstHeader->elements();
dst->fakeNativeElements() = dstHeader->elements();
return nslots * sizeof(HeapSlot);
}

Просмотреть файл

@ -183,7 +183,7 @@ class TenuredCell : public Cell
MOZ_ALWAYS_INLINE void unmark(uint32_t color) const;
MOZ_ALWAYS_INLINE void copyMarkBitsFrom(const TenuredCell *src);
// Note: this is in TenuredCell because ObjectImpl subclasses are sometimes
// Note: this is in TenuredCell because JSObject subclasses are sometimes
// used tagged.
static MOZ_ALWAYS_INLINE bool isNullLike(const Cell *thing) { return !thing; }

Просмотреть файл

@ -13,6 +13,7 @@
#include "jit/IonCode.h"
#include "js/SliceBudget.h"
#include "vm/ArgumentsObject.h"
#include "vm/ArrayObject.h"
#include "vm/ScopeObject.h"
#include "vm/Shape.h"
#include "vm/Symbol.h"
@ -68,7 +69,7 @@ JS_PUBLIC_DATA(void * const) JS::NullPtr::constNullValue = nullptr;
*/
static inline void
PushMarkStack(GCMarker *gcmarker, ObjectImpl *thing);
PushMarkStack(GCMarker *gcmarker, JSObject *thing);
static inline void
PushMarkStack(GCMarker *gcmarker, JSFunction *thing);
@ -254,6 +255,13 @@ SetMaybeAliveFlag(JSObject *thing)
thing->compartment()->maybeAlive = true;
}
template<>
void
SetMaybeAliveFlag(NativeObject *thing)
{
thing->compartment()->maybeAlive = true;
}
template<>
void
SetMaybeAliveFlag(JSScript *thing)
@ -629,6 +637,8 @@ Update##base##IfRelocated(JSRuntime *rt, type **thingp)
DeclMarkerImpl(BaseShape, BaseShape)
DeclMarkerImpl(BaseShape, UnownedBaseShape)
DeclMarkerImpl(JitCode, jit::JitCode)
DeclMarkerImpl(Object, NativeObject)
DeclMarkerImpl(Object, ArrayObject)
DeclMarkerImpl(Object, ArgumentsObject)
DeclMarkerImpl(Object, ArrayBufferObject)
DeclMarkerImpl(Object, ArrayBufferObjectMaybeShared)
@ -638,7 +648,6 @@ DeclMarkerImpl(Object, GlobalObject)
DeclMarkerImpl(Object, JSObject)
DeclMarkerImpl(Object, JSFunction)
DeclMarkerImpl(Object, NestedScopeObject)
DeclMarkerImpl(Object, ObjectImpl)
DeclMarkerImpl(Object, SavedFrame)
DeclMarkerImpl(Object, ScopeObject)
DeclMarkerImpl(Object, SharedArrayBufferObject)
@ -931,7 +940,7 @@ gc::MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslot
MOZ_ASSERT(obj->isNative());
for (uint32_t i = start; i < (start + nslots); ++i) {
trc->setTracingDetails(js_GetObjectSlotName, obj, i);
MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet());
MarkValueInternal(trc, obj->fakeNativeGetSlotRef(i).unsafeGet());
}
}
@ -1036,7 +1045,7 @@ gc::IsCellAboutToBeFinalized(Cell **thingp)
JS_COMPARTMENT_ASSERT_STR(rt, sym)
static void
PushMarkStack(GCMarker *gcmarker, ObjectImpl *thing)
PushMarkStack(GCMarker *gcmarker, JSObject *thing)
{
JS_COMPARTMENT_ASSERT(gcmarker->runtime(), thing);
MOZ_ASSERT(!IsInsideNursery(thing));
@ -1541,7 +1550,7 @@ struct SlotArrayLayout
HeapSlot *start;
uintptr_t index;
};
JSObject *obj;
NativeObject *obj;
static void staticAsserts() {
/* This should have the same layout as three mark stack items. */
@ -1566,7 +1575,7 @@ GCMarker::saveValueRanges()
*p &= ~StackTagMask;
p -= 2;
SlotArrayLayout *arr = reinterpret_cast<SlotArrayLayout *>(p);
JSObject *obj = arr->obj;
NativeObject *obj = arr->obj;
MOZ_ASSERT(obj->isNative());
HeapSlot *vp = obj->getDenseElements();
@ -1597,7 +1606,7 @@ GCMarker::saveValueRanges()
}
bool
GCMarker::restoreValueArray(JSObject *obj, void **vpp, void **endp)
GCMarker::restoreValueArray(NativeObject *obj, void **vpp, void **endp)
{
uintptr_t start = stack.pop();
HeapSlot::Kind kind = (HeapSlot::Kind) stack.pop();
@ -1645,7 +1654,7 @@ GCMarker::processMarkStackOther(uintptr_t tag, uintptr_t addr)
ScanTypeObject(this, reinterpret_cast<types::TypeObject *>(addr));
} else if (tag == SavedValueArrayTag) {
MOZ_ASSERT(!(addr & CellMask));
JSObject *obj = reinterpret_cast<JSObject *>(addr);
NativeObject *obj = reinterpret_cast<NativeObject *>(addr);
HeapValue *vp, *end;
if (restoreValueArray(obj, (void **)&vp, (void **)&end))
pushValueArray(obj, vp, end);
@ -1759,38 +1768,39 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
if (!shape->isNative())
return;
unsigned nslots = obj->slotSpan();
NativeObject *nobj = &obj->as<NativeObject>();
unsigned nslots = nobj->slotSpan();
do {
if (obj->hasEmptyElements())
if (nobj->hasEmptyElements())
break;
if (obj->denseElementsAreCopyOnWrite()) {
JSObject *owner = obj->getElementsHeader()->ownerObject();
if (owner != obj) {
if (nobj->denseElementsAreCopyOnWrite()) {
JSObject *owner = nobj->getElementsHeader()->ownerObject();
if (owner != nobj) {
PushMarkStack(this, owner);
break;
}
}
vp = obj->getDenseElementsAllowCopyOnWrite();
end = vp + obj->getDenseInitializedLength();
vp = nobj->getDenseElementsAllowCopyOnWrite();
end = vp + nobj->getDenseInitializedLength();
if (!nslots)
goto scan_value_array;
pushValueArray(obj, vp, end);
pushValueArray(nobj, vp, end);
} while (false);
vp = obj->fixedSlots();
if (obj->slots) {
unsigned nfixed = obj->numFixedSlots();
vp = nobj->fixedSlots();
if (nobj->slots) {
unsigned nfixed = nobj->numFixedSlots();
if (nslots > nfixed) {
pushValueArray(obj, vp, vp + nfixed);
vp = obj->slots;
pushValueArray(nobj, vp, vp + nfixed);
vp = nobj->slots;
end = vp + (nslots - nfixed);
goto scan_value_array;
}
}
MOZ_ASSERT(nslots <= obj->numFixedSlots());
MOZ_ASSERT(nslots <= nobj->numFixedSlots());
end = vp + nslots;
goto scan_value_array;
}

Просмотреть файл

@ -105,6 +105,8 @@ type *Update##base##IfRelocated(JSRuntime *rt, type **thingp);
DeclMarker(BaseShape, BaseShape)
DeclMarker(BaseShape, UnownedBaseShape)
DeclMarker(JitCode, jit::JitCode)
DeclMarker(Object, NativeObject)
DeclMarker(Object, ArrayObject)
DeclMarker(Object, ArgumentsObject)
DeclMarker(Object, ArrayBufferObject)
DeclMarker(Object, ArrayBufferObjectMaybeShared)
@ -305,6 +307,13 @@ Mark(JSTracer *trc, JSObject **objp, const char *name)
MarkObjectUnbarriered(trc, objp, name);
}
/* For use by Debugger::WeakMap's missingScopes HashKeyRef instantiation. */
inline void
Mark(JSTracer *trc, NativeObject **obj, const char *name)
{
MarkObjectUnbarriered(trc, obj, name);
}
/* For use by Debugger::WeakMap's proxiedScopes HashKeyRef instantiation. */
inline void
Mark(JSTracer *trc, ScopeObject **obj, const char *name)

Просмотреть файл

@ -171,7 +171,7 @@ js::Nursery::allocateObject(JSContext *cx, size_t size, size_t numDynamic)
size_t totalSize = size + sizeof(HeapSlot) * numDynamic;
JSObject *obj = static_cast<JSObject *>(allocate(totalSize));
if (obj) {
obj->setInitialSlots(reinterpret_cast<HeapSlot *>(size_t(obj) + size));
obj->fakeNativeSetInitialSlots(reinterpret_cast<HeapSlot *>(size_t(obj) + size));
TraceNurseryAlloc(obj, size);
return obj;
}
@ -188,7 +188,7 @@ js::Nursery::allocateObject(JSContext *cx, size_t size, size_t numDynamic)
JSObject *obj = static_cast<JSObject *>(allocate(size));
if (obj)
obj->setInitialSlots(slots);
obj->fakeNativeSetInitialSlots(slots);
else
freeSlots(slots);
@ -367,13 +367,14 @@ static AllocKind
GetObjectAllocKindForCopy(const Nursery &nursery, JSObject *obj)
{
if (obj->is<ArrayObject>()) {
MOZ_ASSERT(obj->numFixedSlots() == 0);
ArrayObject *aobj = &obj->as<ArrayObject>();
MOZ_ASSERT(aobj->numFixedSlots() == 0);
/* Use minimal size object if we are just going to copy the pointer. */
if (!nursery.isInside(obj->getElementsHeader()))
if (!nursery.isInside(aobj->getElementsHeader()))
return FINALIZE_OBJECT0_BACKGROUND;
size_t nelements = obj->getDenseCapacity();
size_t nelements = aobj->getDenseCapacity();
return GetBackgroundAllocKind(GetGCArrayKind(nelements));
}
@ -399,7 +400,7 @@ GetObjectAllocKindForCopy(const Nursery &nursery, JSObject *obj)
return InlineOpaqueTypedObject::allocKindForTypeDescriptor(descr);
}
AllocKind kind = GetGCObjectFixedSlotsKind(obj->numFixedSlots());
AllocKind kind = GetGCObjectFixedSlotsKind(obj->fakeNativeNumFixedSlots());
MOZ_ASSERT(!IsBackgroundFinalized(kind));
MOZ_ASSERT(CanBeFinalizedInBackground(kind, obj->getClass()));
return GetBackgroundAllocKind(kind);
@ -518,14 +519,15 @@ js::Nursery::traceObject(MinorCollectionTracer *trc, JSObject *obj)
MOZ_ASSERT(obj->isNative() == clasp->isNative());
if (!clasp->isNative())
return;
NativeObject *nobj = &obj->as<NativeObject>();
// Note: the contents of copy on write elements pointers are filled in
// during parsing and cannot contain nursery pointers.
if (!obj->hasEmptyElements() && !obj->denseElementsAreCopyOnWrite())
markSlots(trc, obj->getDenseElements(), obj->getDenseInitializedLength());
if (!nobj->hasEmptyElements() && !nobj->denseElementsAreCopyOnWrite())
markSlots(trc, nobj->getDenseElements(), nobj->getDenseInitializedLength());
HeapSlot *fixedStart, *fixedEnd, *dynStart, *dynEnd;
obj->getSlotRange(0, obj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd);
nobj->getSlotRange(0, nobj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd);
markSlots(trc, fixedStart, fixedEnd);
markSlots(trc, dynStart, dynEnd);
}
@ -597,14 +599,14 @@ js::Nursery::moveObjectToTenured(JSObject *dst, JSObject *src, AllocKind dstKind
* even if they are inlined.
*/
if (src->is<ArrayObject>())
tenuredSize = srcSize = sizeof(ObjectImpl);
tenuredSize = srcSize = sizeof(NativeObject);
js_memcpy(dst, src, srcSize);
tenuredSize += moveSlotsToTenured(dst, src, dstKind);
tenuredSize += moveElementsToTenured(dst, src, dstKind);
if (src->is<TypedArrayObject>())
forwardTypedArrayPointers(dst, src);
forwardTypedArrayPointers(&dst->as<TypedArrayObject>(), &src->as<TypedArrayObject>());
/* The shape's list head may point into the old object. */
if (&src->shape_ == dst->shape_->listp)
@ -614,17 +616,17 @@ js::Nursery::moveObjectToTenured(JSObject *dst, JSObject *src, AllocKind dstKind
}
void
js::Nursery::forwardTypedArrayPointers(JSObject *dst, JSObject *src)
js::Nursery::forwardTypedArrayPointers(TypedArrayObject *dst, TypedArrayObject *src)
{
/*
* Typed array data may be stored inline inside the object's fixed slots. If
* so, we need update the private pointer and leave a forwarding pointer at
* the start of the data.
*/
TypedArrayObject &typedArray = src->as<TypedArrayObject>();
MOZ_ASSERT_IF(typedArray.buffer(), !isInside(src->getPrivate()));
if (typedArray.buffer())
if (src->buffer()) {
MOZ_ASSERT(!isInside(src->getPrivate()));
return;
}
void *srcData = src->fixedData(TypedArrayObject::FIXED_DATA_START);
void *dstData = dst->fixedData(TypedArrayObject::FIXED_DATA_START);
@ -646,37 +648,37 @@ MOZ_ALWAYS_INLINE size_t
js::Nursery::moveSlotsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind)
{
/* Fixed slots have already been copied over. */
if (!src->hasDynamicSlots())
if (!src->fakeNativeHasDynamicSlots())
return 0;
if (!isInside(src->slots)) {
hugeSlots.remove(src->slots);
if (!isInside(src->fakeNativeSlots())) {
hugeSlots.remove(src->fakeNativeSlots());
return 0;
}
Zone *zone = src->zone();
size_t count = src->numDynamicSlots();
dst->slots = zone->pod_malloc<HeapSlot>(count);
if (!dst->slots)
size_t count = src->fakeNativeNumDynamicSlots();
dst->fakeNativeSlots() = zone->pod_malloc<HeapSlot>(count);
if (!dst->fakeNativeSlots())
CrashAtUnhandlableOOM("Failed to allocate slots while tenuring.");
PodCopy(dst->slots, src->slots, count);
setSlotsForwardingPointer(src->slots, dst->slots, count);
PodCopy(dst->fakeNativeSlots(), src->fakeNativeSlots(), count);
setSlotsForwardingPointer(src->fakeNativeSlots(), dst->fakeNativeSlots(), count);
return count * sizeof(HeapSlot);
}
MOZ_ALWAYS_INLINE size_t
js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind)
{
if (src->hasEmptyElements() || src->denseElementsAreCopyOnWrite())
if (src->fakeNativeHasEmptyElements() || src->fakeNativeDenseElementsAreCopyOnWrite())
return 0;
Zone *zone = src->zone();
ObjectElements *srcHeader = src->getElementsHeader();
ObjectElements *srcHeader = src->fakeNativeGetElementsHeader();
ObjectElements *dstHeader;
/* TODO Bug 874151: Prefer to put element data inline if we have space. */
if (!isInside(srcHeader)) {
MOZ_ASSERT(src->elements == dst->elements);
MOZ_ASSERT(src->fakeNativeElements() == dst->fakeNativeElements());
hugeSlots.remove(reinterpret_cast<HeapSlot*>(srcHeader));
return 0;
}
@ -685,8 +687,8 @@ js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKi
/* Unlike other objects, Arrays can have fixed elements. */
if (src->is<ArrayObject>() && nslots <= GetGCKindSlots(dstKind)) {
dst->setFixedElements();
dstHeader = dst->getElementsHeader();
dst->as<ArrayObject>().setFixedElements();
dstHeader = dst->as<ArrayObject>().getElementsHeader();
js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
setElementsForwardingPointer(srcHeader, dstHeader, nslots);
return nslots * sizeof(HeapSlot);
@ -698,7 +700,7 @@ js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKi
CrashAtUnhandlableOOM("Failed to allocate elements while tenuring.");
js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
setElementsForwardingPointer(srcHeader, dstHeader, nslots);
dst->elements = dstHeader->elements();
dst->fakeNativeElements() = dstHeader->elements();
return nslots * sizeof(HeapSlot);
}

Просмотреть файл

@ -28,6 +28,7 @@ struct Zone;
namespace js {
class TypedArrayObject;
class ObjectElements;
class HeapSlot;
void SetGCZeal(JSRuntime *, uint8_t, uint32_t);
@ -286,7 +287,7 @@ class Nursery
size_t moveObjectToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
size_t moveElementsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
size_t moveSlotsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
void forwardTypedArrayPointers(JSObject *dst, JSObject *src);
void forwardTypedArrayPointers(TypedArrayObject *dst, TypedArrayObject *src);
/* Handle relocation of slots/elements pointers stored in Ion frames. */
void setSlotsForwardingPointer(HeapSlot *oldSlots, HeapSlot *newSlots, uint32_t nslots);

Просмотреть файл

@ -15,6 +15,8 @@ class JSLinearString;
namespace js {
class PropertyName;
class NativeObject;
class ArrayObject;
class ScriptSourceObject;
class Shape;
@ -22,21 +24,26 @@ namespace types { struct TypeObject; }
// These are internal counterparts to the public types such as HandleObject.
typedef JS::Handle<NativeObject*> HandleNativeObject;
typedef JS::Handle<Shape*> HandleShape;
typedef JS::Handle<types::TypeObject*> HandleTypeObject;
typedef JS::Handle<JSAtom*> HandleAtom;
typedef JS::Handle<JSLinearString*> HandleLinearString;
typedef JS::Handle<PropertyName*> HandlePropertyName;
typedef JS::Handle<ArrayObject*> HandleArrayObject;
typedef JS::Handle<ScriptSourceObject*> HandleScriptSource;
typedef JS::MutableHandle<Shape*> MutableHandleShape;
typedef JS::MutableHandle<JSAtom*> MutableHandleAtom;
typedef JS::MutableHandle<NativeObject*> MutableHandleNativeObject;
typedef JS::Rooted<NativeObject*> RootedNativeObject;
typedef JS::Rooted<Shape*> RootedShape;
typedef JS::Rooted<types::TypeObject*> RootedTypeObject;
typedef JS::Rooted<JSAtom*> RootedAtom;
typedef JS::Rooted<JSLinearString*> RootedLinearString;
typedef JS::Rooted<PropertyName*> RootedPropertyName;
typedef JS::Rooted<ArrayObject*> RootedArrayObject;
typedef JS::Rooted<ScriptSourceObject*> RootedScriptSource;
} /* namespace js */

Просмотреть файл

@ -37,14 +37,14 @@ StoreBuffer::SlotsEdge::mark(JSTracer *trc)
}
if (kind() == ElementKind) {
int32_t initLen = obj->getDenseInitializedLength();
int32_t initLen = obj->fakeNativeGetDenseInitializedLength();
int32_t clampedStart = Min(start_, initLen);
int32_t clampedEnd = Min(start_ + count_, initLen);
gc::MarkArraySlots(trc, clampedEnd - clampedStart,
obj->getDenseElements() + clampedStart, "element");
obj->fakeNativeGetDenseElements() + clampedStart, "element");
} else {
int32_t start = Min(uint32_t(start_), obj->slotSpan());
int32_t end = Min(uint32_t(start_) + count_, obj->slotSpan());
int32_t start = Min(uint32_t(start_), obj->fakeNativeSlotSpan());
int32_t end = Min(uint32_t(start_) + count_, obj->fakeNativeSlotSpan());
MOZ_ASSERT(end >= start);
MarkObjectSlots(trc, obj, start, end - start);
}

Просмотреть файл

@ -204,7 +204,7 @@ JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing,
PutEscapedString(buf, bufsize, fun->displayAtom(), 0);
}
} else if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE) {
JS_snprintf(buf, bufsize, " %p", obj->getPrivate());
JS_snprintf(buf, bufsize, " %p", obj->fakeNativeGetPrivate());
} else {
JS_snprintf(buf, bufsize, " <no private>");
}

Просмотреть файл

@ -14,8 +14,8 @@
#include "js/TracingAPI.h"
namespace js {
class NativeObject;
class GCMarker;
class ObjectImpl;
namespace gc {
struct ArenaHeader;
}
@ -139,7 +139,7 @@ class GCMarker : public JSTracer
void stop();
void reset();
void pushObject(ObjectImpl *obj) {
void pushObject(JSObject *obj) {
pushTaggedPtr(ObjectTag, obj);
}
@ -270,7 +270,7 @@ class GCMarker : public JSTracer
return stack.isEmpty();
}
bool restoreValueArray(JSObject *obj, void **vpp, void **endp);
bool restoreValueArray(NativeObject *obj, void **vpp, void **endp);
void saveValueRanges();
inline void processMarkStackTop(SliceBudget &budget);
void processMarkStackOther(uintptr_t tag, uintptr_t addr);

Просмотреть файл

@ -478,7 +478,7 @@ PostVerifierVisitEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
/*
* Values will be unpacked to the stack before getting here. However, the
* only things that enter this callback are marked by the JS_TraceChildren
* below. Since ObjectImpl::markChildren handles this, the real trace
* below. Since JSObject::markChildren handles this, the real trace
* location will be set correctly in these cases.
*/
void **loc = trc->tracingLocation(thingp);

Просмотреть файл

@ -155,7 +155,7 @@ Zone::sweepBreakpoints(FreeOp *fop)
Breakpoint *nextbp;
for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) {
nextbp = bp->nextInSite();
HeapPtrObject &dbgobj = bp->debugger->toJSObjectRef();
HeapPtrNativeObject &dbgobj = bp->debugger->toJSObjectRef();
MOZ_ASSERT_IF(isGCSweeping() && dbgobj->zone()->isCollecting(),
dbgobj->zone()->isGCSweeping());
bool dying = scriptGone || IsObjectAboutToBeFinalized(&dbgobj);

Просмотреть файл

@ -23,6 +23,7 @@
#include "jsscriptinlines.h"
#include "vm/Interpreter-inl.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::jit;
@ -1258,7 +1259,7 @@ BaselineCompiler::emit_JSOP_STRING()
return true;
}
typedef JSObject *(*DeepCloneObjectLiteralFn)(JSContext *, HandleObject, NewObjectKind);
typedef NativeObject *(*DeepCloneObjectLiteralFn)(JSContext *, HandleNativeObject, NewObjectKind);
static const VMFunction DeepCloneObjectLiteralInfo =
FunctionInfo<DeepCloneObjectLiteralFn>(DeepCloneObjectLiteral);
@ -1646,7 +1647,7 @@ BaselineCompiler::emit_JSOP_NEWARRAY()
masm.move32(Imm32(length), R0.scratchReg());
masm.movePtr(ImmGCPtr(type), R1.scratchReg());
JSObject *templateObject = NewDenseUnallocatedArray(cx, length, nullptr, TenuredObject);
ArrayObject *templateObject = NewDenseUnallocatedArray(cx, length, nullptr, TenuredObject);
if (!templateObject)
return false;
templateObject->setType(type);
@ -1659,7 +1660,7 @@ BaselineCompiler::emit_JSOP_NEWARRAY()
return true;
}
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleObject, gc::InitialHeap);
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleNativeObject, gc::InitialHeap);
const VMFunction jit::NewArrayCopyOnWriteInfo =
FunctionInfo<NewArrayCopyOnWriteFn>(js::NewDenseCopyOnWriteArray);
@ -1717,8 +1718,8 @@ BaselineCompiler::emit_JSOP_NEWOBJECT()
return false;
}
RootedObject baseObject(cx, script->getObject(pc));
RootedObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
RootedNativeObject baseObject(cx, script->getObject(pc));
RootedNativeObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
if (!templateObject)
return false;
@ -1755,7 +1756,7 @@ BaselineCompiler::emit_JSOP_NEWINIT()
masm.move32(Imm32(0), R0.scratchReg());
masm.movePtr(ImmGCPtr(type), R1.scratchReg());
JSObject *templateObject = NewDenseUnallocatedArray(cx, 0, nullptr, TenuredObject);
ArrayObject *templateObject = NewDenseUnallocatedArray(cx, 0, nullptr, TenuredObject);
if (!templateObject)
return false;
templateObject->setType(type);
@ -1766,8 +1767,8 @@ BaselineCompiler::emit_JSOP_NEWINIT()
} else {
MOZ_ASSERT(key == JSProto_Object);
RootedObject templateObject(cx);
templateObject = NewBuiltinClassInstance(cx, &JSObject::class_, TenuredObject);
RootedNativeObject templateObject(cx);
templateObject = NewNativeBuiltinClassInstance(cx, &JSObject::class_, TenuredObject);
if (!templateObject)
return false;
@ -2103,11 +2104,11 @@ BaselineCompiler::getScopeCoordinateAddressFromObject(Register objReg, Register
Address addr;
if (shape->numFixedSlots() <= sc.slot()) {
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), reg);
masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), reg);
return Address(reg, (sc.slot() - shape->numFixedSlots()) * sizeof(Value));
}
return Address(objReg, JSObject::getFixedSlotOffset(sc.slot()));
return Address(objReg, NativeObject::getFixedSlotOffset(sc.slot()));
}
Address
@ -3217,7 +3218,7 @@ BaselineCompiler::emit_JSOP_REST()
{
frame.syncStack(0);
JSObject *templateObject = NewDenseUnallocatedArray(cx, 0, nullptr, TenuredObject);
ArrayObject *templateObject = NewDenseUnallocatedArray(cx, 0, nullptr, TenuredObject);
if (!templateObject)
return false;
types::FixRestArgumentsType(cx, templateObject);

Просмотреть файл

@ -1748,7 +1748,7 @@ DoNewObject(JSContext *cx, ICNewObject_Fallback *stub, MutableHandleValue res)
{
FallbackICSpew(cx, stub, "NewObject");
RootedObject templateObject(cx, stub->templateObject());
RootedNativeObject templateObject(cx, stub->templateObject());
JSObject *obj = NewInitObject(cx, templateObject);
if (!obj)
return false;
@ -3189,13 +3189,13 @@ ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler &masm)
// GetElem_Fallback
//
static void GetFixedOrDynamicSlotOffset(HandleObject obj, uint32_t slot,
static void GetFixedOrDynamicSlotOffset(NativeObject *obj, uint32_t slot,
bool *isFixed, uint32_t *offset)
{
MOZ_ASSERT(isFixed);
MOZ_ASSERT(offset);
*isFixed = obj->isFixedSlot(slot);
*offset = *isFixed ? JSObject::getFixedSlotOffset(slot)
*offset = *isFixed ? NativeObject::getFixedSlotOffset(slot)
: obj->dynamicSlotIndex(slot) * sizeof(Value);
}
@ -3221,7 +3221,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, Register object,
// 2. The object does not have expando properties, or has an expando
// which is known to not have the desired property.
Address handlerAddr(object, ProxyObject::offsetOfHandler());
Address expandoAddr(object, JSObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
Address expandoAddr(object, NativeObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
// Check that object is a DOMProxy.
masm.loadPtr(checkProxyHandlerAddr, scratch);
@ -3333,7 +3333,7 @@ EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName n
if (!JSObject::lookupProperty(cx, checkObj, name, holder, shape))
return false;
} else if (checkObj->isNative()) {
shape.set(checkObj->nativeLookup(cx, NameToId(name)));
shape.set(checkObj->as<NativeObject>().lookup(cx, NameToId(name)));
if (shape)
holder.set(checkObj);
}
@ -3352,7 +3352,7 @@ CheckHasNoSuchProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
if (!curObj->isNative())
return false;
Shape *shape = curObj->nativeLookup(cx, NameToId(name));
Shape *shape = curObj->as<NativeObject>().lookup(cx, NameToId(name));
if (shape)
return false;
@ -3510,7 +3510,7 @@ IsCacheableSetPropAddSlot(JSContext *cx, HandleObject obj, HandleShape oldShape,
return false;
// if prototype defines this property in a non-plain way, don't optimize
Shape *protoShape = proto->nativeLookup(cx, id);
Shape *protoShape = proto->as<NativeObject>().lookup(cx, id);
if (protoShape && !protoShape->hasDefaultSetter())
return false;
@ -3523,7 +3523,7 @@ IsCacheableSetPropAddSlot(JSContext *cx, HandleObject obj, HandleShape oldShape,
// Only add a IC entry if the dynamic slots didn't change when the shapes
// changed. Need to ensure that a shape change for a subsequent object
// won't involve reallocating the slot array.
if (obj->numDynamicSlots() != oldSlots)
if (obj->as<NativeObject>().numDynamicSlots() != oldSlots)
return false;
*protoChainDepth = chainDepth;
@ -3782,7 +3782,8 @@ static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbyt
bool isFixedSlot;
uint32_t offset;
GetFixedOrDynamicSlotOffset(holder, shape->slot(), &isFixedSlot, &offset);
GetFixedOrDynamicSlotOffset(&holder->as<NativeObject>(),
shape->slot(), &isFixedSlot, &offset);
ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
ICStub::Kind kind = (obj == holder) ? ICStub::GetElem_NativeSlot
@ -4326,7 +4327,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm)
// Load from object.
if (acctype_ == ICGetElemNativeStub::DynamicSlot)
masm.addPtr(Address(holderReg, JSObject::offsetOfSlots()), scratchReg);
masm.addPtr(Address(holderReg, NativeObject::offsetOfSlots()), scratchReg);
else
masm.addPtr(holderReg, scratchReg);
@ -4501,7 +4502,7 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
masm.branchTestObjShape(Assembler::NotEqual, obj, scratchReg, &failure);
// Load obj->elements.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratchReg);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratchReg);
// Unbox key.
Register key = masm.extractInt32(R1, ExtractTemp1);
@ -4902,8 +4903,8 @@ RemoveExistingTypedArraySetElemStub(JSContext *cx, ICSetElem_Fallback *stub, Han
}
static bool
CanOptimizeDenseSetElem(JSContext *cx, HandleObject obj, uint32_t index,
HandleShape oldShape, uint32_t oldCapacity, uint32_t oldInitLength,
CanOptimizeDenseSetElem(NativeObject *obj, uint32_t index,
Shape *oldShape, uint32_t oldCapacity, uint32_t oldInitLength,
bool *isAddingCaseOut, size_t *protoDepthOut)
{
uint32_t initLength = obj->getDenseInitializedLength();
@ -4916,7 +4917,7 @@ CanOptimizeDenseSetElem(JSContext *cx, HandleObject obj, uint32_t index,
if (initLength < oldInitLength || capacity < oldCapacity)
return false;
RootedShape shape(cx, obj->lastProperty());
Shape *shape = obj->lastProperty();
// Cannot optimize if the shape changed.
if (oldShape != shape)
@ -4950,7 +4951,7 @@ CanOptimizeDenseSetElem(JSContext *cx, HandleObject obj, uint32_t index,
// either directly, or via a prototype, or via the target object for a prototype
// which is a proxy, that handles a particular integer write.
// Scan the prototype and shape chain to make sure that this is not the case.
RootedObject curObj(cx, obj);
JSObject *curObj = obj;
while (curObj) {
// Ensure object is native.
if (!curObj->isNative())
@ -5000,8 +5001,8 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub_
uint32_t oldCapacity = 0;
uint32_t oldInitLength = 0;
if (obj->isNative() && index.isInt32() && index.toInt32() >= 0) {
oldCapacity = obj->getDenseCapacity();
oldInitLength = obj->getDenseInitializedLength();
oldCapacity = obj->as<NativeObject>().getDenseCapacity();
oldInitLength = obj->as<NativeObject>().getDenseInitializedLength();
}
if (op == JSOP_INITELEM) {
@ -5042,7 +5043,8 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub_
bool addingCase;
size_t protoDepth;
if (CanOptimizeDenseSetElem(cx, obj, index.toInt32(), oldShape, oldCapacity, oldInitLength,
if (CanOptimizeDenseSetElem(&obj->as<NativeObject>(), index.toInt32(),
oldShape, oldCapacity, oldInitLength,
&addingCase, &protoDepth))
{
RootedShape shape(cx, obj->lastProperty());
@ -5229,7 +5231,7 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
Register key = masm.extractInt32(R1, ExtractTemp1);
// Load obj->elements in scratchReg.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratchReg);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratchReg);
// Bounds check.
Address initLength(scratchReg, ObjectElements::offsetOfInitializedLength());
@ -5412,7 +5414,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
Register key = masm.extractInt32(R1, ExtractTemp1);
// Load obj->elements in scratchReg.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratchReg);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratchReg);
// Bounds check (key == initLength)
Address initLength(scratchReg, ObjectElements::offsetOfInitializedLength());
@ -5669,7 +5671,7 @@ ICIn_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
// Attach an optimized stub for a GETGNAME/CALLGNAME op.
static bool
TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc,
ICGetName_Fallback *stub, HandleObject global,
ICGetName_Fallback *stub, Handle<GlobalObject*> global,
HandlePropertyName name)
{
MOZ_ASSERT(global->is<GlobalObject>());
@ -5681,7 +5683,7 @@ TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc,
types::EnsureTrackPropertyTypes(cx, global, NameToId(name));
// The property must be found, and it must be found as a normal data property.
RootedShape shape(cx, global->nativeLookup(cx, id));
RootedShape shape(cx, global->lookup(cx, id));
if (!shape)
return true;
@ -5740,7 +5742,7 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
return false;
if (scopeChain->is<GlobalObject>()) {
shape = scopeChain->nativeLookup(cx, id);
shape = scopeChain->as<GlobalObject>().lookup(cx, id);
if (shape)
break;
return true;
@ -5752,7 +5754,7 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
// Check for an 'own' property on the scope. There is no need to
// check the prototype as non-with scopes do not inherit properties
// from any prototype.
shape = scopeChain->nativeLookup(cx, id);
shape = scopeChain->as<NativeObject>().lookup(cx, id);
if (shape)
break;
@ -5768,7 +5770,8 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
bool isFixedSlot;
uint32_t offset;
GetFixedOrDynamicSlotOffset(scopeChain, shape->slot(), &isFixedSlot, &offset);
GetFixedOrDynamicSlotOffset(&scopeChain->as<NativeObject>(),
shape->slot(), &isFixedSlot, &offset);
ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
ICStub *newStub;
@ -5861,7 +5864,7 @@ DoGetNameFallback(JSContext *cx, BaselineFrame *frame, ICGetName_Fallback *stub_
}
if (js_CodeSpec[*pc].format & JOF_GNAME) {
if (!TryAttachGlobalNameStub(cx, script, pc, stub, scopeChain, name))
if (!TryAttachGlobalNameStub(cx, script, pc, stub, scopeChain.as<GlobalObject>(), name))
return false;
} else {
if (!TryAttachScopeNameStub(cx, script, stub, scopeChain, name))
@ -5901,7 +5904,7 @@ ICGetName_Global::Compiler::generateStubCode(MacroAssembler &masm)
masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure);
// Load dynamic slot.
masm.loadPtr(Address(obj, JSObject::offsetOfSlots()), obj);
masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), obj);
masm.load32(Address(BaselineStubReg, ICGetName_Global::offsetOfSlot()), scratch);
masm.loadValue(BaseIndex(obj, scratch, TimesEight), R0);
@ -5941,7 +5944,7 @@ ICGetName_Scope<NumHops>::Compiler::generateStubCode(MacroAssembler &masm)
Register scope = NumHops ? walker : obj;
if (!isFixedSlot_) {
masm.loadPtr(Address(scope, JSObject::offsetOfSlots()), walker);
masm.loadPtr(Address(scope, NativeObject::offsetOfSlots()), walker);
scope = walker;
}
@ -6185,7 +6188,7 @@ static bool
UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback *stub,
HandleObject obj)
{
Value expandoSlot = obj->getFixedSlot(GetDOMProxyExpandoSlot());
Value expandoSlot = obj->fakeNativeGetReservedSlot(GetDOMProxyExpandoSlot());
MOZ_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
ExpandoAndGeneration *expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
@ -6272,7 +6275,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
if (!isDOMProxy && IsCacheableGetPropReadSlot(obj, holder, shape)) {
bool isFixedSlot;
uint32_t offset;
GetFixedOrDynamicSlotOffset(holder, shape->slot(), &isFixedSlot, &offset);
GetFixedOrDynamicSlotOffset(&holder->as<NativeObject>(), shape->slot(), &isFixedSlot, &offset);
// Instantiate this property for singleton holders, for use during Ion compilation.
if (IsIonEnabled(cx))
@ -6417,7 +6420,7 @@ TryAttachPrimitiveGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc
MOZ_ASSERT(!*attached);
JSValueType primitiveType;
RootedObject proto(cx);
RootedNativeObject proto(cx);
Rooted<GlobalObject*> global(cx, &script->global());
if (val.isString()) {
primitiveType = JSVAL_TYPE_STRING;
@ -6442,7 +6445,7 @@ TryAttachPrimitiveGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc
types::EnsureTrackPropertyTypes(cx, proto, id);
// For now, only look for properties directly set on the prototype.
RootedShape shape(cx, proto->nativeLookup(cx, id));
RootedShape shape(cx, proto->lookup(cx, id));
if (!shape || !shape->hasSlot() || !shape->hasDefaultGetter())
return true;
@ -6693,7 +6696,7 @@ ICGetProp_ArrayLength::Compiler::generateStubCode(MacroAssembler &masm)
masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, &ArrayObject::class_, &failure);
// Load obj->elements->length.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratch);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
masm.load32(Address(scratch, ObjectElements::offsetOfLength()), scratch);
// Guard length fits in an int32.
@ -6760,7 +6763,7 @@ ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler &masm)
masm.branchPtr(Assembler::NotEqual, shapeAddr, scratchReg, &failure);
if (!isFixedSlot_)
masm.loadPtr(Address(holderReg, JSObject::offsetOfSlots()), holderReg);
masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
masm.load32(Address(BaselineStubReg, ICGetPropNativeStub::offsetOfOffset()), scratchReg);
masm.loadValue(BaseIndex(holderReg, scratchReg, TimesOne), R0);
@ -6807,7 +6810,7 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler &masm)
// Don't overwrite actual holderReg if we need to load a dynamic slots object.
// May need to preserve object for noSuchMethod check later.
Register nextHolder = regs.takeAny();
masm.loadPtr(Address(holderReg, JSObject::offsetOfSlots()), nextHolder);
masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), nextHolder);
holderReg = nextHolder;
}
@ -7241,7 +7244,7 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace *space)
RootedShape shape(cx, proxy_->lastProperty());
RootedShape holderShape(cx, holder_->lastProperty());
Value expandoSlot = proxy_->getFixedSlot(GetDOMProxyExpandoSlot());
Value expandoSlot = proxy_->fakeNativeGetReservedSlot(GetDOMProxyExpandoSlot());
RootedShape expandoShape(cx, nullptr);
ExpandoAndGeneration *expandoAndGeneration;
int32_t generation;
@ -7528,7 +7531,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
bool isFixedSlot;
uint32_t offset;
GetFixedOrDynamicSlotOffset(obj, shape->slot(), &isFixedSlot, &offset);
GetFixedOrDynamicSlotOffset(&obj->as<NativeObject>(), shape->slot(), &isFixedSlot, &offset);
JitSpew(JitSpew_BaselineIC, " Generating SetProp(NativeObject.ADD) stub");
ICSetPropNativeAddCompiler compiler(cx, obj, oldShape, oldType,
@ -7557,7 +7560,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
bool isFixedSlot;
uint32_t offset;
GetFixedOrDynamicSlotOffset(obj, shape->slot(), &isFixedSlot, &offset);
GetFixedOrDynamicSlotOffset(&obj->as<NativeObject>(), shape->slot(), &isFixedSlot, &offset);
JitSpew(JitSpew_BaselineIC, " Generating SetProp(NativeObject.PROP) stub");
ICSetProp_Native::Compiler compiler(cx, obj, isFixedSlot, offset);
@ -7654,12 +7657,15 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
RootedTypeObject oldType(cx, obj->getType(cx));
if (!oldType)
return false;
uint32_t oldSlots = obj->numDynamicSlots();
uint32_t oldSlots = obj->fakeNativeNumDynamicSlots();
if (op == JSOP_INITPROP) {
MOZ_ASSERT(obj->is<JSObject>());
if (!DefineNativeProperty(cx, obj, id, rhs, nullptr, nullptr, JSPROP_ENUMERATE))
if (!DefineNativeProperty(cx, obj.as<NativeObject>(), id, rhs,
nullptr, nullptr, JSPROP_ENUMERATE))
{
return false;
}
} else if (op == JSOP_SETNAME || op == JSOP_SETGNAME) {
if (!SetNameOperation(cx, script, pc, obj, rhs))
return false;
@ -7798,7 +7804,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm)
holderReg = objReg;
} else {
holderReg = regs.takeAny();
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), holderReg);
masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
}
// Perform the store.
@ -7942,7 +7948,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
holderReg = objReg;
} else {
holderReg = regs.takeAny();
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), holderReg);
masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
}
// Perform the store. No write barrier required since this is a new
@ -8256,7 +8262,7 @@ TryAttachFunCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script,
static bool
GetTemplateObjectForNative(JSContext *cx, HandleScript script, jsbytecode *pc,
Native native, const CallArgs &args, MutableHandleObject res)
Native native, const CallArgs &args, MutableHandleNativeObject res)
{
// Check for natives to which template objects can be attached. This is
// done to provide templates to Ion for inlining these natives later on.
@ -8431,7 +8437,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
// Remember the template object associated with any script being called
// as a constructor, for later use during Ion compilation.
RootedObject templateObject(cx);
RootedNativeObject templateObject(cx);
if (constructing) {
templateObject = CreateThisForFunction(cx, fun, MaybeSingletonObject);
if (!templateObject)
@ -8496,7 +8502,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
return true;
}
RootedObject templateObject(cx);
RootedNativeObject templateObject(cx);
if (MOZ_LIKELY(!isSpread)) {
CallArgs args = CallArgsFromVp(argc, vp);
if (!GetTemplateObjectForNative(cx, script, pc, fun->native(), args, &templateObject))
@ -8520,7 +8526,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
}
static bool
CopyArray(JSContext *cx, HandleObject obj, MutableHandleValue result)
CopyArray(JSContext *cx, HandleArrayObject obj, MutableHandleValue result)
{
MOZ_ASSERT(obj->is<ArrayObject>());
uint32_t length = obj->as<ArrayObject>().length();
@ -8530,7 +8536,7 @@ CopyArray(JSContext *cx, HandleObject obj, MutableHandleValue result)
if (!type)
return false;
RootedObject newObj(cx, NewDenseArray(cx, length, type, NewArray_FullyAllocating));
RootedArrayObject newObj(cx, NewDenseArray(cx, length, type, NewArray_FullyAllocating));
if (!newObj)
return false;
@ -8554,13 +8560,12 @@ TryAttachStringSplit(JSContext *cx, ICCall_Fallback *stub, HandleScript script,
if (!IsOptimizableCallStringSplit(callee, thisv, argc, args))
return true;
MOZ_ASSERT(res.toObject().is<ArrayObject>());
MOZ_ASSERT(callee.isObject());
MOZ_ASSERT(callee.toObject().is<JSFunction>());
RootedString thisString(cx, thisv.toString());
RootedString argString(cx, args[0].toString());
RootedObject obj(cx, &res.toObject());
RootedArrayObject obj(cx, &res.toObject().as<ArrayObject>());
RootedValue arr(cx);
// Copy the array before storing in stub.
@ -8765,7 +8770,7 @@ void
ICCallStubCompiler::guardSpreadCall(MacroAssembler &masm, Register argcReg, Label *failure)
{
masm.unboxObject(Address(BaselineStackReg, ICStackValueOffset), argcReg);
masm.loadPtr(Address(argcReg, JSObject::offsetOfElements()), argcReg);
masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg);
masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg);
// Limit actual argc to something reasonable (huge number of arguments can
@ -8784,7 +8789,7 @@ ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegiste
Register startReg = regs.takeAny();
Register endReg = regs.takeAny();
masm.unboxObject(Address(BaselineStackReg, STUB_FRAME_SIZE), startReg);
masm.loadPtr(Address(startReg, JSObject::offsetOfElements()), startReg);
masm.loadPtr(Address(startReg, NativeObject::offsetOfElements()), startReg);
masm.mov(argcReg, endReg);
static_assert(sizeof(Value) == 8, "Value must be 8 bytes");
masm.lshiftPtr(Imm32(3), endReg);
@ -8847,7 +8852,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs,
&ArrayObject::class_, failure);
// Get the array elements and ensure that initializedLength == length
masm.loadPtr(Address(secondArgObj, JSObject::offsetOfElements()), secondArgObj);
masm.loadPtr(Address(secondArgObj, NativeObject::offsetOfElements()), secondArgObj);
Register lenReg = regsx.takeAny();
masm.load32(Address(secondArgObj, ObjectElements::offsetOfLength()), lenReg);
@ -8957,7 +8962,7 @@ ICCallStubCompiler::pushArrayArguments(MacroAssembler &masm, Address arrayVal,
Register startReg = regs.takeAny();
Register endReg = regs.takeAny();
masm.extractObject(arrayVal, startReg);
masm.loadPtr(Address(startReg, JSObject::offsetOfElements()), startReg);
masm.loadPtr(Address(startReg, NativeObject::offsetOfElements()), startReg);
masm.load32(Address(startReg, ObjectElements::offsetOfInitializedLength()), endReg);
JS_STATIC_ASSERT(sizeof(Value) == 8);
masm.lshiftPtr(Imm32(3), endReg);
@ -9355,7 +9360,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm)
return true;
}
typedef bool (*CopyArrayFn)(JSContext *, HandleObject, MutableHandleValue);
typedef bool (*CopyArrayFn)(JSContext *, HandleArrayObject, MutableHandleValue);
static const VMFunction CopyArrayInfo = FunctionInfo<CopyArrayFn>(CopyArray);
bool
@ -9617,7 +9622,7 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm)
// Reload argc from length of array.
masm.extractObject(arrayVal, argcReg);
masm.loadPtr(Address(argcReg, JSObject::offsetOfElements()), argcReg);
masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg);
masm.load32(Address(argcReg, ObjectElements::offsetOfInitializedLength()), argcReg);
masm.Push(argcReg);
@ -10852,7 +10857,7 @@ ICSetProp_CallNative::Clone(JSContext *cx, ICStubSpace *space, ICStub *,
}
ICCall_Scripted::ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub,
HandleScript calleeScript, HandleObject templateObject,
HandleScript calleeScript, HandleNativeObject templateObject,
uint32_t pcOffset)
: ICMonitoredStub(ICStub::Call_Scripted, stubCode, firstMonitorStub),
calleeScript_(calleeScript),
@ -10865,7 +10870,7 @@ ICCall_Scripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorSt
ICCall_Scripted &other)
{
RootedScript calleeScript(cx, other.calleeScript_);
RootedObject templateObject(cx, other.templateObject_);
RootedNativeObject templateObject(cx, other.templateObject_);
return New(space, other.jitCode(), firstMonitorStub, calleeScript, templateObject,
other.pcOffset_);
}
@ -10878,7 +10883,7 @@ ICCall_AnyScripted::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorS
}
ICCall_Native::ICCall_Native(JitCode *stubCode, ICStub *firstMonitorStub,
HandleFunction callee, HandleObject templateObject,
HandleFunction callee, HandleNativeObject templateObject,
uint32_t pcOffset)
: ICMonitoredStub(ICStub::Call_Native, stubCode, firstMonitorStub),
callee_(callee),
@ -10899,7 +10904,7 @@ ICCall_Native::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub
ICCall_Native &other)
{
RootedFunction callee(cx, other.callee_);
RootedObject templateObject(cx, other.templateObject_);
RootedNativeObject templateObject(cx, other.templateObject_);
return New(space, other.jitCode(), firstMonitorStub, callee, templateObject,
other.pcOffset_);
}
@ -11027,7 +11032,7 @@ static bool DoRestFallback(JSContext *cx, ICRest_Fallback *stub,
unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0;
Value *rest = frame->argv() + numFormals;
JSObject *obj = NewDenseCopiedArray(cx, numRest, rest, nullptr);
ArrayObject *obj = NewDenseCopiedArray(cx, numRest, rest, nullptr);
if (!obj)
return false;
types::FixRestArgumentsType(cx, obj);

Просмотреть файл

@ -16,6 +16,7 @@
#include "jit/BaselineJIT.h"
#include "jit/BaselineRegisters.h"
#include "vm/ArrayObject.h"
namespace js {
@ -1878,26 +1879,26 @@ class ICNewArray_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
HeapPtrObject templateObject_;
HeapPtrArrayObject templateObject_;
ICNewArray_Fallback(JitCode *stubCode, JSObject *templateObject)
ICNewArray_Fallback(JitCode *stubCode, ArrayObject *templateObject)
: ICFallbackStub(ICStub::NewArray_Fallback, stubCode), templateObject_(templateObject)
{}
public:
static inline ICNewArray_Fallback *New(ICStubSpace *space, JitCode *code,
JSObject *templateObject) {
ArrayObject *templateObject) {
if (!code)
return nullptr;
return space->allocate<ICNewArray_Fallback>(code, templateObject);
}
class Compiler : public ICStubCompiler {
RootedObject templateObject;
RootedArrayObject templateObject;
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx, JSObject *templateObject)
Compiler(JSContext *cx, ArrayObject *templateObject)
: ICStubCompiler(cx, ICStub::NewArray_Fallback),
templateObject(cx, templateObject)
{}
@ -1907,7 +1908,7 @@ class ICNewArray_Fallback : public ICFallbackStub
}
};
HeapPtrObject &templateObject() {
HeapPtrArrayObject &templateObject() {
return templateObject_;
}
};
@ -1916,26 +1917,26 @@ class ICNewObject_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
HeapPtrObject templateObject_;
HeapPtrNativeObject templateObject_;
ICNewObject_Fallback(JitCode *stubCode, JSObject *templateObject)
ICNewObject_Fallback(JitCode *stubCode, NativeObject *templateObject)
: ICFallbackStub(ICStub::NewObject_Fallback, stubCode), templateObject_(templateObject)
{}
public:
static inline ICNewObject_Fallback *New(ICStubSpace *space, JitCode *code,
JSObject *templateObject) {
NativeObject *templateObject) {
if (!code)
return nullptr;
return space->allocate<ICNewObject_Fallback>(code, templateObject);
}
class Compiler : public ICStubCompiler {
RootedObject templateObject;
RootedNativeObject templateObject;
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx, JSObject *templateObject)
Compiler(JSContext *cx, NativeObject *templateObject)
: ICStubCompiler(cx, ICStub::NewObject_Fallback),
templateObject(cx, templateObject)
{}
@ -1945,7 +1946,7 @@ class ICNewObject_Fallback : public ICFallbackStub
}
};
HeapPtrObject &templateObject() {
HeapPtrNativeObject &templateObject() {
return templateObject_;
}
};
@ -5679,17 +5680,17 @@ class ICCall_Scripted : public ICMonitoredStub
protected:
HeapPtrScript calleeScript_;
HeapPtrObject templateObject_;
HeapPtrNativeObject templateObject_;
uint32_t pcOffset_;
ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub,
HandleScript calleeScript, HandleObject templateObject,
HandleScript calleeScript, HandleNativeObject templateObject,
uint32_t pcOffset);
public:
static inline ICCall_Scripted *New(
ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
HandleScript calleeScript, HandleObject templateObject,
HandleScript calleeScript, HandleNativeObject templateObject,
uint32_t pcOffset)
{
if (!code)
@ -5704,7 +5705,7 @@ class ICCall_Scripted : public ICMonitoredStub
HeapPtrScript &calleeScript() {
return calleeScript_;
}
HeapPtrObject &templateObject() {
HeapPtrNativeObject &templateObject() {
return templateObject_;
}
@ -5752,7 +5753,7 @@ class ICCallScriptedCompiler : public ICCallStubCompiler {
bool isConstructing_;
bool isSpread_;
RootedScript calleeScript_;
RootedObject templateObject_;
RootedNativeObject templateObject_;
uint32_t pcOffset_;
bool generateStubCode(MacroAssembler &masm);
@ -5763,7 +5764,7 @@ class ICCallScriptedCompiler : public ICCallStubCompiler {
public:
ICCallScriptedCompiler(JSContext *cx, ICStub *firstMonitorStub,
HandleScript calleeScript, HandleObject templateObject,
HandleScript calleeScript, HandleNativeObject templateObject,
bool isConstructing, bool isSpread, uint32_t pcOffset)
: ICCallStubCompiler(cx, ICStub::Call_Scripted),
firstMonitorStub_(firstMonitorStub),
@ -5801,7 +5802,7 @@ class ICCall_Native : public ICMonitoredStub
protected:
HeapPtrFunction callee_;
HeapPtrObject templateObject_;
HeapPtrNativeObject templateObject_;
uint32_t pcOffset_;
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
@ -5809,12 +5810,12 @@ class ICCall_Native : public ICMonitoredStub
#endif
ICCall_Native(JitCode *stubCode, ICStub *firstMonitorStub,
HandleFunction callee, HandleObject templateObject,
HandleFunction callee, HandleNativeObject templateObject,
uint32_t pcOffset);
public:
static inline ICCall_Native *New(ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub,
HandleFunction callee, HandleObject templateObject,
HandleFunction callee, HandleNativeObject templateObject,
uint32_t pcOffset)
{
if (!code)
@ -5829,7 +5830,7 @@ class ICCall_Native : public ICMonitoredStub
HeapPtrFunction &callee() {
return callee_;
}
HeapPtrObject &templateObject() {
HeapPtrNativeObject &templateObject() {
return templateObject_;
}
@ -5853,7 +5854,7 @@ class ICCall_Native : public ICMonitoredStub
bool isConstructing_;
bool isSpread_;
RootedFunction callee_;
RootedObject templateObject_;
RootedNativeObject templateObject_;
uint32_t pcOffset_;
bool generateStubCode(MacroAssembler &masm);
@ -5864,7 +5865,7 @@ class ICCall_Native : public ICMonitoredStub
public:
Compiler(JSContext *cx, ICStub *firstMonitorStub,
HandleFunction callee, HandleObject templateObject,
HandleFunction callee, HandleNativeObject templateObject,
bool isConstructing, bool isSpread, uint32_t pcOffset)
: ICCallStubCompiler(cx, ICStub::Call_Native),
firstMonitorStub_(firstMonitorStub),
@ -6422,9 +6423,9 @@ class ICRest_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
HeapPtrObject templateObject_;
HeapPtrArrayObject templateObject_;
ICRest_Fallback(JitCode *stubCode, JSObject *templateObject)
ICRest_Fallback(JitCode *stubCode, ArrayObject *templateObject)
: ICFallbackStub(ICStub::Rest_Fallback, stubCode), templateObject_(templateObject)
{ }
@ -6432,23 +6433,23 @@ class ICRest_Fallback : public ICFallbackStub
static const uint32_t MAX_OPTIMIZED_STUBS = 8;
static inline ICRest_Fallback *New(ICStubSpace *space, JitCode *code,
JSObject *templateObject) {
ArrayObject *templateObject) {
if (!code)
return nullptr;
return space->allocate<ICRest_Fallback>(code, templateObject);
}
HeapPtrObject &templateObject() {
HeapPtrArrayObject &templateObject() {
return templateObject_;
}
class Compiler : public ICStubCompiler {
protected:
RootedObject templateObject;
RootedArrayObject templateObject;
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx, JSObject *templateObject)
Compiler(JSContext *cx, ArrayObject *templateObject)
: ICStubCompiler(cx, ICStub::Rest_Fallback),
templateObject(cx, templateObject)
{ }
@ -6553,7 +6554,7 @@ IsCacheableDOMProxy(JSObject *obj)
if (handler->family() != GetDOMProxyHandlerFamily())
return false;
if (obj->numFixedSlots() <= GetDOMProxyExpandoSlot())
if (obj->fakeNativeNumFixedSlots() <= GetDOMProxyExpandoSlot())
return false;
return true;

Просмотреть файл

@ -413,7 +413,7 @@ BaselineInspector::hasSeenDoubleResult(jsbytecode *pc)
return false;
}
JSObject *
NativeObject *
BaselineInspector::getTemplateObject(jsbytecode *pc)
{
if (!hasBaselineScript())
@ -429,7 +429,7 @@ BaselineInspector::getTemplateObject(jsbytecode *pc)
case ICStub::Rest_Fallback:
return stub->toRest_Fallback()->templateObject();
case ICStub::Call_Scripted:
if (JSObject *obj = stub->toCall_Scripted()->templateObject())
if (NativeObject *obj = stub->toCall_Scripted()->templateObject())
return obj;
break;
default:
@ -440,7 +440,7 @@ BaselineInspector::getTemplateObject(jsbytecode *pc)
return nullptr;
}
JSObject *
NativeObject *
BaselineInspector::getTemplateObjectForNative(jsbytecode *pc, Native native)
{
if (!hasBaselineScript())

Просмотреть файл

@ -109,8 +109,8 @@ class BaselineInspector
bool hasSeenDoubleResult(jsbytecode *pc);
bool hasSeenNonStringIterMore(jsbytecode *pc);
JSObject *getTemplateObject(jsbytecode *pc);
JSObject *getTemplateObjectForNative(jsbytecode *pc, Native native);
NativeObject *getTemplateObject(jsbytecode *pc);
NativeObject *getTemplateObjectForNative(jsbytecode *pc, Native native);
DeclEnvObject *templateDeclEnvObject();
CallObject *templateCallObject();

Просмотреть файл

@ -1376,7 +1376,7 @@ CodeGenerator::visitTableSwitchV(LTableSwitchV *ins)
return emitTableSwitchDispatch(mir, index, ToRegisterOrInvalid(ins->tempPointer()));
}
typedef JSObject *(*DeepCloneObjectLiteralFn)(JSContext *, HandleObject, NewObjectKind);
typedef NativeObject *(*DeepCloneObjectLiteralFn)(JSContext *, HandleNativeObject, NewObjectKind);
static const VMFunction DeepCloneObjectLiteralInfo =
FunctionInfo<DeepCloneObjectLiteralFn>(DeepCloneObjectLiteral);
@ -1634,7 +1634,7 @@ CodeGenerator::visitPointer(LPointer *lir)
bool
CodeGenerator::visitSlots(LSlots *lir)
{
Address slots(ToRegister(lir->object()), JSObject::offsetOfSlots());
Address slots(ToRegister(lir->object()), NativeObject::offsetOfSlots());
masm.loadPtr(slots, ToRegister(lir->output()));
return true;
}
@ -1722,12 +1722,12 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction *ins, Register obj, Regis
Shape *shape = mir->shape(i);
if (shape->slot() < shape->numFixedSlots()) {
// Fixed slot.
masm.loadTypedOrValue(Address(obj, JSObject::getFixedSlotOffset(shape->slot())),
masm.loadTypedOrValue(Address(obj, NativeObject::getFixedSlotOffset(shape->slot())),
output);
} else {
// Dynamic slot.
uint32_t offset = (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value);
masm.loadPtr(Address(obj, JSObject::offsetOfSlots()), scratch);
masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch);
masm.loadTypedOrValue(Address(scratch, offset), output);
}
@ -1784,13 +1784,13 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction *ins, Register obj, Regis
Shape *shape = mir->shape(i);
if (shape->slot() < shape->numFixedSlots()) {
// Fixed slot.
Address addr(obj, JSObject::getFixedSlotOffset(shape->slot()));
Address addr(obj, NativeObject::getFixedSlotOffset(shape->slot()));
if (mir->needsBarrier())
emitPreBarrier(addr);
masm.storeConstantOrRegister(value, addr);
} else {
// Dynamic slot.
masm.loadPtr(Address(obj, JSObject::offsetOfSlots()), scratch);
masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch);
Address addr(scratch, (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value));
if (mir->needsBarrier())
emitPreBarrier(addr);
@ -1833,7 +1833,7 @@ CodeGenerator::visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT *ins)
bool
CodeGenerator::visitElements(LElements *lir)
{
Address elements(ToRegister(lir->object()), JSObject::offsetOfElements());
Address elements(ToRegister(lir->object()), NativeObject::offsetOfElements());
masm.loadPtr(elements, ToRegister(lir->output()));
return true;
}
@ -1887,9 +1887,9 @@ CodeGenerator::visitMaybeToDoubleElement(LMaybeToDoubleElement *lir)
return true;
}
typedef bool (*CopyElementsForWriteFn)(ThreadSafeContext *, JSObject *);
typedef bool (*CopyElementsForWriteFn)(ThreadSafeContext *, NativeObject *);
static const VMFunction CopyElementsForWriteInfo =
FunctionInfo<CopyElementsForWriteFn>(JSObject::CopyElementsForWrite);
FunctionInfo<CopyElementsForWriteFn>(NativeObject::CopyElementsForWrite);
bool
CodeGenerator::visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite *lir)
@ -1902,7 +1902,7 @@ CodeGenerator::visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite *lir)
if (!ool)
return false;
masm.loadPtr(Address(object, JSObject::offsetOfElements()), temp);
masm.loadPtr(Address(object, NativeObject::offsetOfElements()), temp);
masm.branchTest32(Assembler::NonZero,
Address(temp, ObjectElements::offsetOfFlags()),
Imm32(ObjectElements::COPY_ON_WRITE),
@ -2278,7 +2278,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
masm.computeEffectiveAddress(Address(StackPointer, 2 * sizeof(Value)), argArgs);
// GetReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate()
masm.loadPrivate(Address(obj, JSObject::getFixedSlotOffset(0)), argPrivate);
masm.loadPrivate(Address(obj, NativeObject::getFixedSlotOffset(0)), argPrivate);
// Push argc from the call instruction into what will become the IonExitFrame
masm.Push(Imm32(call->numStackArgs()));
@ -3595,10 +3595,10 @@ CodeGenerator::visitNewArray(LNewArray *lir)
MOZ_ASSERT(gen->info().executionMode() == SequentialExecution);
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObject = lir->mir()->templateObject();
ArrayObject *templateObject = lir->mir()->templateObject();
DebugOnly<uint32_t> count = lir->mir()->count();
MOZ_ASSERT(count < JSObject::NELEMENTS_LIMIT);
MOZ_ASSERT(count < NativeObject::NELEMENTS_LIMIT);
if (lir->mir()->shouldUseVM())
return visitNewArrayCallVM(lir);
@ -3627,7 +3627,7 @@ CodeGenerator::visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite *lir)
{
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObject = lir->mir()->templateObject();
ArrayObject *templateObject = lir->mir()->templateObject();
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
// If we have a template object, we can inline call object creation.
@ -3662,7 +3662,7 @@ class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator>
}
};
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandleObject);
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandleNativeObject);
static const VMFunction NewInitObjectInfo = FunctionInfo<NewInitObjectFn>(NewInitObject);
typedef JSObject *(*NewInitObjectWithClassPrototypeFn)(JSContext *, HandleObject);
@ -3700,7 +3700,7 @@ CodeGenerator::visitNewObjectVMCall(LNewObject *lir)
}
static bool
ShouldInitFixedSlots(LInstruction *lir, JSObject *templateObj)
ShouldInitFixedSlots(LInstruction *lir, NativeObject *templateObj)
{
// Look for StoreFixedSlot instructions following an object allocation
// that write to this object before a GC is triggered or this object is
@ -3721,8 +3721,8 @@ ShouldInitFixedSlots(LInstruction *lir, JSObject *templateObj)
// Keep track of the fixed slots that are initialized. initializedSlots is
// a bit mask with a bit for each slot.
MOZ_ASSERT(nfixed <= JSObject::MAX_FIXED_SLOTS);
static_assert(JSObject::MAX_FIXED_SLOTS <= 32, "Slot bits must fit in 32 bits");
MOZ_ASSERT(nfixed <= NativeObject::MAX_FIXED_SLOTS);
static_assert(NativeObject::MAX_FIXED_SLOTS <= 32, "Slot bits must fit in 32 bits");
uint32_t initializedSlots = 0;
uint32_t numInitialized = 0;
@ -3789,7 +3789,7 @@ CodeGenerator::visitNewObject(LNewObject *lir)
MOZ_ASSERT(gen->info().executionMode() == SequentialExecution);
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObject = lir->mir()->templateObject();
NativeObject *templateObject = lir->mir()->templateObject();
if (lir->mir()->shouldUseVM())
return visitNewObjectVMCall(lir);
@ -3824,7 +3824,7 @@ CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
{
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObj = lir->mir()->templateObj();
NativeObject *templateObj = lir->mir()->templateObj();
CompileInfo &info = lir->mir()->block()->info();
// If we have a template object, we can inline call object creation.
@ -3853,7 +3853,7 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObj = lir->mir()->templateObject();
NativeObject *templateObj = lir->mir()->templateObject();
OutOfLineCode *ool = oolCallVM(NewCallObjectInfo, lir,
(ArgList(), ImmGCPtr(templateObj->lastProperty()),
@ -3905,12 +3905,12 @@ CodeGenerator::visitNewCallObjectPar(LNewCallObjectPar *lir)
Register cxReg = ToRegister(lir->forkJoinContext());
Register tempReg1 = ToRegister(lir->getTemp0());
Register tempReg2 = ToRegister(lir->getTemp1());
JSObject *templateObj = lir->mir()->templateObj();
NativeObject *templateObj = lir->mir()->templateObj();
return emitAllocateGCThingPar(lir, resultReg, cxReg, tempReg1, tempReg2, templateObj);
}
typedef JSObject *(*ExtendArrayParFn)(ForkJoinContext*, JSObject*, uint32_t);
typedef ArrayObject *(*ExtendArrayParFn)(ForkJoinContext*, ArrayObject*, uint32_t);
static const VMFunction ExtendArrayParInfo =
FunctionInfo<ExtendArrayParFn>(ExtendArrayPar);
@ -3922,7 +3922,7 @@ CodeGenerator::visitNewDenseArrayPar(LNewDenseArrayPar *lir)
Register tempReg0 = ToRegister(lir->getTemp0());
Register tempReg1 = ToRegister(lir->getTemp1());
Register tempReg2 = ToRegister(lir->getTemp2());
JSObject *templateObj = lir->mir()->templateObject();
ArrayObject *templateObj = lir->mir()->templateObject();
if (!emitAllocateGCThingPar(lir, tempReg2, cxReg, tempReg0, tempReg1, templateObj))
return false;
@ -3976,7 +3976,7 @@ CodeGenerator::visitNewPar(LNewPar *lir)
Register cxReg = ToRegister(lir->forkJoinContext());
Register tempReg1 = ToRegister(lir->getTemp0());
Register tempReg2 = ToRegister(lir->getTemp1());
JSObject *templateObject = lir->mir()->templateObject();
NativeObject *templateObject = lir->mir()->templateObject();
return emitAllocateGCThingPar(lir, objReg, cxReg, tempReg1, tempReg2, templateObject);
}
@ -4006,7 +4006,7 @@ static const VMFunction NewGCThingParInfo =
bool
CodeGenerator::emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg,
Register tempReg1, Register tempReg2, JSObject *templateObj)
Register tempReg1, Register tempReg2, NativeObject *templateObj)
{
MOZ_ASSERT(lir->mirRaw());
MOZ_ASSERT(lir->mirRaw()->isInstruction());
@ -4103,7 +4103,7 @@ CodeGenerator::visitMutateProto(LMutateProto *lir)
return callVM(MutatePrototypeInfo, lir);
}
typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj,
typedef bool(*InitPropFn)(JSContext *cx, HandleNativeObject obj,
HandlePropertyName name, HandleValue value);
static const VMFunction InitPropInfo =
FunctionInfo<InitPropFn>(InitProp);
@ -4192,7 +4192,7 @@ static const VMFunction NewGCObjectInfo =
bool
CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
{
JSObject *templateObject = lir->mir()->templateObject();
NativeObject *templateObject = lir->mir()->templateObject();
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
Register objReg = ToRegister(lir->output());
@ -5947,7 +5947,7 @@ CodeGenerator::visitStoreElementHoleV(LStoreElementHoleV *lir)
return true;
}
typedef bool (*SetDenseElementFn)(JSContext *, HandleObject, int32_t, HandleValue,
typedef bool (*SetDenseElementFn)(JSContext *, HandleNativeObject, int32_t, HandleValue,
bool strict);
typedef bool (*SetDenseElementParFn)(ForkJoinContext *, HandleObject, int32_t, HandleValue, bool);
static const VMFunctionsModal SetDenseElementInfo = VMFunctionsModal(
@ -6069,7 +6069,7 @@ CodeGenerator::emitArrayPopShift(LInstruction *lir, const MArrayPopShift *mir, R
masm.branchTestNeedsIncrementalBarrier(Assembler::NonZero, ool->entry());
// Load elements and length.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), elementsTemp);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp);
masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), lengthTemp);
// VM call if length != initializedLength.
@ -6152,7 +6152,7 @@ CodeGenerator::visitArrayPopShiftT(LArrayPopShiftT *lir)
return emitArrayPopShift(lir, lir->mir(), obj, elements, length, out);
}
typedef bool (*ArrayPushDenseFn)(JSContext *, HandleObject, HandleValue, uint32_t *);
typedef bool (*ArrayPushDenseFn)(JSContext *, HandleArrayObject, HandleValue, uint32_t *);
static const VMFunction ArrayPushDenseInfo =
FunctionInfo<ArrayPushDenseFn>(jit::ArrayPushDense);
@ -6165,7 +6165,7 @@ CodeGenerator::emitArrayPush(LInstruction *lir, const MArrayPush *mir, Register
return false;
// Load elements and length.
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), elementsTemp);
masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp);
masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length);
Int32Key key = Int32Key(length);
@ -6227,11 +6227,11 @@ CodeGenerator::visitArrayConcat(LArrayConcat *lir)
// inline and pass it to the stub. Else, we just pass nullptr and the stub falls
// back to a slow path.
Label fail, call;
masm.loadPtr(Address(lhs, JSObject::offsetOfElements()), temp1);
masm.loadPtr(Address(lhs, NativeObject::offsetOfElements()), temp1);
masm.load32(Address(temp1, ObjectElements::offsetOfInitializedLength()), temp2);
masm.branch32(Assembler::NotEqual, Address(temp1, ObjectElements::offsetOfLength()), temp2, &fail);
masm.loadPtr(Address(rhs, JSObject::offsetOfElements()), temp1);
masm.loadPtr(Address(rhs, NativeObject::offsetOfElements()), temp1);
masm.load32(Address(temp1, ObjectElements::offsetOfInitializedLength()), temp2);
masm.branch32(Assembler::NotEqual, Address(temp1, ObjectElements::offsetOfLength()), temp2, &fail);
@ -6326,7 +6326,7 @@ CodeGenerator::visitIteratorStart(LIteratorStart *lir)
// Ensure the object does not have any elements. The presence of dense
// elements is not captured by the shape tests above.
masm.branchPtr(Assembler::NotEqual,
Address(obj, JSObject::offsetOfElements()),
Address(obj, NativeObject::offsetOfElements()),
ImmPtr(js::emptyObjectElements),
ool->entry());
@ -6571,7 +6571,7 @@ CodeGenerator::visitRunOncePrologue(LRunOncePrologue *lir)
typedef JSObject *(*InitRestParameterFn)(JSContext *, uint32_t, Value *, HandleObject,
HandleObject);
typedef JSObject *(*InitRestParameterParFn)(ForkJoinContext *, uint32_t, Value *,
HandleObject, HandleObject);
HandleObject, HandleArrayObject);
static const VMFunctionsModal InitRestParameterInfo = VMFunctionsModal(
FunctionInfo<InitRestParameterFn>(InitRestParameter),
FunctionInfo<InitRestParameterParFn>(InitRestParameterPar));
@ -6624,7 +6624,7 @@ CodeGenerator::visitRest(LRest *lir)
Register temp1 = ToRegister(lir->getTemp(1));
Register temp2 = ToRegister(lir->getTemp(2));
unsigned numFormals = lir->mir()->numFormals();
JSObject *templateObject = lir->mir()->templateObject();
ArrayObject *templateObject = lir->mir()->templateObject();
Label joinAlloc, failAlloc;
masm.createGCObject(temp2, temp0, templateObject, gc::DefaultHeap, &failAlloc);
@ -6650,7 +6650,7 @@ CodeGenerator::visitRestPar(LRestPar *lir)
Register temp1 = ToRegister(lir->getTemp(1));
Register temp2 = ToRegister(lir->getTemp(2));
unsigned numFormals = lir->mir()->numFormals();
JSObject *templateObject = lir->mir()->templateObject();
ArrayObject *templateObject = lir->mir()->templateObject();
if (!emitAllocateGCThingPar(lir, temp2, cx, temp0, temp1, templateObject))
return false;
@ -7213,7 +7213,7 @@ CodeGenerator::visitLoadFixedSlotV(LLoadFixedSlotV *ins)
size_t slot = ins->mir()->slot();
ValueOperand result = GetValueOutput(ins);
masm.loadValue(Address(obj, JSObject::getFixedSlotOffset(slot)), result);
masm.loadValue(Address(obj, NativeObject::getFixedSlotOffset(slot)), result);
return true;
}
@ -7225,7 +7225,7 @@ CodeGenerator::visitLoadFixedSlotT(LLoadFixedSlotT *ins)
AnyRegister result = ToAnyRegister(ins->getDef(0));
MIRType type = ins->mir()->type();
masm.loadUnboxedValue(Address(obj, JSObject::getFixedSlotOffset(slot)), type, result);
masm.loadUnboxedValue(Address(obj, NativeObject::getFixedSlotOffset(slot)), type, result);
return true;
}
@ -7238,7 +7238,7 @@ CodeGenerator::visitStoreFixedSlotV(LStoreFixedSlotV *ins)
const ValueOperand value = ToValue(ins, LStoreFixedSlotV::Value);
Address address(obj, JSObject::getFixedSlotOffset(slot));
Address address(obj, NativeObject::getFixedSlotOffset(slot));
if (ins->mir()->needsBarrier())
emitPreBarrier(address);
@ -7260,7 +7260,7 @@ CodeGenerator::visitStoreFixedSlotT(LStoreFixedSlotT *ins)
? ConstantOrRegister(*value->toConstant())
: TypedOrValueRegister(valueType, ToAnyRegister(value));
Address address(obj, JSObject::getFixedSlotOffset(slot));
Address address(obj, NativeObject::getFixedSlotOffset(slot));
if (ins->mir()->needsBarrier())
emitPreBarrier(address);
@ -8595,14 +8595,14 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty *ins)
// It's a bit annoying to redo these slot calculations, which duplcate
// LSlots and a few other things like that, but I'm not sure there's a
// way to reuse those here.
if (slot < JSObject::MAX_FIXED_SLOTS) {
masm.loadValue(Address(ObjectReg, JSObject::getFixedSlotOffset(slot)),
if (slot < NativeObject::MAX_FIXED_SLOTS) {
masm.loadValue(Address(ObjectReg, NativeObject::getFixedSlotOffset(slot)),
JSReturnOperand);
} else {
// It's a dynamic slot.
slot -= JSObject::MAX_FIXED_SLOTS;
slot -= NativeObject::MAX_FIXED_SLOTS;
// Use PrivateReg as a scratch register for the slots pointer.
masm.loadPtr(Address(ObjectReg, JSObject::offsetOfSlots()),
masm.loadPtr(Address(ObjectReg, NativeObject::offsetOfSlots()),
PrivateReg);
masm.loadValue(Address(PrivateReg, slot*sizeof(js::Value)),
JSReturnOperand);
@ -8625,7 +8625,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty *ins)
masm.Push(ObjectReg);
// GetReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate()
masm.loadPrivate(Address(ObjectReg, JSObject::getFixedSlotOffset(0)), PrivateReg);
masm.loadPrivate(Address(ObjectReg, NativeObject::getFixedSlotOffset(0)), PrivateReg);
// Rooting will happen at GC time.
masm.movePtr(StackPointer, ObjectReg);
@ -8677,7 +8677,7 @@ CodeGenerator::visitGetDOMMember(LGetDOMMember *ins)
size_t slot = ins->mir()->domMemberSlotIndex();
ValueOperand result = GetValueOutput(ins);
masm.loadValue(Address(object, JSObject::getFixedSlotOffset(slot)), result);
masm.loadValue(Address(object, NativeObject::getFixedSlotOffset(slot)), result);
return true;
}
@ -8704,7 +8704,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty *ins)
masm.Push(ObjectReg);
// GetReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate()
masm.loadPrivate(Address(ObjectReg, JSObject::getFixedSlotOffset(0)), PrivateReg);
masm.loadPrivate(Address(ObjectReg, NativeObject::getFixedSlotOffset(0)), PrivateReg);
// Rooting will happen at GC time.
masm.movePtr(StackPointer, ObjectReg);

Просмотреть файл

@ -388,7 +388,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg,
Register tempReg1, Register tempReg2,
JSObject *templateObj);
NativeObject *templateObj);
bool emitCallToUncompiledScriptPar(LInstruction *lir, Register calleeReg);

Просмотреть файл

@ -2689,7 +2689,7 @@ jit::ConvertLinearInequality(TempAllocator &alloc, MBasicBlock *block, const Lin
static bool
AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
MDefinition *thisValue, MInstruction *ins, bool definitelyExecuted,
HandleObject baseobj,
HandleNativeObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList,
Vector<PropertyName *> *accessedProperties,
bool *phandled)
@ -2714,7 +2714,7 @@ AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
}
// Ignore assignments to properties that were already written to.
if (baseobj->nativeLookup(cx, NameToId(setprop->name()))) {
if (baseobj->lookup(cx, NameToId(setprop->name()))) {
*phandled = true;
return true;
}
@ -2744,7 +2744,7 @@ AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
// Add the property to the object, being careful not to update type information.
DebugOnly<unsigned> slotSpan = baseobj->slotSpan();
MOZ_ASSERT(!baseobj->nativeContainsPure(id));
MOZ_ASSERT(!baseobj->containsPure(id));
if (!baseobj->addDataProperty(cx, id, baseobj->slotSpan(), JSPROP_ENUMERATE))
return false;
MOZ_ASSERT(baseobj->slotSpan() != slotSpan);
@ -2793,7 +2793,7 @@ AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
* definite property before it is assigned could incorrectly hit.
*/
RootedId id(cx, NameToId(get->name()));
if (!baseobj->nativeLookup(cx, id) && !accessedProperties->append(get->name()))
if (!baseobj->lookup(cx, id) && !accessedProperties->append(get->name()))
return false;
if (!types::AddClearDefiniteGetterSetterForPrototypeChain(cx, type, id)) {
@ -2823,7 +2823,7 @@ CmpInstructions(const void *a, const void *b)
bool
jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleObject baseobj,
types::TypeObject *type, HandleNativeObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList)
{
MOZ_ASSERT(cx->compartment()->activeAnalysis);

Просмотреть файл

@ -162,7 +162,7 @@ ConvertLinearInequality(TempAllocator &alloc, MBasicBlock *block, const LinearSu
bool
AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleObject baseobj,
types::TypeObject *type, HandleNativeObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList);
bool

Просмотреть файл

@ -29,6 +29,7 @@
#include "jit/CompileInfo-inl.h"
#include "jit/ExecutionMode-inl.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::jit;
@ -5809,7 +5810,7 @@ IonBuilder::jsop_compare(JSOp op)
bool
IonBuilder::jsop_newarray(uint32_t count)
{
JSObject *templateObject = inspector->getTemplateObject(pc);
NativeObject *templateObject = inspector->getTemplateObject(pc);
if (!templateObject) {
if (info().executionMode() == ArgumentsUsageAnalysis) {
MUnknownValue *unknown = MUnknownValue::New(alloc());
@ -5855,7 +5856,7 @@ IonBuilder::jsop_newarray(uint32_t count)
bool
IonBuilder::jsop_newarray_copyonwrite()
{
JSObject *templateObject = types::GetCopyOnWriteObject(script(), pc);
ArrayObject *templateObject = types::GetCopyOnWriteObject(script(), pc);
// The baseline compiler should have ensured the template object has a type
// with the copy on write flag set already. During the arguments usage
@ -5958,7 +5959,7 @@ IonBuilder::jsop_initelem_array()
MElements *elements = MElements::New(alloc(), obj);
current->add(elements);
JSObject *templateObject = obj->toNewArray()->templateObject();
NativeObject *templateObject = obj->toNewArray()->templateObject();
if (templateObject->shouldConvertDoubleElements()) {
MInstruction *valueDouble = MToDouble::New(alloc(), value);
@ -5999,7 +6000,7 @@ IonBuilder::jsop_initprop(PropertyName *name)
MDefinition *value = current->pop();
MDefinition *obj = current->peek(-1);
JSObject *templateObject = nullptr;
NativeObject *templateObject = nullptr;
Shape *shape = nullptr;
bool useSlowPath = false;
@ -8576,8 +8577,7 @@ IonBuilder::jsop_arguments()
bool
IonBuilder::jsop_rest()
{
JSObject *templateObject = inspector->getTemplateObject(pc);
MOZ_ASSERT(templateObject->is<ArrayObject>());
ArrayObject *templateObject = &inspector->getTemplateObject(pc)->as<ArrayObject>();
if (inliningDepth_ == 0) {
// We don't know anything about the callee.
@ -9323,13 +9323,13 @@ IonBuilder::getPropTryDefiniteSlot(bool *emitted, MDefinition *obj, PropertyName
}
MInstruction *load;
if (slot < JSObject::MAX_FIXED_SLOTS) {
if (slot < NativeObject::MAX_FIXED_SLOTS) {
load = MLoadFixedSlot::New(alloc(), obj, slot);
} else {
MInstruction *slots = MSlots::New(alloc(), obj);
current->add(slots);
load = MLoadSlot::New(alloc(), slots, slot - JSObject::MAX_FIXED_SLOTS);
load = MLoadSlot::New(alloc(), slots, slot - NativeObject::MAX_FIXED_SLOTS);
}
if (barrier == BarrierKind::NoBarrier)
@ -9977,7 +9977,7 @@ IonBuilder::setPropTryDefiniteSlot(bool *emitted, MDefinition *obj,
}
MInstruction *store;
if (slot < JSObject::MAX_FIXED_SLOTS) {
if (slot < NativeObject::MAX_FIXED_SLOTS) {
store = MStoreFixedSlot::New(alloc(), obj, slot, value);
if (writeBarrier)
store->toStoreFixedSlot()->setNeedsBarrier();
@ -9985,7 +9985,7 @@ IonBuilder::setPropTryDefiniteSlot(bool *emitted, MDefinition *obj,
MInstruction *slots = MSlots::New(alloc(), obj);
current->add(slots);
store = MStoreSlot::New(alloc(), slots, slot - JSObject::MAX_FIXED_SLOTS, value);
store = MStoreSlot::New(alloc(), slots, slot - NativeObject::MAX_FIXED_SLOTS, value);
if (writeBarrier)
store->toStoreSlot()->setNeedsBarrier();
}

Просмотреть файл

@ -654,15 +654,15 @@ IsCacheableGetPropCallPropertyOp(JSObject *obj, JSObject *holder, Shape *shape)
}
static inline void
EmitLoadSlot(MacroAssembler &masm, JSObject *holder, Shape *shape, Register holderReg,
EmitLoadSlot(MacroAssembler &masm, NativeObject *holder, Shape *shape, Register holderReg,
TypedOrValueRegister output, Register scratchReg)
{
MOZ_ASSERT(holder);
if (holder->isFixedSlot(shape->slot())) {
Address addr(holderReg, JSObject::getFixedSlotOffset(shape->slot()));
Address addr(holderReg, NativeObject::getFixedSlotOffset(shape->slot()));
masm.loadTypedOrValue(addr, output);
} else {
masm.loadPtr(Address(holderReg, JSObject::offsetOfSlots()), scratchReg);
masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), scratchReg);
Address addr(scratchReg, holder->dynamicSlotIndex(shape->slot()) * sizeof(Value));
masm.loadTypedOrValue(addr, output);
@ -681,7 +681,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
// 2. The object does not have expando properties, or has an expando
// which is known to not have the desired property.
Address handlerAddr(object, ProxyObject::offsetOfHandler());
Address expandoSlotAddr(object, JSObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
Address expandoSlotAddr(object, NativeObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
// Check that object is a DOMProxy.
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr,
@ -700,7 +700,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
Label failDOMProxyCheck;
Label domProxyOk;
Value expandoVal = obj->getFixedSlot(GetDOMProxyExpandoSlot());
Value expandoVal = obj->fakeNativeGetSlot(GetDOMProxyExpandoSlot());
masm.loadValue(expandoSlotAddr, tempVal);
if (!expandoVal.isObject() && !expandoVal.isUndefined()) {
@ -726,7 +726,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
masm.branchTestUndefined(Assembler::Equal, tempVal, &domProxyOk);
if (expandoVal.isObject()) {
MOZ_ASSERT(!expandoVal.toObject().nativeContains(cx, name));
MOZ_ASSERT(!expandoVal.toObject().as<NativeObject>().contains(cx, name));
// Reference object has an expando object that doesn't define the name. Check that
// the incoming object has an expando object with the same shape.
@ -750,7 +750,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
static void
GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm,
IonCache::StubAttacher &attacher, JSObject *obj, JSObject *holder,
IonCache::StubAttacher &attacher, JSObject *obj, NativeObject *holder,
Shape *shape, Register object, TypedOrValueRegister output,
Label *failures = nullptr)
{
@ -1075,7 +1075,7 @@ GenerateArrayLength(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher
outReg = output.typedReg().gpr();
}
masm.loadPtr(Address(object, JSObject::offsetOfElements()), outReg);
masm.loadPtr(Address(object, NativeObject::offsetOfElements()), outReg);
masm.load32(Address(outReg, ObjectElements::offsetOfLength()), outReg);
// The length is an unsigned int, but the value encodes a signed int.
@ -1152,7 +1152,7 @@ template <class GetPropCache>
static GetPropertyIC::NativeGetPropCacheability
CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &cache,
HandleObject obj, HandlePropertyName name,
MutableHandleObject holder, MutableHandleShape shape,
MutableHandleNativeObject holder, MutableHandleShape shape,
bool skipArrayLen = false)
{
if (!obj || !obj->isNative())
@ -1241,7 +1241,7 @@ GetPropertyIC::tryAttachNative(JSContext *cx, HandleScript outerScript, IonScrip
MOZ_ASSERT(outerScript->ionScript() == ion);
RootedShape shape(cx);
RootedObject holder(cx);
RootedNativeObject holder(cx);
NativeGetPropCacheability type =
CanAttachNativeGetProp(cx, *this, obj, name, &holder, &shape);
@ -1448,7 +1448,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext *cx, HandleScript outerScri
MOZ_ASSERT(output().hasValue());
RootedObject checkObj(cx, obj->getTaggedProto().toObjectOrNull());
RootedObject holder(cx);
RootedNativeObject holder(cx);
RootedShape shape(cx);
NativeGetPropCacheability canCache =
@ -1844,7 +1844,7 @@ GetPropertyParIC::reset()
bool
GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
HandleObject holder, HandleShape shape)
HandleNativeObject holder, HandleShape shape)
{
// Ready to generate the read slot stub.
DispatchStubPrepender attacher(*this);
@ -1910,7 +1910,7 @@ GetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex,
{
RootedShape shape(ncx);
RootedObject holder(ncx);
RootedNativeObject holder(ncx);
RootedPropertyName name(ncx, cache.name());
GetPropertyIC::NativeGetPropCacheability canCache =
@ -1963,7 +1963,7 @@ IonCache::destroy()
static void
GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
JSObject *obj, Shape *shape, Register object, ConstantOrRegister value,
NativeObject *obj, Shape *shape, Register object, ConstantOrRegister value,
bool needsTypeBarrier, bool checkTypeset)
{
MOZ_ASSERT(obj->isNative());
@ -2003,7 +2003,7 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
}
if (obj->isFixedSlot(shape->slot())) {
Address addr(object, JSObject::getFixedSlotOffset(shape->slot()));
Address addr(object, NativeObject::getFixedSlotOffset(shape->slot()));
if (cx->zone()->needsIncrementalBarrier())
masm.callPreBarrier(addr, MIRType_Value);
@ -2011,7 +2011,7 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
masm.storeConstantOrRegister(value, addr);
} else {
Register slotsReg = object;
masm.loadPtr(Address(object, JSObject::offsetOfSlots()), slotsReg);
masm.loadPtr(Address(object, NativeObject::offsetOfSlots()), slotsReg);
Address addr(slotsReg, obj->dynamicSlotIndex(shape->slot()) * sizeof(Value));
@ -2034,7 +2034,7 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
bool
SetPropertyIC::attachSetSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape shape, bool checkTypeset)
HandleNativeObject obj, HandleShape shape, bool checkTypeset)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
@ -2523,7 +2523,7 @@ SetPropertyIC::attachCallSetter(JSContext *cx, HandleScript outerScript, IonScri
static void
GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
JSObject *obj, Shape *oldShape, types::TypeObject *oldType,
NativeObject *obj, Shape *oldShape, types::TypeObject *oldType,
Register object, ConstantOrRegister value,
bool checkTypeset)
{
@ -2609,12 +2609,12 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
// Set the value on the object. Since this is an add, obj->lastProperty()
// must be the shape of the property we are adding.
if (obj->isFixedSlot(newShape->slot())) {
Address addr(object, JSObject::getFixedSlotOffset(newShape->slot()));
Address addr(object, NativeObject::getFixedSlotOffset(newShape->slot()));
masm.storeConstantOrRegister(value, addr);
} else {
Register slotsReg = object;
masm.loadPtr(Address(object, JSObject::offsetOfSlots()), slotsReg);
masm.loadPtr(Address(object, NativeObject::offsetOfSlots()), slotsReg);
Address addr(slotsReg, obj->dynamicSlotIndex(newShape->slot()) * sizeof(Value));
masm.storeConstantOrRegister(value, addr);
@ -2633,7 +2633,7 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att
bool
SetPropertyIC::attachAddSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape oldShape, HandleTypeObject oldType,
HandleNativeObject obj, HandleShape oldShape, HandleTypeObject oldType,
bool checkTypeset)
{
MOZ_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
@ -2683,14 +2683,12 @@ CanInlineSetPropTypeCheck(JSObject *obj, jsid id, ConstantOrRegister val, bool *
}
static bool
IsPropertySetInlineable(HandleObject obj, HandleId id, MutableHandleShape pshape,
IsPropertySetInlineable(NativeObject *obj, HandleId id, MutableHandleShape pshape,
ConstantOrRegister val, bool needsTypeBarrier, bool *checkTypeset)
{
MOZ_ASSERT(obj->isNative());
// Do a pure non-proto chain climbing lookup. See note in
// CanAttachNativeGetProp.
pshape.set(obj->nativeLookupPure(id));
pshape.set(obj->lookupPure(id));
if (!pshape)
return false;
@ -2711,16 +2709,14 @@ IsPropertySetInlineable(HandleObject obj, HandleId id, MutableHandleShape pshape
}
static bool
IsPropertyAddInlineable(HandleObject obj, HandleId id, ConstantOrRegister val, uint32_t oldSlots,
IsPropertyAddInlineable(NativeObject *obj, HandleId id, ConstantOrRegister val, uint32_t oldSlots,
HandleShape oldShape, bool needsTypeBarrier, bool *checkTypeset)
{
MOZ_ASSERT(obj->isNative());
// If the shape of the object did not change, then this was not an add.
if (obj->lastProperty() == oldShape)
return false;
Shape *shape = obj->nativeLookupPure(id);
Shape *shape = obj->lookupPure(id);
if (!shape || shape->inDictionary() || !shape->hasSlot() || !shape->hasDefaultSetter())
return false;
@ -2749,7 +2745,7 @@ IsPropertyAddInlineable(HandleObject obj, HandleId id, ConstantOrRegister val, u
return false;
// If prototype defines this property in a non-plain way, don't optimize
Shape *protoShape = proto->nativeLookupPure(id);
Shape *protoShape = proto->as<NativeObject>().lookupPure(id);
if (protoShape && !protoShape->hasDefaultSetter())
return false;
@ -2781,14 +2777,14 @@ IsPropertyAddInlineable(HandleObject obj, HandleId id, ConstantOrRegister val, u
static SetPropertyIC::NativeSetPropCacheability
CanAttachNativeSetProp(HandleObject obj, HandleId id, ConstantOrRegister val,
bool needsTypeBarrier, MutableHandleObject holder,
bool needsTypeBarrier, MutableHandleNativeObject holder,
MutableHandleShape shape, bool *checkTypeset)
{
if (!obj->isNative())
return SetPropertyIC::CanAttachNone;
// See if the property exists on the object.
if (IsPropertySetInlineable(obj, id, shape, val, needsTypeBarrier, checkTypeset))
if (IsPropertySetInlineable(&obj->as<NativeObject>(), id, shape, val, needsTypeBarrier, checkTypeset))
return SetPropertyIC::CanAttachSetSlot;
// If we couldn't find the property on the object itself, do a full, but
@ -2859,13 +2855,14 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
}
RootedShape shape(cx);
RootedObject holder(cx);
RootedNativeObject holder(cx);
bool checkTypeset;
canCache = CanAttachNativeSetProp(obj, id, cache.value(), cache.needsTypeBarrier(),
&holder, &shape, &checkTypeset);
if (!addedSetterStub && canCache == CanAttachSetSlot) {
if (!cache.attachSetSlot(cx, script, ion, obj, shape, checkTypeset))
RootedNativeObject nobj(cx, &obj->as<NativeObject>());
if (!cache.attachSetSlot(cx, script, ion, nobj, shape, checkTypeset))
return false;
addedSetterStub = true;
}
@ -2877,7 +2874,7 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
}
}
uint32_t oldSlots = obj->numDynamicSlots();
uint32_t oldSlots = obj->fakeNativeNumDynamicSlots();
RootedShape oldShape(cx, obj->lastProperty());
// Set/Add the property on the object, the inlined cache are setup for the next execution.
@ -2887,10 +2884,12 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
// The property did not exist before, now we can try to inline the property add.
bool checkTypeset;
if (!addedSetterStub && canCache == MaybeCanAttachAddSlot &&
IsPropertyAddInlineable(obj, id, cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
IsPropertyAddInlineable(&obj->as<NativeObject>(), id,
cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
&checkTypeset))
{
if (!cache.attachAddSlot(cx, script, ion, obj, oldShape, oldType, checkTypeset))
RootedNativeObject nobj(cx, &obj->as<NativeObject>());
if (!cache.attachAddSlot(cx, script, ion, nobj, oldShape, oldType, checkTypeset))
return false;
}
@ -2916,10 +2915,14 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
RootedValue v(cx, value);
RootedId id(cx, AtomToId(cache.name()));
if (!obj->isNative())
return false;
RootedNativeObject nobj(cx, &obj->as<NativeObject>());
// Avoid unnecessary locking if cannot attach stubs.
if (!cache.canAttachStub()) {
return baseops::SetPropertyHelper<ParallelExecution>(
cx, obj, obj, id, baseops::Qualified, &v, cache.strict());
cx, nobj, nobj, id, baseops::Qualified, &v, cache.strict());
}
SetPropertyIC::NativeSetPropCacheability canCache = SetPropertyIC::CanAttachNone;
@ -2931,27 +2934,27 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
if (cache.canAttachStub()) {
bool alreadyStubbed;
if (!cache.hasOrAddStubbedShape(ncx, obj->lastProperty(), &alreadyStubbed))
if (!cache.hasOrAddStubbedShape(ncx, nobj->lastProperty(), &alreadyStubbed))
return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory);
if (alreadyStubbed) {
return baseops::SetPropertyHelper<ParallelExecution>(
cx, obj, obj, id, baseops::Qualified, &v, cache.strict());
cx, nobj, nobj, id, baseops::Qualified, &v, cache.strict());
}
// If the object has a lazy type, we need to de-lazify it, but
// this is not safe in parallel.
if (obj->hasLazyType())
if (nobj->hasLazyType())
return false;
{
RootedShape shape(cx);
RootedObject holder(cx);
RootedNativeObject holder(cx);
bool checkTypeset;
canCache = CanAttachNativeSetProp(obj, id, cache.value(), cache.needsTypeBarrier(),
canCache = CanAttachNativeSetProp(nobj, id, cache.value(), cache.needsTypeBarrier(),
&holder, &shape, &checkTypeset);
if (canCache == SetPropertyIC::CanAttachSetSlot) {
if (!cache.attachSetSlot(ncx, ion, obj, shape, checkTypeset))
if (!cache.attachSetSlot(ncx, ion, nobj, shape, checkTypeset))
return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory);
attachedStub = true;
}
@ -2959,11 +2962,11 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
}
}
uint32_t oldSlots = obj->numDynamicSlots();
RootedShape oldShape(cx, obj->lastProperty());
RootedTypeObject oldType(cx, obj->type());
uint32_t oldSlots = nobj->numDynamicSlots();
RootedShape oldShape(cx, nobj->lastProperty());
RootedTypeObject oldType(cx, nobj->type());
if (!baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
if (!baseops::SetPropertyHelper<ParallelExecution>(cx, nobj, nobj, id, baseops::Qualified, &v,
cache.strict()))
{
return false;
@ -2971,11 +2974,12 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
bool checkTypeset;
if (!attachedStub && canCache == SetPropertyIC::MaybeCanAttachAddSlot &&
IsPropertyAddInlineable(obj, id, cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
IsPropertyAddInlineable(nobj, id,
cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
&checkTypeset))
{
LockedJSContext ncx(cx);
if (cache.canAttachStub() && !cache.attachAddSlot(ncx, ion, obj, oldShape, oldType, checkTypeset))
if (cache.canAttachStub() && !cache.attachAddSlot(ncx, ion, nobj, oldShape, oldType, checkTypeset))
return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory);
}
@ -2983,7 +2987,7 @@ SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject ob
}
bool
SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj,
HandleShape shape, bool checkTypeset)
{
MacroAssembler masm(cx, ion);
@ -2994,7 +2998,7 @@ SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleObjec
}
bool
SetPropertyParIC::attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
SetPropertyParIC::attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj,
HandleShape oldShape, HandleTypeObject oldType, bool checkTypeset)
{
MOZ_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
@ -3038,7 +3042,7 @@ GetElementIC::attachGetProp(JSContext *cx, HandleScript outerScript, IonScript *
{
MOZ_ASSERT(index().reg().hasValue());
RootedObject holder(cx);
RootedNativeObject holder(cx);
RootedShape shape(cx);
GetPropertyIC::NativeGetPropCacheability canCache =
@ -3165,7 +3169,7 @@ GenerateDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher
// Load elements vector.
masm.push(object);
masm.loadPtr(Address(object, JSObject::offsetOfElements()), object);
masm.loadPtr(Address(object, NativeObject::offsetOfElements()), object);
Label hole;
@ -3673,7 +3677,7 @@ GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttac
{
// Load obj->elements.
Register elements = temp;
masm.loadPtr(Address(object, JSObject::offsetOfElements()), elements);
masm.loadPtr(Address(object, NativeObject::offsetOfElements()), elements);
// Compute the location of the element.
BaseIndex target(elements, index, TimesEight);
@ -3964,7 +3968,7 @@ SetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
bool
GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval, HandlePropertyName name, HandleObject holder,
const Value &idval, HandlePropertyName name, HandleNativeObject holder,
HandleShape shape)
{
MacroAssembler masm(cx, ion);
@ -4040,7 +4044,7 @@ GetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj
GetElementIC::canAttachGetProp(obj, idval, id))
{
RootedShape shape(ncx);
RootedObject holder(ncx);
RootedNativeObject holder(ncx);
RootedPropertyName name(ncx, JSID_TO_ATOM(id)->asPropertyName());
GetPropertyIC::NativeGetPropCacheability canCache =
@ -4245,7 +4249,7 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
bool
NameIC::attachReadSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holderBase,
HandleObject holder, HandleShape shape)
HandleNativeObject holder, HandleShape shape)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
Label failures;
@ -4381,8 +4385,11 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
if (cache.canAttachStub()) {
if (IsCacheableNameReadSlot(scopeChain, obj, holder, shape, pc, cache.outputReg())) {
if (!cache.attachReadSlot(cx, outerScript, ion, scopeChain, obj, holder, shape))
if (!cache.attachReadSlot(cx, outerScript, ion, scopeChain, obj,
holder.as<NativeObject>(), shape))
{
return false;
}
} else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
if (!cache.attachCallGetter(cx, outerScript, ion, scopeChain, obj, holder, shape, returnAddr))
return false;

Просмотреть файл

@ -738,14 +738,14 @@ class SetPropertyIC : public RepatchIonCache
};
bool attachSetSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape shape, bool checkTypeset);
HandleNativeObject obj, HandleShape shape, bool checkTypeset);
bool attachCallSetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleObject holder, HandleShape shape,
void *returnAddr);
bool attachAddSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject obj, HandleShape oldShape, HandleTypeObject oldType,
HandleNativeObject obj, HandleShape oldShape, HandleTypeObject oldType,
bool checkTypeset);
bool attachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion,
@ -1029,7 +1029,7 @@ class NameIC : public RepatchIonCache
bool attachReadSlot(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject holderBase,
HandleObject holder, HandleShape shape);
HandleNativeObject holder, HandleShape shape);
bool attachCallGetter(JSContext *cx, HandleScript outerScript, IonScript *ion,
HandleObject scopeChain, HandleObject obj, HandleObject holder,
@ -1156,7 +1156,8 @@ class GetPropertyParIC : public ParallelIonCache
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return true; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, HandleObject holder,
bool attachReadSlot(LockedJSContext &cx, IonScript *ion,
HandleObject obj, HandleNativeObject holder,
HandleShape shape);
bool attachArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj);
bool attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj);
@ -1217,7 +1218,7 @@ class GetElementParIC : public ParallelIonCache
bool allowArrayLength(Context, HandleObject) const { return false; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, const Value &idval,
HandlePropertyName name, HandleObject holder, HandleShape shape);
HandlePropertyName name, HandleNativeObject holder, HandleShape shape);
bool attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj,
const Value &idval);
bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, HandleObject tarr,
@ -1272,9 +1273,9 @@ class SetPropertyParIC : public ParallelIonCache
return needsTypeBarrier_;
}
bool attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, HandleShape shape,
bool attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj, HandleShape shape,
bool checkTypeset);
bool attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj,
bool attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj,
HandleShape oldShape, HandleTypeObject oldType, bool checkTypeset);
static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj,

Просмотреть файл

@ -587,7 +587,7 @@ MacroAssembler::allocateObject(Register result, Register slots, gc::AllocKind al
}
void
MacroAssembler::newGCThing(Register result, Register temp, JSObject *templateObj,
MacroAssembler::newGCThing(Register result, Register temp, NativeObject *templateObj,
gc::InitialHeap initialHeap, Label *fail)
{
// This method does not initialize the object: if external slots get
@ -602,7 +602,7 @@ MacroAssembler::newGCThing(Register result, Register temp, JSObject *templateObj
}
void
MacroAssembler::createGCObject(Register obj, Register temp, JSObject *templateObj,
MacroAssembler::createGCObject(Register obj, Register temp, NativeObject *templateObj,
gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots)
{
uint32_t nDynamicSlots = templateObj->numDynamicSlots();
@ -734,7 +734,7 @@ MacroAssembler::newGCTenuredThingPar(Register result, Register cx,
void
MacroAssembler::newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
JSObject *templateObject, Label *fail)
NativeObject *templateObject, Label *fail)
{
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
MOZ_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST);
@ -758,12 +758,12 @@ MacroAssembler::newGCFatInlineStringPar(Register result, Register cx, Register t
}
void
MacroAssembler::copySlotsFromTemplate(Register obj, const JSObject *templateObj,
MacroAssembler::copySlotsFromTemplate(Register obj, const NativeObject *templateObj,
uint32_t start, uint32_t end)
{
uint32_t nfixed = Min(templateObj->numFixedSlots(), end);
for (unsigned i = start; i < nfixed; i++)
storeValue(templateObj->getFixedSlot(i), Address(obj, JSObject::getFixedSlotOffset(i)));
storeValue(templateObj->getFixedSlot(i), Address(obj, NativeObject::getFixedSlotOffset(i)));
}
void
@ -791,7 +791,7 @@ MacroAssembler::fillSlotsWithUndefined(Address base, Register temp, uint32_t sta
}
static uint32_t
FindStartOfUndefinedSlots(JSObject *templateObj, uint32_t nslots)
FindStartOfUndefinedSlots(NativeObject *templateObj, uint32_t nslots)
{
MOZ_ASSERT(nslots == templateObj->lastProperty()->slotSpan(templateObj->getClass()));
MOZ_ASSERT(nslots > 0);
@ -803,7 +803,7 @@ FindStartOfUndefinedSlots(JSObject *templateObj, uint32_t nslots)
}
void
MacroAssembler::initGCSlots(Register obj, Register slots, JSObject *templateObj,
MacroAssembler::initGCSlots(Register obj, Register slots, NativeObject *templateObj,
bool initFixedSlots)
{
// Slots of non-array objects are required to be initialized.
@ -830,7 +830,7 @@ MacroAssembler::initGCSlots(Register obj, Register slots, JSObject *templateObj,
// Fill the rest of the fixed slots with undefined.
if (initFixedSlots) {
fillSlotsWithUndefined(Address(obj, JSObject::getFixedSlotOffset(startOfUndefined)), slots,
fillSlotsWithUndefined(Address(obj, NativeObject::getFixedSlotOffset(startOfUndefined)), slots,
startOfUndefined, nfixed);
}
@ -838,14 +838,14 @@ MacroAssembler::initGCSlots(Register obj, Register slots, JSObject *templateObj,
// We are short one register to do this elegantly. Borrow the obj
// register briefly for our slots base address.
push(obj);
loadPtr(Address(obj, JSObject::offsetOfSlots()), obj);
loadPtr(Address(obj, NativeObject::offsetOfSlots()), obj);
fillSlotsWithUndefined(Address(obj, 0), slots, 0, ndynamic);
pop(obj);
}
}
void
MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj,
MacroAssembler::initGCThing(Register obj, Register slots, NativeObject *templateObj,
bool initFixedSlots)
{
// Fast initialization of an empty object returned by allocateObject().
@ -855,21 +855,21 @@ MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj,
storePtr(ImmGCPtr(templateObj->lastProperty()), Address(obj, JSObject::offsetOfShape()));
storePtr(ImmGCPtr(templateObj->type()), Address(obj, JSObject::offsetOfType()));
if (templateObj->hasDynamicSlots())
storePtr(slots, Address(obj, JSObject::offsetOfSlots()));
storePtr(slots, Address(obj, NativeObject::offsetOfSlots()));
else
storePtr(ImmPtr(nullptr), Address(obj, JSObject::offsetOfSlots()));
storePtr(ImmPtr(nullptr), Address(obj, NativeObject::offsetOfSlots()));
if (templateObj->denseElementsAreCopyOnWrite()) {
storePtr(ImmPtr((const Value *) templateObj->getDenseElements()),
Address(obj, JSObject::offsetOfElements()));
Address(obj, NativeObject::offsetOfElements()));
} else if (templateObj->is<ArrayObject>()) {
Register temp = slots;
MOZ_ASSERT(!templateObj->getDenseInitializedLength());
int elementsOffset = JSObject::offsetOfFixedElements();
int elementsOffset = NativeObject::offsetOfFixedElements();
computeEffectiveAddress(Address(obj, elementsOffset), temp);
storePtr(temp, Address(obj, JSObject::offsetOfElements()));
storePtr(temp, Address(obj, NativeObject::offsetOfElements()));
// Fill in the elements header.
store32(Imm32(templateObj->getDenseCapacity()),
@ -884,14 +884,14 @@ MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj,
Address(obj, elementsOffset + ObjectElements::offsetOfFlags()));
MOZ_ASSERT(!templateObj->hasPrivate());
} else {
storePtr(ImmPtr(emptyObjectElements), Address(obj, JSObject::offsetOfElements()));
storePtr(ImmPtr(emptyObjectElements), Address(obj, NativeObject::offsetOfElements()));
initGCSlots(obj, slots, templateObj, initFixedSlots);
if (templateObj->hasPrivate()) {
uint32_t nfixed = templateObj->numFixedSlots();
storePtr(ImmPtr(templateObj->getPrivate()),
Address(obj, JSObject::getPrivateDataOffset(nfixed)));
Address(obj, NativeObject::getPrivateDataOffset(nfixed)));
}
}

Просмотреть файл

@ -364,7 +364,7 @@ class MacroAssembler : public MacroAssemblerSpecific
}
void loadObjPrivate(Register obj, uint32_t nfixed, Register dest) {
loadPtr(Address(obj, JSObject::getPrivateDataOffset(nfixed)), dest);
loadPtr(Address(obj, NativeObject::getPrivateDataOffset(nfixed)), dest);
}
void loadObjProto(Register obj, Register dest) {
@ -811,20 +811,20 @@ class MacroAssembler : public MacroAssemblerSpecific
void allocateObject(Register result, Register slots, gc::AllocKind allocKind,
uint32_t nDynamicSlots, gc::InitialHeap initialHeap, Label *fail);
void allocateNonObject(Register result, Register temp, gc::AllocKind allocKind, Label *fail);
void copySlotsFromTemplate(Register obj, const JSObject *templateObj,
void copySlotsFromTemplate(Register obj, const NativeObject *templateObj,
uint32_t start, uint32_t end);
void fillSlotsWithUndefined(Address addr, Register temp, uint32_t start, uint32_t end);
void initGCSlots(Register obj, Register temp, JSObject *templateObj, bool initFixedSlots);
void initGCSlots(Register obj, Register temp, NativeObject *templateObj, bool initFixedSlots);
public:
void callMallocStub(size_t nbytes, Register result, Label *fail);
void callFreeStub(Register slots);
void createGCObject(Register result, Register temp, JSObject *templateObj,
void createGCObject(Register result, Register temp, NativeObject *templateObj,
gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots = true);
void newGCThing(Register result, Register temp, JSObject *templateObj,
void newGCThing(Register result, Register temp, NativeObject *templateObj,
gc::InitialHeap initialHeap, Label *fail);
void initGCThing(Register obj, Register temp, JSObject *templateObj,
void initGCThing(Register obj, Register temp, NativeObject *templateObj,
bool initFixedSlots = true);
void newGCString(Register result, Register temp, Label *fail);
@ -839,7 +839,7 @@ class MacroAssembler : public MacroAssemblerSpecific
void newGCTenuredThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
gc::AllocKind allocKind, Label *fail);
void newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
JSObject *templateObject, Label *fail);
NativeObject *templateObject, Label *fail);
void newGCStringPar(Register result, Register cx, Register tempReg1, Register tempReg2,
Label *fail);
void newGCFatInlineStringPar(Register result, Register cx, Register tempReg1, Register tempReg2,

Просмотреть файл

@ -17,6 +17,7 @@
#include "jsscriptinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/StringObject-inl.h"
using mozilla::ArrayLength;
@ -301,7 +302,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
uint32_t initLength = 0;
AllocatingBehaviour allocating = NewArray_Unallocating;
JSObject *templateObject = inspector->getTemplateObjectForNative(pc, js_Array);
NativeObject *templateObject = inspector->getTemplateObjectForNative(pc, js_Array);
if (!templateObject)
return InliningStatus_NotInlined;
MOZ_ASSERT(templateObject->is<ArrayObject>());
@ -335,7 +336,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
// Negative lengths generate a RangeError, unhandled by the inline path.
initLength = arg->toConstant()->value().toInt32();
if (initLength >= JSObject::NELEMENTS_LIMIT)
if (initLength >= NativeObject::NELEMENTS_LIMIT)
return InliningStatus_NotInlined;
// Make sure initLength matches the template object's length. This is
@ -672,7 +673,7 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
}
// Inline the call.
JSObject *templateObj = inspector->getTemplateObjectForNative(pc, js::array_concat);
NativeObject *templateObj = inspector->getTemplateObjectForNative(pc, js::array_concat);
if (!templateObj || templateObj->type() != baseThisType)
return InliningStatus_NotInlined;
MOZ_ASSERT(templateObj->is<ArrayObject>());
@ -680,7 +681,8 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
callInfo.setImplicitlyUsedUnchecked();
MArrayConcat *ins = MArrayConcat::New(alloc(), constraints(), callInfo.thisArg(), callInfo.getArg(0),
templateObj, templateObj->type()->initialHeap(constraints()));
&templateObj->as<ArrayObject>(),
templateObj->type()->initialHeap(constraints()));
current->add(ins);
current->push(ins);
@ -1748,7 +1750,7 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo)
return InliningStatus_NotInlined;
types::TypeObject *typeObject = returnTypes->getTypeObject(0);
JSObject *templateObject = inspector->getTemplateObjectForNative(pc, intrinsic_NewDenseArray);
NativeObject *templateObject = inspector->getTemplateObjectForNative(pc, intrinsic_NewDenseArray);
if (!templateObject || templateObject->type() != typeObject)
return InliningStatus_NotInlined;
@ -1757,7 +1759,7 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo)
MNewDenseArrayPar *newObject = MNewDenseArrayPar::New(alloc(),
graph().forkJoinContext(),
callInfo.getArg(0),
templateObject);
&templateObject->as<ArrayObject>());
current->add(newObject);
current->push(newObject);

Просмотреть файл

@ -3180,7 +3180,7 @@ MBeta::printOpcode(FILE *fp) const
bool
MNewObject::shouldUseVM() const
{
JSObject *obj = templateObject();
NativeObject *obj = templateObject();
return obj->hasSingletonType() || obj->hasDynamicSlots();
}
@ -3197,7 +3197,7 @@ MObjectState::MObjectState(MDefinition *obj)
// This instruction is only used as a summary for bailout paths.
setResultType(MIRType_Object);
setRecoveredOnBailout();
JSObject *templateObject = nullptr;
NativeObject *templateObject = nullptr;
if (obj->isNewObject())
templateObject = obj->toNewObject()->templateObject();
else
@ -3241,7 +3241,7 @@ MObjectState::Copy(TempAllocator &alloc, MObjectState *state)
bool
MNewArray::shouldUseVM() const
{
MOZ_ASSERT(count() < JSObject::NELEMENTS_LIMIT);
MOZ_ASSERT(count() < NativeObject::NELEMENTS_LIMIT);
size_t arraySlots =
gc::GetGCKindSlots(templateObject()->asTenured().getAllocKind()) - ObjectElements::VALUES_PER_HEADER;

Просмотреть файл

@ -22,6 +22,7 @@
#include "jit/MOpcodes.h"
#include "jit/TypedObjectPrediction.h"
#include "jit/TypePolicy.h"
#include "vm/ArrayObject.h"
#include "vm/ScopeObject.h"
#include "vm/TypedArrayCommon.h"
@ -2269,6 +2270,7 @@ class AlwaysTenured
};
typedef AlwaysTenured<JSObject*> AlwaysTenuredObject;
typedef AlwaysTenured<NativeObject*> AlwaysTenuredNativeObject;
typedef AlwaysTenured<JSFunction*> AlwaysTenuredFunction;
typedef AlwaysTenured<JSScript*> AlwaysTenuredScript;
typedef AlwaysTenured<PropertyName*> AlwaysTenuredPropertyName;
@ -2292,7 +2294,7 @@ class MNewArray : public MUnaryInstruction
initialHeap_(initialHeap),
allocating_(allocating)
{
JSObject *obj = templateObject();
ArrayObject *obj = templateObject();
setResultType(MIRType_Object);
if (!obj->hasSingletonType())
setResultTypeSet(MakeSingletonTypeSet(constraints, obj));
@ -2312,8 +2314,8 @@ class MNewArray : public MUnaryInstruction
return count_;
}
JSObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject();
ArrayObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<ArrayObject>();
}
gc::InitialHeap initialHeap() const {
@ -2348,10 +2350,10 @@ class MNewArray : public MUnaryInstruction
class MNewArrayCopyOnWrite : public MNullaryInstruction
{
AlwaysTenuredObject templateObject_;
AlwaysTenured<ArrayObject*> templateObject_;
gc::InitialHeap initialHeap_;
MNewArrayCopyOnWrite(types::CompilerConstraintList *constraints, JSObject *templateObject,
MNewArrayCopyOnWrite(types::CompilerConstraintList *constraints, ArrayObject *templateObject,
gc::InitialHeap initialHeap)
: templateObject_(templateObject),
initialHeap_(initialHeap)
@ -2366,13 +2368,13 @@ class MNewArrayCopyOnWrite : public MNullaryInstruction
static MNewArrayCopyOnWrite *New(TempAllocator &alloc,
types::CompilerConstraintList *constraints,
JSObject *templateObject,
ArrayObject *templateObject,
gc::InitialHeap initialHeap)
{
return new(alloc) MNewArrayCopyOnWrite(constraints, templateObject, initialHeap);
}
JSObject *templateObject() const {
ArrayObject *templateObject() const {
return templateObject_;
}
@ -2429,8 +2431,8 @@ class MNewObject : public MUnaryInstruction
return templateObjectIsClassPrototype_;
}
JSObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject();
NativeObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<NativeObject>();
}
gc::InitialHeap initialHeap() const {
@ -2448,9 +2450,9 @@ class MNewObject : public MUnaryInstruction
// Could be allocating either a new array or a new object.
class MNewPar : public MUnaryInstruction
{
AlwaysTenuredObject templateObject_;
AlwaysTenuredNativeObject templateObject_;
MNewPar(MDefinition *cx, JSObject *templateObject)
MNewPar(MDefinition *cx, NativeObject *templateObject)
: MUnaryInstruction(cx),
templateObject_(templateObject)
{
@ -2460,7 +2462,7 @@ class MNewPar : public MUnaryInstruction
public:
INSTRUCTION_HEADER(NewPar);
static MNewPar *New(TempAllocator &alloc, MDefinition *cx, JSObject *templateObject) {
static MNewPar *New(TempAllocator &alloc, MDefinition *cx, NativeObject *templateObject) {
return new(alloc) MNewPar(cx, templateObject);
}
@ -2468,7 +2470,7 @@ class MNewPar : public MUnaryInstruction
return getOperand(0);
}
JSObject *templateObject() const {
NativeObject *templateObject() const {
return templateObject_;
}
@ -3717,8 +3719,8 @@ class MCreateThisWithTemplate
}
// Template for |this|, provided by TI.
JSObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject();
NativeObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<NativeObject>();
}
gc::InitialHeap initialHeap() const {
@ -7669,11 +7671,11 @@ class MArrayConcat
: public MBinaryInstruction,
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> >::Data
{
AlwaysTenuredObject templateObj_;
AlwaysTenured<ArrayObject*> templateObj_;
gc::InitialHeap initialHeap_;
MArrayConcat(types::CompilerConstraintList *constraints, MDefinition *lhs, MDefinition *rhs,
JSObject *templateObj, gc::InitialHeap initialHeap)
ArrayObject *templateObj, gc::InitialHeap initialHeap)
: MBinaryInstruction(lhs, rhs),
templateObj_(templateObj),
initialHeap_(initialHeap)
@ -7687,12 +7689,12 @@ class MArrayConcat
static MArrayConcat *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
MDefinition *lhs, MDefinition *rhs,
JSObject *templateObj, gc::InitialHeap initialHeap)
ArrayObject *templateObj, gc::InitialHeap initialHeap)
{
return new(alloc) MArrayConcat(constraints, lhs, rhs, templateObj, initialHeap);
}
JSObject *templateObj() const {
ArrayObject *templateObj() const {
return templateObj_;
}
@ -10308,10 +10310,10 @@ class MSetFrameArgument
class MRestCommon
{
unsigned numFormals_;
AlwaysTenuredObject templateObject_;
AlwaysTenured<ArrayObject*> templateObject_;
protected:
MRestCommon(unsigned numFormals, JSObject *templateObject)
MRestCommon(unsigned numFormals, ArrayObject *templateObject)
: numFormals_(numFormals),
templateObject_(templateObject)
{ }
@ -10320,7 +10322,7 @@ class MRestCommon
unsigned numFormals() const {
return numFormals_;
}
JSObject *templateObject() const {
ArrayObject *templateObject() const {
return templateObject_;
}
};
@ -10331,7 +10333,7 @@ class MRest
public IntPolicy<0>::Data
{
MRest(types::CompilerConstraintList *constraints, MDefinition *numActuals, unsigned numFormals,
JSObject *templateObject)
ArrayObject *templateObject)
: MUnaryInstruction(numActuals),
MRestCommon(numFormals, templateObject)
{
@ -10344,7 +10346,7 @@ class MRest
static MRest *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
MDefinition *numActuals, unsigned numFormals,
JSObject *templateObject)
ArrayObject *templateObject)
{
return new(alloc) MRest(constraints, numActuals, numFormals, templateObject);
}
@ -10367,7 +10369,7 @@ class MRestPar
public IntPolicy<1>::Data
{
MRestPar(MDefinition *cx, MDefinition *numActuals, unsigned numFormals,
JSObject *templateObject, types::TemporaryTypeSet *resultTypes)
ArrayObject *templateObject, types::TemporaryTypeSet *resultTypes)
: MBinaryInstruction(cx, numActuals),
MRestCommon(numFormals, templateObject)
{
@ -10607,9 +10609,9 @@ class MPostWriteBarrier : public MBinaryInstruction, public ObjectPolicy<0>::Dat
class MNewDeclEnvObject : public MNullaryInstruction
{
AlwaysTenuredObject templateObj_;
AlwaysTenuredNativeObject templateObj_;
explicit MNewDeclEnvObject(JSObject *templateObj)
explicit MNewDeclEnvObject(NativeObject *templateObj)
: MNullaryInstruction(),
templateObj_(templateObj)
{
@ -10619,11 +10621,11 @@ class MNewDeclEnvObject : public MNullaryInstruction
public:
INSTRUCTION_HEADER(NewDeclEnvObject);
static MNewDeclEnvObject *New(TempAllocator &alloc, JSObject *templateObj) {
static MNewDeclEnvObject *New(TempAllocator &alloc, NativeObject *templateObj) {
return new(alloc) MNewDeclEnvObject(templateObj);
}
JSObject *templateObj() {
NativeObject *templateObj() {
return templateObj_;
}
AliasSet getAliasSet() const {
@ -10633,10 +10635,10 @@ class MNewDeclEnvObject : public MNullaryInstruction
class MNewCallObjectBase : public MNullaryInstruction
{
AlwaysTenuredObject templateObj_;
AlwaysTenuredNativeObject templateObj_;
protected:
explicit MNewCallObjectBase(JSObject *templateObj)
explicit MNewCallObjectBase(NativeObject *templateObj)
: MNullaryInstruction(),
templateObj_(templateObj)
{
@ -10644,7 +10646,7 @@ class MNewCallObjectBase : public MNullaryInstruction
}
public:
JSObject *templateObject() {
NativeObject *templateObject() {
return templateObj_;
}
AliasSet getAliasSet() const {
@ -10657,12 +10659,12 @@ class MNewCallObject : public MNewCallObjectBase
public:
INSTRUCTION_HEADER(NewCallObject)
explicit MNewCallObject(JSObject *templateObj)
explicit MNewCallObject(NativeObject *templateObj)
: MNewCallObjectBase(templateObj)
{}
static MNewCallObject *
New(TempAllocator &alloc, JSObject *templateObj)
New(TempAllocator &alloc, NativeObject *templateObj)
{
return new(alloc) MNewCallObject(templateObj);
}
@ -10673,12 +10675,12 @@ class MNewRunOnceCallObject : public MNewCallObjectBase
public:
INSTRUCTION_HEADER(NewRunOnceCallObject)
explicit MNewRunOnceCallObject(JSObject *templateObj)
explicit MNewRunOnceCallObject(NativeObject *templateObj)
: MNewCallObjectBase(templateObj)
{}
static MNewRunOnceCallObject *
New(TempAllocator &alloc, JSObject *templateObj)
New(TempAllocator &alloc, NativeObject *templateObj)
{
return new(alloc) MNewRunOnceCallObject(templateObj);
}
@ -10686,9 +10688,9 @@ class MNewRunOnceCallObject : public MNewCallObjectBase
class MNewCallObjectPar : public MUnaryInstruction
{
AlwaysTenuredObject templateObj_;
AlwaysTenuredNativeObject templateObj_;
MNewCallObjectPar(MDefinition *cx, JSObject *templateObj)
MNewCallObjectPar(MDefinition *cx, NativeObject *templateObj)
: MUnaryInstruction(cx),
templateObj_(templateObj)
{
@ -10706,7 +10708,7 @@ class MNewCallObjectPar : public MUnaryInstruction
return getOperand(0);
}
JSObject *templateObj() const {
NativeObject *templateObj() const {
return templateObj_;
}
@ -10805,9 +10807,9 @@ class MEnclosingScope : public MLoadFixedSlot
// Note: the template object should be an *empty* dense array!
class MNewDenseArrayPar : public MBinaryInstruction
{
AlwaysTenuredObject templateObject_;
AlwaysTenured<ArrayObject*> templateObject_;
MNewDenseArrayPar(MDefinition *cx, MDefinition *length, JSObject *templateObject)
MNewDenseArrayPar(MDefinition *cx, MDefinition *length, ArrayObject *templateObject)
: MBinaryInstruction(cx, length),
templateObject_(templateObject)
{
@ -10819,7 +10821,7 @@ class MNewDenseArrayPar : public MBinaryInstruction
INSTRUCTION_HEADER(NewDenseArrayPar);
static MNewDenseArrayPar *New(TempAllocator &alloc, MDefinition *cx, MDefinition *length,
JSObject *templateObject)
ArrayObject *templateObject)
{
return new(alloc) MNewDenseArrayPar(cx, length, templateObject);
}
@ -10832,7 +10834,7 @@ class MNewDenseArrayPar : public MBinaryInstruction
return getOperand(1);
}
JSObject *templateObject() const {
ArrayObject *templateObject() const {
return templateObject_;
}

Просмотреть файл

@ -15,6 +15,8 @@
#include "jsgcinlines.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace jit;
@ -165,12 +167,12 @@ jit::InterruptCheckPar(ForkJoinContext *cx)
return true;
}
JSObject *
jit::ExtendArrayPar(ForkJoinContext *cx, JSObject *array, uint32_t length)
ArrayObject *
jit::ExtendArrayPar(ForkJoinContext *cx, ArrayObject *array, uint32_t length)
{
JSObject::EnsureDenseResult res =
NativeObject::EnsureDenseResult res =
array->ensureDenseElementsPreservePackedFlag(cx, 0, length);
if (res != JSObject::ED_OK)
if (res != NativeObject::ED_OK)
return nullptr;
return array;
}
@ -183,9 +185,9 @@ jit::SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName na
if (*pc == JSOP_SETALIASEDVAR) {
// See comment in jit::SetProperty.
Shape *shape = obj->nativeLookupPure(name);
Shape *shape = obj->as<NativeObject>().lookupPure(name);
MOZ_ASSERT(shape && shape->hasSlot());
return obj->nativeSetSlotIfHasType(shape, value);
return obj->as<NativeObject>().setSlotIfHasType(shape, value);
}
// Fail early on hooks.
@ -194,7 +196,10 @@ jit::SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName na
RootedValue v(cx, value);
RootedId id(cx, NameToId(name));
return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
return baseops::SetPropertyHelper<ParallelExecution>(cx,
obj.as<NativeObject>(),
obj.as<NativeObject>(),
id, baseops::Qualified, &v,
strict);
}
@ -206,13 +211,19 @@ jit::SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index, Han
if (!ValueToIdPure(index, id.address()))
return false;
if (!obj->isNative())
return false;
// SetObjectElementOperation, the sequential version, has several checks
// for certain deoptimizing behaviors, such as marking having written to
// holes and non-indexed element accesses. We don't do that here, as we
// can't modify any TI state anyways. If we need to add a new type, we
// would bail out.
RootedValue v(cx, value);
return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
return baseops::SetPropertyHelper<ParallelExecution>(cx,
obj.as<NativeObject>(),
obj.as<NativeObject>(),
id, baseops::Qualified, &v,
strict);
}
@ -589,23 +600,22 @@ jit::CallToUncompiledScriptPar(ForkJoinContext *cx, JSObject *obj)
JSObject *
jit::InitRestParameterPar(ForkJoinContext *cx, uint32_t length, Value *rest,
HandleObject templateObj, HandleObject res)
HandleObject templateObj, HandleArrayObject res)
{
// In parallel execution, we should always have succeeded in allocation
// before this point. We can do the allocation here like in the sequential
// path, but duplicating the initGCThing logic is too tedious.
MOZ_ASSERT(res);
MOZ_ASSERT(res->is<ArrayObject>());
MOZ_ASSERT(!res->getDenseInitializedLength());
MOZ_ASSERT(res->type() == templateObj->type());
if (length > 0) {
JSObject::EnsureDenseResult edr =
NativeObject::EnsureDenseResult edr =
res->ensureDenseElementsPreservePackedFlag(cx, 0, length);
if (edr != JSObject::ED_OK)
if (edr != NativeObject::ED_OK)
return nullptr;
res->initDenseElementsUnbarriered(0, rest, length);
res->as<ArrayObject>().setLengthInt32(length);
res->setLengthInt32(length);
}
return res;

Просмотреть файл

@ -26,7 +26,7 @@ bool InterruptCheckPar(ForkJoinContext *cx);
// Extends the given array with `length` new holes. Returns nullptr on
// failure or else `array`, which is convenient during code
// generation.
JSObject *ExtendArrayPar(ForkJoinContext *cx, JSObject *array, uint32_t length);
ArrayObject *ExtendArrayPar(ForkJoinContext *cx, ArrayObject *array, uint32_t length);
// Set properties and elements on thread local objects.
bool SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName name,
@ -69,7 +69,7 @@ bool UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, Mutabl
// Make a new rest parameter in parallel.
JSObject *InitRestParameterPar(ForkJoinContext *cx, uint32_t length, Value *rest,
HandleObject templateObj, HandleObject res);
HandleObject templateObj, HandleArrayObject res);
// Abort and debug tracing functions.
void BailoutPar(BailoutStack *sp, uint8_t **entryFramePointer);

Просмотреть файл

@ -72,7 +72,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
bool insertWriteGuard(MInstruction *writeInstruction, MDefinition *valueBeingWritten);
bool replaceWithNewPar(MInstruction *newInstruction, JSObject *templateObject);
bool replaceWithNewPar(MInstruction *newInstruction, NativeObject *templateObject);
bool replace(MInstruction *oldInstruction, MInstruction *replacementInstruction);
bool visitSpecializedInstruction(MInstruction *ins, MIRType spec, uint32_t flags);
@ -584,7 +584,7 @@ ParallelSafetyVisitor::visitToString(MToString *ins)
bool
ParallelSafetyVisitor::replaceWithNewPar(MInstruction *newInstruction,
JSObject *templateObject)
NativeObject *templateObject)
{
return replace(newInstruction, MNewPar::New(alloc(), ForkJoinContext(), templateObject));
}

Просмотреть файл

@ -1507,7 +1507,7 @@ MArrayLength::computeRange(TempAllocator &alloc)
void
MInitializedLength::computeRange(TempAllocator &alloc)
{
setRange(Range::NewUInt32Range(alloc, 0, JSObject::NELEMENTS_LIMIT));
setRange(Range::NewUInt32Range(alloc, 0, NativeObject::NELEMENTS_LIMIT));
}
void

Просмотреть файл

@ -21,9 +21,10 @@
#include "jit/MIR.h"
#include "jit/MIRGraph.h"
#include "jit/VMFunctions.h"
#include "vm/Interpreter.h"
#include "vm/Interpreter-inl.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::jit;
@ -1003,7 +1004,7 @@ RNewObject::RNewObject(CompactBufferReader &reader)
bool
RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedObject templateObject(cx, &iter.read().toObject());
RootedNativeObject templateObject(cx, &iter.read().toObject().as<NativeObject>());
RootedValue result(cx);
JSObject *resultObject = nullptr;
@ -1113,7 +1114,7 @@ RCreateThisWithTemplate::RCreateThisWithTemplate(CompactBufferReader &reader)
bool
RCreateThisWithTemplate::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedObject templateObject(cx, &iter.read().toObject());
RootedNativeObject templateObject(cx, &iter.read().toObject().as<NativeObject>());
// Use AutoEnterAnalysis to avoid invoking the object metadata callback
// while bailing out, which could try to walk the stack.
@ -1122,7 +1123,7 @@ RCreateThisWithTemplate::recover(JSContext *cx, SnapshotIterator &iter) const
// See CodeGenerator::visitCreateThisWithTemplate
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
gc::InitialHeap initialHeap = tenuredHeap_ ? gc::TenuredHeap : gc::DefaultHeap;
JSObject *resultObject = JSObject::copy(cx, allocKind, initialHeap, templateObject);
JSObject *resultObject = NativeObject::copy(cx, allocKind, initialHeap, templateObject);
if (!resultObject)
return false;
@ -1149,13 +1150,13 @@ RObjectState::RObjectState(CompactBufferReader &reader)
bool
RObjectState::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedObject object(cx, &iter.read().toObject());
RootedNativeObject object(cx, &iter.read().toObject().as<NativeObject>());
MOZ_ASSERT(object->slotSpan() == numSlots());
RootedValue val(cx);
for (size_t i = 0; i < numSlots(); i++) {
val = iter.read();
object->nativeSetSlot(i, val);
object->setSlot(i, val);
}
val.setObject(*object);
@ -1181,7 +1182,7 @@ bool
RArrayState::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedValue result(cx);
JSObject *object = &iter.read().toObject();
ArrayObject *object = &iter.read().toObject().as<ArrayObject>();
uint32_t initLength = iter.read().toInt32();
object->setDenseInitializedLength(initLength);

Просмотреть файл

@ -23,6 +23,7 @@
#include "jit/BaselineFrame-inl.h"
#include "jit/IonFrames-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/StringObject-inl.h"
using namespace js;
@ -221,7 +222,7 @@ MutatePrototype(JSContext *cx, HandleObject obj, HandleValue value)
}
bool
InitProp(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value)
InitProp(JSContext *cx, HandleNativeObject obj, HandlePropertyName name, HandleValue value)
{
RootedId id(cx, NameToId(name));
return DefineNativeProperty(cx, obj, id, value, nullptr, nullptr, JSPROP_ENUMERATE);
@ -294,7 +295,7 @@ template bool StringsEqual<true>(JSContext *cx, HandleString lhs, HandleString r
template bool StringsEqual<false>(JSContext *cx, HandleString lhs, HandleString rhs, bool *res);
JSObject*
NewInitObject(JSContext *cx, HandleObject templateObject)
NewInitObject(JSContext *cx, HandleNativeObject templateObject)
{
NewObjectKind newKind = templateObject->hasSingletonType() ? SingletonObject : GenericObject;
if (!templateObject->hasLazyType() && templateObject->type()->shouldPreTenure())
@ -366,21 +367,19 @@ ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval)
}
bool
ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length)
ArrayPushDense(JSContext *cx, HandleArrayObject obj, HandleValue v, uint32_t *length)
{
MOZ_ASSERT(obj->is<ArrayObject>());
if (MOZ_LIKELY(obj->as<ArrayObject>().lengthIsWritable())) {
uint32_t idx = obj->as<ArrayObject>().length();
JSObject::EnsureDenseResult result = obj->ensureDenseElements(cx, idx, 1);
if (result == JSObject::ED_FAILED)
if (MOZ_LIKELY(obj->lengthIsWritable())) {
uint32_t idx = obj->length();
NativeObject::EnsureDenseResult result = obj->ensureDenseElements(cx, idx, 1);
if (result == NativeObject::ED_FAILED)
return false;
if (result == JSObject::ED_OK) {
if (result == NativeObject::ED_OK) {
obj->setDenseElement(idx, v);
MOZ_ASSERT(idx < INT32_MAX);
*length = idx + 1;
obj->as<ArrayObject>().setLengthInt32(*length);
obj->setLengthInt32(*length);
return true;
}
}
@ -511,15 +510,15 @@ SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValu
if (op == JSOP_SETALIASEDVAR) {
// Aliased var assigns ignore readonly attributes on the property, as
// required for initializing 'const' closure variables.
Shape *shape = obj->nativeLookup(cx, name);
Shape *shape = obj->as<NativeObject>().lookup(cx, name);
MOZ_ASSERT(shape && shape->hasSlot());
obj->nativeSetSlotWithType(cx, shape, value);
obj->as<NativeObject>().setSlotWithType(cx, shape, value);
return true;
}
if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
return baseops::SetPropertyHelper<SequentialExecution>(
cx, obj, obj, id,
cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
(op == JSOP_SETNAME || op == JSOP_SETGNAME)
? baseops::Unqualified
: baseops::Qualified,
@ -1074,17 +1073,15 @@ Recompile(JSContext *cx)
}
bool
SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue value,
SetDenseElement(JSContext *cx, HandleNativeObject obj, int32_t index, HandleValue value,
bool strict)
{
// This function is called from Ion code for StoreElementHole's OOL path.
// In this case we know the object is native, has no indexed properties
// and we can use setDenseElement instead of setDenseElementWithType.
MOZ_ASSERT(obj->isNative());
MOZ_ASSERT(!obj->isIndexed());
JSObject::EnsureDenseResult result = JSObject::ED_SPARSE;
NativeObject::EnsureDenseResult result = NativeObject::ED_SPARSE;
do {
if (index < 0)
break;
@ -1093,7 +1090,7 @@ SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue valu
break;
uint32_t idx = uint32_t(index);
result = obj->ensureDenseElements(cx, idx, 1);
if (result != JSObject::ED_OK)
if (result != NativeObject::ED_OK)
break;
if (isArray) {
ArrayObject &arr = obj->as<ArrayObject>();
@ -1104,9 +1101,9 @@ SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue valu
return true;
} while (false);
if (result == JSObject::ED_FAILED)
if (result == NativeObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
RootedValue indexVal(cx, Int32Value(index));
return SetObjectElement(cx, obj, indexVal, value, strict);

Просмотреть файл

@ -288,6 +288,7 @@ struct VMFunctionsModal
template <class> struct TypeToDataType { /* Unexpected return type for a VMFunction. */ };
template <> struct TypeToDataType<bool> { static const DataType result = Type_Bool; };
template <> struct TypeToDataType<JSObject *> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<NativeObject *> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<DeclEnvObject *> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<ArrayObject *> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<JSString *> { static const DataType result = Type_Object; };
@ -296,6 +297,8 @@ template <> struct TypeToDataType<HandleObject> { static const DataType result =
template <> struct TypeToDataType<HandleString> { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<HandlePropertyName> { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<HandleFunction> { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<NativeObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<ArrayObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<StaticWithObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<StaticBlockObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<HandleScript> { static const DataType result = Type_Handle; };
@ -322,6 +325,12 @@ template <> struct TypeToArgProperties<HandlePropertyName> {
template <> struct TypeToArgProperties<HandleFunction> {
static const uint32_t result = TypeToArgProperties<JSFunction *>::result | VMFunction::ByRef;
};
template <> struct TypeToArgProperties<Handle<NativeObject *> > {
static const uint32_t result = TypeToArgProperties<NativeObject *>::result | VMFunction::ByRef;
};
template <> struct TypeToArgProperties<Handle<ArrayObject *> > {
static const uint32_t result = TypeToArgProperties<ArrayObject *>::result | VMFunction::ByRef;
};
template <> struct TypeToArgProperties<Handle<StaticWithObject *> > {
static const uint32_t result = TypeToArgProperties<StaticWithObject *>::result | VMFunction::ByRef;
};
@ -384,6 +393,12 @@ template <> struct TypeToRootType<HandleTypeObject> {
template <> struct TypeToRootType<HandleScript> {
static const uint32_t result = VMFunction::RootCell;
};
template <> struct TypeToRootType<Handle<NativeObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
template <> struct TypeToRootType<Handle<ArrayObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
template <> struct TypeToRootType<Handle<StaticBlockObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
@ -616,7 +631,7 @@ bool CheckOverRecursedWithExtra(JSContext *cx, BaselineFrame *frame,
bool DefVarOrConst(JSContext *cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
bool SetConst(JSContext *cx, HandlePropertyName name, HandleObject scopeChain, HandleValue rval);
bool MutatePrototype(JSContext *cx, HandleObject obj, HandleValue value);
bool InitProp(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value);
bool InitProp(JSContext *cx, HandleNativeObject obj, HandlePropertyName name, HandleValue value);
template<bool Equal>
bool LooselyEqual(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res);
@ -634,11 +649,11 @@ bool StringsEqual(JSContext *cx, HandleString left, HandleString right, bool *re
// Allocation functions for JSOP_NEWARRAY and JSOP_NEWOBJECT and parallel array inlining
JSObject *NewInitParallelArray(JSContext *cx, HandleObject templateObj);
JSObject *NewInitObject(JSContext *cx, HandleObject templateObject);
JSObject *NewInitObject(JSContext *cx, HandleNativeObject templateObject);
JSObject *NewInitObjectWithClassPrototype(JSContext *cx, HandleObject templateObject);
bool ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval);
bool ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length);
bool ArrayPushDense(JSContext *cx, HandleArrayObject obj, HandleValue v, uint32_t *length);
bool ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval);
JSObject *ArrayConcatDense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject res);
JSString *ArrayJoin(JSContext *cx, HandleObject array, HandleString sep);
@ -714,7 +729,7 @@ JSString *RegExpReplace(JSContext *cx, HandleString string, HandleObject regexp,
JSString *StringReplace(JSContext *cx, HandleString string, HandleString pattern,
HandleString repl);
bool SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue value,
bool SetDenseElement(JSContext *cx, HandleNativeObject obj, int32_t index, HandleValue value,
bool strict);
#ifdef DEBUG

Просмотреть файл

@ -90,7 +90,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
CHECK(JS_DefineProperty(cx, obj, "quox", defineValue, AllowWritable));
CHECK(JS_GetPropertyDescriptor(cx, obj, "quox", &desc));
CHECK(CheckDescriptor(desc, false, true, true));
CHECK_SAME(ObjectValue(*obj), desc.value());
CHECK_SAME(JS::ObjectValue(*obj), desc.value());
return true;
}

Просмотреть файл

@ -67,7 +67,7 @@ document_resolve(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS_NewObject(cx, &DocumentAllClass, JS::NullPtr(), JS::NullPtr()));
if (!docAll)
return false;
JS::Rooted<JS::Value> allValue(cx, ObjectValue(*docAll));
JS::Rooted<JS::Value> allValue(cx, JS::ObjectValue(*docAll));
bool ok = JS_DefinePropertyById(cx, obj, id, allValue, 0);
objp.set(ok ? obj.get() : nullptr);
return ok;

Просмотреть файл

@ -38,8 +38,8 @@ BEGIN_TEST(testResolveRecursion)
JS_SetPrivate(obj1, this);
JS_SetPrivate(obj2, this);
JS::RootedValue obj1Val(cx, ObjectValue(*obj1));
JS::RootedValue obj2Val(cx, ObjectValue(*obj2));
JS::RootedValue obj1Val(cx, JS::ObjectValue(*obj1));
JS::RootedValue obj2Val(cx, JS::ObjectValue(*obj2));
CHECK(JS_DefineProperty(cx, global, "obj1", obj1Val, 0));
CHECK(JS_DefineProperty(cx, global, "obj2", obj2Val, 0));

Просмотреть файл

@ -2233,14 +2233,14 @@ JS_PUBLIC_API(void *)
JS_GetPrivate(JSObject *obj)
{
/* This function can be called by a finalizer. */
return obj->getPrivate();
return obj->fakeNativeGetPrivate();
}
JS_PUBLIC_API(void)
JS_SetPrivate(JSObject *obj, void *data)
{
/* This function can be called by a finalizer. */
obj->setPrivate(data);
obj->fakeNativeSetPrivate(data);
}
JS_PUBLIC_API(void *)
@ -2248,7 +2248,7 @@ JS_GetInstancePrivate(JSContext *cx, HandleObject obj, const JSClass *clasp, Cal
{
if (!JS_InstanceOf(cx, obj, clasp, args))
return nullptr;
return obj->getPrivate();
return obj->fakeNativeGetPrivate();
}
JS_PUBLIC_API(bool)
@ -2566,8 +2566,8 @@ JS_DeepFreezeObject(JSContext *cx, HandleObject obj)
return false;
/* Walk slots in obj and if any value is a non-null object, seal it. */
for (uint32_t i = 0, n = obj->slotSpan(); i < n; ++i) {
const Value &v = obj->getSlot(i);
for (uint32_t i = 0, n = obj->fakeNativeSlotSpan(); i < n; ++i) {
const Value &v = obj->fakeNativeGetSlot(i);
if (v.isPrimitive())
continue;
RootedObject obj(cx, &v.toObject());
@ -2612,12 +2612,12 @@ LookupResult(JSContext *cx, HandleObject obj, HandleObject obj2, HandleId id,
}
}
} else if (IsImplicitDenseOrTypedArrayElement(shape)) {
vp.set(obj2->getDenseOrTypedArrayElement(JSID_TO_INT(id)));
vp.set(obj2->as<NativeObject>().getDenseOrTypedArrayElement(JSID_TO_INT(id)));
return true;
} else {
/* Peek at the native property's slot value, without doing a Get. */
if (shape->hasSlot()) {
vp.set(obj2->nativeGetSlot(shape->slot()));
vp.set(obj2->as<NativeObject>().getSlot(shape->slot()));
return true;
}
}
@ -2735,7 +2735,7 @@ JS_AlreadyHasOwnPropertyById(JSContext *cx, HandleObject obj, HandleId id, bool
if (JSID_IS_INT(id)) {
uint32_t index = JSID_TO_INT(id);
if (obj->containsDenseElement(index)) {
if (obj->as<NativeObject>().containsDenseElement(index)) {
*foundp = true;
return true;
}
@ -2746,7 +2746,7 @@ JS_AlreadyHasOwnPropertyById(JSContext *cx, HandleObject obj, HandleId id, bool
}
}
*foundp = obj->nativeContains(cx, id);
*foundp = obj->as<NativeObject>().contains(cx, id);
return true;
}
@ -3321,14 +3321,14 @@ GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id,
if (obj2->isNative()) {
if (IsImplicitDenseOrTypedArrayElement(shape)) {
desc.setEnumerable();
desc.value().set(obj2->getDenseOrTypedArrayElement(JSID_TO_INT(id)));
desc.value().set(obj2->as<NativeObject>().getDenseOrTypedArrayElement(JSID_TO_INT(id)));
} else {
desc.setAttributes(shape->attributes());
desc.setGetter(shape->getter());
desc.setSetter(shape->setter());
MOZ_ASSERT(desc.value().isUndefined());
if (shape->hasSlot())
desc.value().set(obj2->nativeGetSlot(shape->slot()));
desc.value().set(obj2->as<NativeObject>().getSlot(shape->slot()));
}
} else {
if (obj2->is<ProxyObject>())
@ -3602,9 +3602,9 @@ JS_SetAllNonReservedSlotsToUndefined(JSContext *cx, JSObject *objArg)
const Class *clasp = obj->getClass();
unsigned numReserved = JSCLASS_RESERVED_SLOTS(clasp);
unsigned numSlots = obj->slotSpan();
unsigned numSlots = obj->as<NativeObject>().slotSpan();
for (unsigned i = numReserved; i < numSlots; i++)
obj->setSlot(i, UndefinedValue());
obj->as<NativeObject>().setSlot(i, UndefinedValue());
}
JS_PUBLIC_API(JSIdArray *)
@ -3633,11 +3633,11 @@ static const uint32_t JSSLOT_ITER_INDEX = 0;
static void
prop_iter_finalize(FreeOp *fop, JSObject *obj)
{
void *pdata = obj->getPrivate();
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->getSlot(JSSLOT_ITER_INDEX).toInt32() >= 0) {
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() >= 0) {
/* Non-native case: destroy the ida enumerated when obj was created. */
JSIdArray *ida = (JSIdArray *) pdata;
fop->free_(ida);
@ -3647,11 +3647,11 @@ prop_iter_finalize(FreeOp *fop, JSObject *obj)
static void
prop_iter_trace(JSTracer *trc, JSObject *obj)
{
void *pdata = obj->getPrivate();
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->getSlot(JSSLOT_ITER_INDEX).toInt32() < 0) {
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() < 0) {
/*
* Native case: just mark the next property to visit. We don't need a
* barrier here because the pointer is updated via setPrivate, which
@ -3659,7 +3659,7 @@ prop_iter_trace(JSTracer *trc, JSObject *obj)
*/
Shape *tmp = static_cast<Shape *>(pdata);
MarkShapeUnbarriered(trc, &tmp, "prop iter shape");
obj->setPrivateUnbarriered(tmp);
obj->as<NativeObject>().setPrivateUnbarriered(tmp);
} else {
/* Non-native case: mark each id in the JSIdArray private. */
JSIdArray *ida = (JSIdArray *) pdata;
@ -3691,7 +3691,7 @@ JS_NewPropertyIterator(JSContext *cx, HandleObject obj)
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
RootedObject iterobj(cx, NewObjectWithClassProto(cx, &prop_iter_class, nullptr, obj));
NativeObject *iterobj = NewNativeObjectWithClassProto(cx, &prop_iter_class, nullptr, obj);
if (!iterobj)
return nullptr;
@ -3720,11 +3720,11 @@ JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, iterobj);
int32_t i = iterobj->getSlot(JSSLOT_ITER_INDEX).toInt32();
int32_t i = iterobj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32();
if (i < 0) {
/* Native case: private data is a property tree node pointer. */
MOZ_ASSERT(iterobj->getParent()->isNative());
Shape *shape = static_cast<Shape *>(iterobj->getPrivate());
Shape *shape = static_cast<Shape *>(iterobj->as<NativeObject>().getPrivate());
while (shape->previous() && !shape->enumerable())
shape = shape->previous();
@ -3733,19 +3733,19 @@ JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
MOZ_ASSERT(shape->isEmptyShape());
idp.set(JSID_VOID);
} else {
iterobj->setPrivateGCThing(const_cast<Shape *>(shape->previous().get()));
iterobj->as<NativeObject>().setPrivateGCThing(const_cast<Shape *>(shape->previous().get()));
idp.set(shape->propid());
}
} else {
/* Non-native case: use the ida enumerated when iterobj was created. */
JSIdArray *ida = (JSIdArray *) iterobj->getPrivate();
JSIdArray *ida = (JSIdArray *) iterobj->as<NativeObject>().getPrivate();
MOZ_ASSERT(i <= ida->length);
STATIC_ASSUME(i <= ida->length);
if (i == 0) {
idp.set(JSID_VOID);
} else {
idp.set(ida->vector[--i]);
iterobj->setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
iterobj->as<NativeObject>().setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
}
}
return true;
@ -3754,13 +3754,13 @@ JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index)
{
return obj->getReservedSlot(index);
return obj->fakeNativeGetReservedSlot(index);
}
JS_PUBLIC_API(void)
JS_SetReservedSlot(JSObject *obj, uint32_t index, Value value)
{
obj->setReservedSlot(index, value);
obj->fakeNativeSetReservedSlot(index, value);
}
JS_PUBLIC_API(JSObject *)
@ -6476,7 +6476,7 @@ JS_PUBLIC_API(void *)
JS_EncodeInterpretedFunction(JSContext *cx, HandleObject funobjArg, uint32_t *lengthp)
{
XDREncoder encoder(cx);
RootedObject funobj(cx, funobjArg);
RootedFunction funobj(cx, &funobjArg->as<JSFunction>());
if (!encoder.codeFunction(&funobj))
return nullptr;
return encoder.forgetData(lengthp);
@ -6496,7 +6496,7 @@ JS_PUBLIC_API(JSObject *)
JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length)
{
XDRDecoder decoder(cx, data, length);
RootedObject funobj(cx);
RootedFunction funobj(cx);
if (!decoder.codeFunction(&funobj))
return nullptr;
return funobj;

Просмотреть файл

@ -39,6 +39,7 @@
#include "vm/ArgumentsObject-inl.h"
#include "vm/ArrayObject-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Runtime-inl.h"
using namespace js;
@ -213,8 +214,8 @@ GetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
IndexType index, bool *hole, MutableHandleValue vp)
{
AssertGreaterThanZero(index);
if (obj->isNative() && index < obj->getDenseInitializedLength()) {
vp.set(obj->getDenseElement(uint32_t(index)));
if (obj->isNative() && index < obj->as<NativeObject>().getDenseInitializedLength()) {
vp.set(obj->as<NativeObject>().getDenseElement(uint32_t(index)));
if (!vp.isMagic(JS_ELEMENTS_HOLE)) {
*hole = false;
return true;
@ -251,11 +252,12 @@ GetElementsSlow(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
bool
js::GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
{
if (aobj->is<ArrayObject>() && length <= aobj->getDenseInitializedLength() &&
if (aobj->is<ArrayObject>() &&
length <= aobj->as<ArrayObject>().getDenseInitializedLength() &&
!ObjectMayHaveExtraIndexedProperties(aobj))
{
/* No other indexed properties so hole = undefined */
const Value *srcbeg = aobj->getDenseElements();
const Value *srcbeg = aobj->as<ArrayObject>().getDenseElements();
const Value *srcend = srcbeg + length;
const Value *src = srcbeg;
for (Value *dst = vp; src < srcend; ++dst, ++src)
@ -285,7 +287,7 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
if (obj->is<ArrayObject>() && !obj->isIndexed()) {
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
/* Predicted/prefetched code should favor the remains-dense case. */
JSObject::EnsureDenseResult result = JSObject::ED_SPARSE;
NativeObject::EnsureDenseResult result = NativeObject::ED_SPARSE;
do {
if (index > uint32_t(-1))
break;
@ -296,7 +298,7 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
return false;
}
result = arr->ensureDenseElements(cx, idx, 1);
if (result != JSObject::ED_OK)
if (result != NativeObject::ED_OK)
break;
if (idx >= arr->length())
arr->setLengthInt32(idx + 1);
@ -304,9 +306,9 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
return true;
} while (false);
if (result == JSObject::ED_FAILED)
if (result == NativeObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
}
RootedId id(cx);
@ -336,16 +338,17 @@ DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool *succeede
MOZ_ASSERT(floor(index) == index);
if (obj->is<ArrayObject>() && !obj->isIndexed()) {
ArrayObject *aobj = &obj->as<ArrayObject>();
if (index <= UINT32_MAX) {
uint32_t idx = uint32_t(index);
if (idx < obj->getDenseInitializedLength()) {
if (!obj->maybeCopyElementsForWrite(cx))
if (idx < aobj->getDenseInitializedLength()) {
if (!aobj->maybeCopyElementsForWrite(cx))
return false;
if (idx+1 == obj->getDenseInitializedLength()) {
obj->setDenseInitializedLength(idx);
if (idx+1 == aobj->getDenseInitializedLength()) {
aobj->setDenseInitializedLength(idx);
} else {
obj->markDenseElementsNotPacked(cx);
obj->setDenseElement(idx, MagicValue(JS_ELEMENTS_HOLE));
aobj->markDenseElementsNotPacked(cx);
aobj->setDenseElement(idx, MagicValue(JS_ELEMENTS_HOLE));
}
if (!SuppressDeletedElement(cx, obj, idx))
return false;
@ -514,7 +517,7 @@ js::ArraySetLength(typename ExecutionModeTraits<mode>::ContextType cxArg,
bool lengthIsWritable = arr->lengthIsWritable();
#ifdef DEBUG
{
RootedShape lengthShape(cxArg, arr->nativeLookupPure(id));
RootedShape lengthShape(cxArg, arr->lookupPure(id));
MOZ_ASSERT(lengthShape);
MOZ_ASSERT(lengthShape->writable() == lengthIsWritable);
}
@ -692,11 +695,11 @@ js::ArraySetLength(typename ExecutionModeTraits<mode>::ContextType cxArg,
// the long run, with accessors replacing them both internally and at the
// API level, just run with this.
RootedShape lengthShape(cxArg, mode == ParallelExecution
? arr->nativeLookupPure(id)
: arr->nativeLookup(cxArg->asJSContext(), id));
if (!JSObject::changeProperty<mode>(cxArg, arr, lengthShape, attrs,
JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED,
array_length_getter, array_length_setter))
? arr->lookupPure(id)
: arr->lookup(cxArg->asJSContext(), id));
if (!NativeObject::changeProperty<mode>(cxArg, arr, lengthShape, attrs,
JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_SHARED,
array_length_getter, array_length_setter))
{
return false;
}
@ -847,7 +850,7 @@ js::ObjectMayHaveExtraIndexedProperties(JSObject *obj)
return true;
if (obj->isIndexed())
return true;
if (obj->getDenseInitializedLength() > 0)
if (obj->as<NativeObject>().getDenseInitializedLength() > 0)
return true;
if (IsAnyTypedArray(obj))
return true;
@ -857,7 +860,7 @@ js::ObjectMayHaveExtraIndexedProperties(JSObject *obj)
}
static bool
AddLengthProperty(ExclusiveContext *cx, HandleObject obj)
AddLengthProperty(ExclusiveContext *cx, HandleArrayObject obj)
{
/*
* Add the 'length' property for a newly created array,
@ -867,11 +870,11 @@ AddLengthProperty(ExclusiveContext *cx, HandleObject obj)
*/
RootedId lengthId(cx, NameToId(cx->names().length));
MOZ_ASSERT(!obj->nativeLookup(cx, lengthId));
MOZ_ASSERT(!obj->lookup(cx, lengthId));
return JSObject::addProperty(cx, obj, lengthId, array_length_getter, array_length_setter,
SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0,
/* allowDictionary = */ false);
return NativeObject::addProperty(cx, obj, lengthId, array_length_getter, array_length_setter,
SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0,
/* allowDictionary = */ false);
}
#if JS_HAS_TOSOURCE
@ -988,12 +991,12 @@ ArrayJoinKernel(JSContext *cx, SeparatorOp sepOp, HandleObject obj, uint32_t len
// This loop handles all elements up to initializedLength. If
// length > initLength we rely on the second loop to add the
// other elements.
uint32_t initLength = obj->getDenseInitializedLength();
uint32_t initLength = obj->as<ArrayObject>().getDenseInitializedLength();
while (i < initLength) {
if (!CheckForInterrupt(cx))
return false;
const Value &elem = obj->getDenseElement(i);
const Value &elem = obj->as<ArrayObject>().getDenseElement(i);
if (elem.isString()) {
if (!sb.append(elem.toString()))
@ -1069,9 +1072,9 @@ js::ArrayJoin(JSContext *cx, HandleObject obj, HandleLinearString sepstr, uint32
// the 0th element is a string, ToString() of that element is a no-op and
// so it can be immediately returned as the result.
if (length == 1 && !Locale && obj->is<ArrayObject>() &&
obj->getDenseInitializedLength() == 1)
obj->as<ArrayObject>().getDenseInitializedLength() == 1)
{
const Value &elem0 = obj->getDenseElement(0);
const Value &elem0 = obj->as<ArrayObject>().getDenseElement(0);
if (elem0.isString()) {
return elem0.toString();
}
@ -1270,19 +1273,19 @@ InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t coun
if (ObjectMayHaveExtraIndexedProperties(obj))
break;
if (obj->shouldConvertDoubleElements())
break;
HandleArrayObject arr = obj.as<ArrayObject>();
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
if (arr->shouldConvertDoubleElements())
break;
if (!arr->lengthIsWritable() && start + count > arr->length())
break;
JSObject::EnsureDenseResult result = arr->ensureDenseElements(cx, start, count);
if (result != JSObject::ED_OK) {
if (result == JSObject::ED_FAILED)
NativeObject::EnsureDenseResult result = arr->ensureDenseElements(cx, start, count);
if (result != NativeObject::ED_OK) {
if (result == NativeObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
break;
}
@ -1344,8 +1347,10 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
if (ObjectMayHaveExtraIndexedProperties(obj))
break;
HandleArrayObject arr = obj.as<ArrayObject>();
/* An empty array or an array with no elements is already reversed. */
if (len == 0 || obj->getDenseCapacity() == 0) {
if (len == 0 || arr->getDenseCapacity() == 0) {
args.rval().setObject(*obj);
return true;
}
@ -1359,32 +1364,33 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
* holes in the array at its start) and ensure that the capacity is
* sufficient to hold all the elements in the array if it were full.
*/
JSObject::EnsureDenseResult result = obj->ensureDenseElements(cx, len, 0);
if (result != JSObject::ED_OK) {
if (result == JSObject::ED_FAILED)
NativeObject::EnsureDenseResult result =
arr->ensureDenseElements(cx, len, 0);
if (result != NativeObject::ED_OK) {
if (result == NativeObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
break;
}
/* Fill out the array's initialized length to its proper length. */
obj->ensureDenseInitializedLength(cx, len, 0);
arr->ensureDenseInitializedLength(cx, len, 0);
RootedValue origlo(cx), orighi(cx);
uint32_t lo = 0, hi = len - 1;
for (; lo < hi; lo++, hi--) {
origlo = obj->getDenseElement(lo);
orighi = obj->getDenseElement(hi);
obj->setDenseElement(lo, orighi);
origlo = arr->getDenseElement(lo);
orighi = arr->getDenseElement(hi);
arr->setDenseElement(lo, orighi);
if (orighi.isMagic(JS_ELEMENTS_HOLE) &&
!SuppressDeletedProperty(cx, obj, INT_TO_JSID(lo)))
!SuppressDeletedProperty(cx, arr, INT_TO_JSID(lo)))
{
return false;
}
obj->setDenseElement(hi, origlo);
arr->setDenseElement(hi, origlo);
if (origlo.isMagic(JS_ELEMENTS_HOLE) &&
!SuppressDeletedProperty(cx, obj, INT_TO_JSID(hi)))
!SuppressDeletedProperty(cx, arr, INT_TO_JSID(hi)))
{
return false;
}
@ -1395,7 +1401,7 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
* array has trailing holes (and thus the original array began with
* holes).
*/
args.rval().setObject(*obj);
args.rval().setObject(*arr);
return true;
} while (false);
@ -2084,13 +2090,14 @@ js::array_push(JSContext *cx, unsigned argc, Value *vp)
break;
uint32_t argCount = args.length();
JSObject::EnsureDenseResult result = obj->ensureDenseElements(cx, length, argCount);
if (result == JSObject::ED_FAILED)
NativeObject::EnsureDenseResult result =
obj->as<NativeObject>().ensureDenseElements(cx, length, argCount);
if (result == NativeObject::ED_FAILED)
return false;
if (result == JSObject::ED_OK) {
if (result == NativeObject::ED_OK) {
for (uint32_t i = 0, index = length; i < argCount; index++, i++)
obj->setDenseElementWithType(cx, index, args[i]);
obj->as<NativeObject>().setDenseElementWithType(cx, index, args[i]);
uint32_t newlength = length + argCount;
args.rval().setNumber(newlength);
if (obj->is<ArrayObject>()) {
@ -2100,7 +2107,7 @@ js::array_push(JSContext *cx, unsigned argc, Value *vp)
return SetLengthProperty(cx, obj, newlength);
}
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
} while (false);
/* Steps 4-5. */
@ -2152,10 +2159,9 @@ js::array_pop(JSContext *cx, unsigned argc, Value *vp)
}
void
js::ArrayShiftMoveElements(JSObject *obj)
js::ArrayShiftMoveElements(ArrayObject *obj)
{
MOZ_ASSERT(obj->is<ArrayObject>());
MOZ_ASSERT(obj->as<ArrayObject>().lengthIsWritable());
MOZ_ASSERT(obj->lengthIsWritable());
/*
* At this point the length and initialized length have already been
@ -2196,25 +2202,27 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
uint32_t newlen = len - 1;
/* Fast paths. */
if (obj->is<ArrayObject>() &&
obj->getDenseInitializedLength() > 0 &&
newlen < obj->getDenseCapacity() &&
!ObjectMayHaveExtraIndexedProperties(obj))
{
args.rval().set(obj->getDenseElement(0));
if (args.rval().isMagic(JS_ELEMENTS_HOLE))
args.rval().setUndefined();
if (obj->is<ArrayObject>()) {
ArrayObject *aobj = &obj->as<ArrayObject>();
if (aobj->getDenseInitializedLength() > 0 &&
newlen < aobj->getDenseCapacity() &&
!ObjectMayHaveExtraIndexedProperties(aobj))
{
args.rval().set(aobj->getDenseElement(0));
if (args.rval().isMagic(JS_ELEMENTS_HOLE))
args.rval().setUndefined();
if (!obj->maybeCopyElementsForWrite(cx))
return false;
if (!aobj->maybeCopyElementsForWrite(cx))
return false;
obj->moveDenseElements(0, 1, obj->getDenseInitializedLength() - 1);
obj->setDenseInitializedLength(obj->getDenseInitializedLength() - 1);
aobj->moveDenseElements(0, 1, aobj->getDenseInitializedLength() - 1);
aobj->setDenseInitializedLength(aobj->getDenseInitializedLength() - 1);
if (!SetLengthProperty(cx, obj, newlen))
return false;
if (!SetLengthProperty(cx, obj, newlen))
return false;
return SuppressDeletedProperty(cx, obj, INT_TO_JSID(newlen));
return SuppressDeletedProperty(cx, obj, INT_TO_JSID(newlen));
}
}
/* Steps 5, 10. */
@ -2268,18 +2276,20 @@ js::array_unshift(JSContext *cx, unsigned argc, Value *vp)
break;
if (ObjectMayHaveExtraIndexedProperties(obj))
break;
if (!obj->as<ArrayObject>().lengthIsWritable())
ArrayObject *aobj = &obj->as<ArrayObject>();
if (!aobj->lengthIsWritable())
break;
JSObject::EnsureDenseResult result = obj->ensureDenseElements(cx, length, args.length());
if (result != JSObject::ED_OK) {
if (result == JSObject::ED_FAILED)
NativeObject::EnsureDenseResult result =
aobj->ensureDenseElements(cx, length, args.length());
if (result != NativeObject::ED_OK) {
if (result == NativeObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
break;
}
obj->moveDenseElements(args.length(), 0, length);
aobj->moveDenseElements(args.length(), 0, length);
for (uint32_t i = 0; i < args.length(); i++)
obj->setDenseElement(i, MagicValue(JS_ELEMENTS_HOLE));
aobj->setDenseElement(i, MagicValue(JS_ELEMENTS_HOLE));
optimized = true;
} while (false);
@ -2374,7 +2384,7 @@ CanOptimizeForDenseStorage(HandleObject arr, uint32_t startingIndex, uint32_t co
* is subsumed by the initializedLength comparison.)
*/
return !ObjectMayHaveExtraIndexedProperties(arr) &&
startingIndex + count <= arr->getDenseInitializedLength();
startingIndex + count <= arr->as<ArrayObject>().getDenseInitializedLength();
}
/* ES5 15.4.4.12. */
@ -2433,7 +2443,7 @@ js::array_splice_impl(JSContext *cx, unsigned argc, Value *vp, bool returnValueI
Rooted<ArrayObject*> arr(cx);
if (CanOptimizeForDenseStorage(obj, actualStart, actualDeleteCount, cx)) {
if (returnValueIsUsed) {
arr = NewDenseCopiedArray(cx, actualDeleteCount, obj, actualStart);
arr = NewDenseCopiedArray(cx, actualDeleteCount, obj.as<ArrayObject>(), actualStart);
if (!arr)
return false;
TryReuseArrayType(obj, arr);
@ -2466,20 +2476,22 @@ js::array_splice_impl(JSContext *cx, unsigned argc, Value *vp, bool returnValueI
uint32_t finalLength = len - actualDeleteCount + itemCount;
if (CanOptimizeForDenseStorage(obj, 0, len, cx)) {
if (!obj->maybeCopyElementsForWrite(cx))
ArrayObject *aobj = &obj->as<ArrayObject>();
if (!aobj->maybeCopyElementsForWrite(cx))
return false;
/* Steps 12(a)-(b). */
obj->moveDenseElements(targetIndex, sourceIndex, len - sourceIndex);
aobj->moveDenseElements(targetIndex, sourceIndex, len - sourceIndex);
/*
* Update the initialized length. Do so before shrinking so that we
* can apply the write barrier to the old slots.
*/
obj->setDenseInitializedLength(finalLength);
aobj->setDenseInitializedLength(finalLength);
/* Steps 12(c)-(d). */
obj->shrinkElements(cx, finalLength);
aobj->shrinkElements(cx, finalLength);
} else {
/*
* This is all very slow if the length is very large. We don't yet
@ -2542,20 +2554,21 @@ js::array_splice_impl(JSContext *cx, unsigned argc, Value *vp, bool returnValueI
if (obj->is<ArrayObject>()) {
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
if (arr->lengthIsWritable()) {
JSObject::EnsureDenseResult res =
NativeObject::EnsureDenseResult res =
arr->ensureDenseElements(cx, arr->length(), itemCount - actualDeleteCount);
if (res == JSObject::ED_FAILED)
if (res == NativeObject::ED_FAILED)
return false;
}
}
if (CanOptimizeForDenseStorage(obj, len, itemCount - actualDeleteCount, cx)) {
if (!obj->maybeCopyElementsForWrite(cx))
ArrayObject *aobj = &obj->as<ArrayObject>();
if (!aobj->maybeCopyElementsForWrite(cx))
return false;
obj->moveDenseElements(actualStart + itemCount,
actualStart + actualDeleteCount,
len - (actualStart + actualDeleteCount));
obj->setDenseInitializedLength(len + itemCount - actualDeleteCount);
aobj->moveDenseElements(actualStart + itemCount,
actualStart + actualDeleteCount,
len - (actualStart + actualDeleteCount));
aobj->setDenseInitializedLength(len + itemCount - actualDeleteCount);
} else {
RootedValue fromValue(cx);
for (double k = len - actualDeleteCount; k > actualStart; k--) {
@ -2646,8 +2659,8 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
uint32_t length;
if (aobj->is<ArrayObject>() && !aobj->isIndexed()) {
length = aobj->as<ArrayObject>().length();
uint32_t initlen = aobj->getDenseInitializedLength();
narr = NewDenseCopiedArray(cx, initlen, aobj, 0);
uint32_t initlen = aobj->as<ArrayObject>().getDenseInitializedLength();
narr = NewDenseCopiedArray(cx, initlen, aobj.as<ArrayObject>(), 0);
if (!narr)
return false;
TryReuseArrayType(aobj, narr);
@ -2754,11 +2767,12 @@ js::array_slice(JSContext *cx, unsigned argc, Value *vp)
TryReuseArrayType(obj, narr);
if (obj->is<ArrayObject>() && !ObjectMayHaveExtraIndexedProperties(obj)) {
if (obj->getDenseInitializedLength() > begin) {
uint32_t numSourceElements = obj->getDenseInitializedLength() - begin;
ArrayObject *aobj = &obj->as<ArrayObject>();
if (aobj->getDenseInitializedLength() > begin) {
uint32_t numSourceElements = aobj->getDenseInitializedLength() - begin;
uint32_t initLength = Min(numSourceElements, end - begin);
narr->setDenseInitializedLength(initLength);
narr->initDenseElements(0, &obj->getDenseElement(begin), initLength);
narr->initDenseElements(0, &aobj->getDenseElement(begin), initLength);
}
args.rval().setObject(*narr);
return true;
@ -2766,11 +2780,11 @@ js::array_slice(JSContext *cx, unsigned argc, Value *vp)
if (js::SliceOp op = obj->getOps()->slice) {
// Ensure that we have dense elements, so that DOM can use js::UnsafeDefineElement.
JSObject::EnsureDenseResult result = narr->ensureDenseElements(cx, 0, end - begin);
if (result == JSObject::ED_FAILED)
NativeObject::EnsureDenseResult result = narr->ensureDenseElements(cx, 0, end - begin);
if (result == NativeObject::ED_FAILED)
return false;
if (result == JSObject::ED_OK) {
if (result == NativeObject::ED_OK) {
if (!op(cx, obj, begin, end, narr))
return false;
@ -2779,7 +2793,7 @@ js::array_slice(JSContext *cx, unsigned argc, Value *vp)
}
// Fallthrough
MOZ_ASSERT(result == JSObject::ED_SPARSE);
MOZ_ASSERT(result == NativeObject::ED_SPARSE);
}
@ -3114,9 +3128,14 @@ CreateArrayPrototype(JSContext *cx, JSProtoKey key)
if (!shape)
return nullptr;
RootedObject arrayProto(cx, JSObject::createArray(cx, gc::FINALIZE_OBJECT4, gc::TenuredHeap, shape, type, 0));
if (!arrayProto || !JSObject::setSingletonType(cx, arrayProto) || !AddLengthProperty(cx, arrayProto))
RootedArrayObject arrayProto(cx, ArrayObject::createArray(cx, gc::FINALIZE_OBJECT4,
gc::TenuredHeap, shape, type, 0));
if (!arrayProto ||
!JSObject::setSingletonType(cx, arrayProto) ||
!AddLengthProperty(cx, arrayProto))
{
return nullptr;
}
/*
* The default 'new' type of Array.prototype is required by type inference
@ -3158,7 +3177,7 @@ const Class ArrayObject::class_ = {
*/
static inline bool
EnsureNewArrayElements(ExclusiveContext *cx, JSObject *obj, uint32_t length)
EnsureNewArrayElements(ExclusiveContext *cx, ArrayObject *obj, uint32_t length)
{
/*
* If ensureElements creates dynamically allocated slots, then having
@ -3237,7 +3256,7 @@ NewArray(ExclusiveContext *cxArg, uint32_t length,
if (!shape)
return nullptr;
Rooted<ArrayObject*> arr(cxArg, JSObject::createArray(cxArg, allocKind,
RootedArrayObject arr(cxArg, ArrayObject::createArray(cxArg, allocKind,
GetInitialHeap(newKind, &ArrayObject::class_),
shape, type, length));
if (!arr)
@ -3277,7 +3296,7 @@ js::NewDenseFullyAllocatedArray(ExclusiveContext *cx, uint32_t length,
JSObject *proto /* = nullptr */,
NewObjectKind newKind /* = GenericObject */)
{
return NewArray<JSObject::NELEMENTS_LIMIT>(cx, length, proto, newKind);
return NewArray<NativeObject::NELEMENTS_LIMIT>(cx, length, proto, newKind);
}
ArrayObject * JS_FASTCALL
@ -3327,12 +3346,12 @@ js::NewDenseArray(ExclusiveContext *cx, uint32_t length, HandleTypeObject type,
}
ArrayObject *
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset,
JSObject *proto /* = nullptr */)
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleArrayObject src,
uint32_t elementOffset, JSObject *proto /* = nullptr */)
{
MOZ_ASSERT(!src->isIndexed());
ArrayObject* arr = NewArray<JSObject::NELEMENTS_LIMIT>(cx, length, proto);
ArrayObject *arr = NewArray<NativeObject::NELEMENTS_LIMIT>(cx, length, proto);
if (!arr)
return nullptr;
@ -3352,7 +3371,7 @@ ArrayObject *
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values,
JSObject *proto /* = nullptr */, NewObjectKind newKind /* = GenericObject */)
{
ArrayObject* arr = NewArray<JSObject::NELEMENTS_LIMIT>(cx, length, proto);
ArrayObject *arr = NewArray<NativeObject::NELEMENTS_LIMIT>(cx, length, proto);
if (!arr)
return nullptr;
@ -3377,7 +3396,8 @@ js::NewDenseFullyAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSOb
RootedShape shape(cx, templateObject->lastProperty());
gc::InitialHeap heap = GetInitialHeap(GenericObject, &ArrayObject::class_);
Rooted<ArrayObject *> arr(cx, JSObject::createArray(cx, allocKind, heap, shape, type, length));
Rooted<ArrayObject *> arr(cx, ArrayObject::createArray(cx, allocKind,
heap, shape, type, length));
if (!arr)
return nullptr;
@ -3390,7 +3410,7 @@ js::NewDenseFullyAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSOb
}
JSObject *
js::NewDenseCopyOnWriteArray(JSContext *cx, HandleObject templateObject, gc::InitialHeap heap)
js::NewDenseCopyOnWriteArray(JSContext *cx, HandleNativeObject templateObject, gc::InitialHeap heap)
{
RootedShape shape(cx, templateObject->lastProperty());
@ -3405,7 +3425,7 @@ js::NewDenseCopyOnWriteArray(JSContext *cx, HandleObject templateObject, gc::Ini
return nullptr;
}
Rooted<ArrayObject *> arr(cx, JSObject::createCopyOnWriteArray(cx, heap, shape, templateObject));
ArrayObject *arr = ArrayObject::createCopyOnWriteArray(cx, heap, shape, templateObject);
if (!arr)
return nullptr;
@ -3433,7 +3453,7 @@ js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
continue;
}
fprintf(stderr, "%s: (len %u", bytes, obj->as<ArrayObject>().length());
fprintf(stderr, ", capacity %u", obj->getDenseCapacity());
fprintf(stderr, ", capacity %u", obj->as<ArrayObject>().getDenseCapacity());
fputs(")\n", stderr);
js_free(bytes);
}

Просмотреть файл

@ -85,7 +85,8 @@ NewDenseArray(ExclusiveContext *cx, uint32_t length, HandleTypeObject type,
/* Create a dense array with a copy of the dense array elements in src. */
extern ArrayObject *
NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, JSObject *proto = nullptr);
NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleArrayObject src,
uint32_t elementOffset, JSObject *proto = nullptr);
/* Create a dense array from the given array values, which must be rooted */
extern ArrayObject *
@ -98,7 +99,7 @@ NewDenseFullyAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject
/* Create a dense array with the same copy-on-write elements as another object. */
extern JSObject *
NewDenseCopyOnWriteArray(JSContext *cx, HandleObject templateObject, gc::InitialHeap heap);
NewDenseCopyOnWriteArray(JSContext *cx, HandleNativeObject templateObject, gc::InitialHeap heap);
/*
* Determines whether a write to the given element on |obj| should fail because
@ -174,7 +175,7 @@ extern JSString *
array_join_impl(JSContext *cx, HandleValue array, HandleString sep);
extern void
ArrayShiftMoveElements(JSObject *obj);
ArrayShiftMoveElements(ArrayObject *obj);
extern bool
array_shift(JSContext *cx, unsigned argc, js::Value *vp);

Просмотреть файл

@ -140,7 +140,7 @@ js_InitBooleanClass(JSContext *cx, HandleObject obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanObject::class_));
RootedNativeObject booleanProto(cx, global->createBlankPrototype(cx, &BooleanObject::class_));
if (!booleanProto)
return nullptr;
booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));

Просмотреть файл

@ -524,7 +524,7 @@ js::ReportUsageError(JSContext *cx, HandleObject callee, const char *msg)
const char *usageStr = "usage";
PropertyName *usageAtom = Atomize(cx, usageStr, strlen(usageStr))->asPropertyName();
RootedId id(cx, NameToId(usageAtom));
DebugOnly<Shape *> shape = static_cast<Shape *>(callee->nativeLookup(cx, id));
DebugOnly<Shape *> shape = static_cast<Shape *>(callee->as<NativeObject>().lookup(cx, id));
MOZ_ASSERT(!shape->configurable());
MOZ_ASSERT(!shape->writable());
MOZ_ASSERT(shape->hasDefaultGetter());

Просмотреть файл

@ -161,9 +161,9 @@ struct ThreadSafeContext : ContextFriendFields,
friend class Activation;
friend UnownedBaseShape *BaseShape::lookupUnowned(ThreadSafeContext *cx,
const StackBaseShape &base);
friend Shape *JSObject::lookupChildProperty(ThreadSafeContext *cx,
JS::HandleObject obj, js::HandleShape parent,
js::StackShape &child);
friend Shape *NativeObject::lookupChildProperty(ThreadSafeContext *cx,
HandleNativeObject obj, HandleShape parent,
StackShape &child);
public:
enum ContextKind {

Просмотреть файл

@ -3009,8 +3009,8 @@ FinishDateClassInit(JSContext *cx, HandleObject ctor, HandleObject proto)
RootedValue toUTCStringFun(cx);
RootedId toUTCStringId(cx, NameToId(cx->names().toUTCString));
RootedId toGMTStringId(cx, NameToId(cx->names().toGMTString));
return baseops::GetProperty(cx, proto, toUTCStringId, &toUTCStringFun) &&
baseops::DefineGeneric(cx, proto, toGMTStringId, toUTCStringFun,
return baseops::GetProperty(cx, proto.as<NativeObject>(), toUTCStringId, &toUTCStringFun) &&
baseops::DefineGeneric(cx, proto.as<NativeObject>(), toGMTStringId, toUTCStringFun,
JS_PropertyStub, JS_StrictPropertyStub, 0);
}

Просмотреть файл

@ -29,6 +29,7 @@
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/ScopeObject-inl.h"
using namespace js;
@ -434,7 +435,7 @@ js::NotifyAnimationActivity(JSObject *obj)
JS_FRIEND_API(uint32_t)
js::GetObjectSlotSpan(JSObject *obj)
{
return obj->slotSpan();
return obj->fakeNativeSlotSpan();
}
JS_FRIEND_API(bool)
@ -556,7 +557,7 @@ js::GetOriginalEval(JSContext *cx, HandleObject scope, MutableHandleObject eval)
JS_FRIEND_API(void)
js::SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const js::Value &value)
{
obj->setSlot(slot, value);
obj->fakeNativeSetSlot(slot, value);
}
JS_FRIEND_API(bool)
@ -1384,8 +1385,8 @@ JS_FRIEND_API(void)
js::UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value)
{
MOZ_ASSERT(obj->isNative());
MOZ_ASSERT(index < obj->getDenseInitializedLength());
obj->setDenseElementWithType(cx, index, value);
MOZ_ASSERT(index < obj->as<NativeObject>().getDenseInitializedLength());
obj->as<NativeObject>().setDenseElementWithType(cx, index, value);
}
JS_FRIEND_API(bool)

Просмотреть файл

@ -508,7 +508,7 @@ js::fun_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObjec
template<XDRMode mode>
bool
js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
MutableHandleObject objp)
MutableHandleFunction objp)
{
enum FirstWordFlag {
HasAtom = 0x1,
@ -528,7 +528,7 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
Rooted<LazyScript *> lazy(cx);
if (mode == XDR_ENCODE) {
fun = &objp->as<JSFunction>();
fun = objp;
if (!fun->isInterpreted()) {
JSAutoByteString funNameBytes;
if (const char *name = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
@ -629,10 +629,10 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
}
template bool
js::XDRInterpretedFunction(XDRState<XDR_ENCODE> *, HandleObject, HandleScript, MutableHandleObject);
js::XDRInterpretedFunction(XDRState<XDR_ENCODE> *, HandleObject, HandleScript, MutableHandleFunction);
template bool
js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, MutableHandleObject);
js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, MutableHandleFunction);
JSObject *
js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun)
@ -1329,7 +1329,7 @@ JSFunction::initBoundFunction(JSContext *cx, HandleValue thisArg,
if (!self->setFlag(cx, BaseShape::BOUND_FUNCTION))
return false;
if (!JSObject::setSlotSpan(cx, self, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
if (!NativeObject::setSlotSpan(cx, self, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
return false;
self->setSlot(JSSLOT_BOUND_FUNCTION_THIS, thisArg);

Просмотреть файл

@ -25,7 +25,7 @@ typedef JSThreadSafeNative ThreadSafeNative;
struct JSAtomState;
class JSFunction : public JSObject
class JSFunction : public js::NativeObject
{
public:
static const js::Class class_;
@ -631,7 +631,7 @@ JSString *FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, boo
template<XDRMode mode>
bool
XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope,
HandleScript enclosingScript, MutableHandleObject objp);
HandleScript enclosingScript, MutableHandleFunction objp);
extern JSObject *
CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);

Просмотреть файл

@ -4379,7 +4379,7 @@ static void
AssertNotOnGrayList(JSObject *obj)
{
MOZ_ASSERT_IF(IsGrayListObject(obj),
obj->getReservedSlot(ProxyObject::grayLinkSlot(obj)).isUndefined());
obj->fakeNativeGetReservedSlot(ProxyObject::grayLinkSlot(obj)).isUndefined());
}
#endif
@ -4394,11 +4394,11 @@ static JSObject *
NextIncomingCrossCompartmentPointer(JSObject *prev, bool unlink)
{
unsigned slot = ProxyObject::grayLinkSlot(prev);
JSObject *next = prev->getReservedSlot(slot).toObjectOrNull();
JSObject *next = prev->fakeNativeGetReservedSlot(slot).toObjectOrNull();
MOZ_ASSERT_IF(next, IsGrayListObject(next));
if (unlink)
prev->setSlot(slot, UndefinedValue());
prev->fakeNativeSetSlot(slot, UndefinedValue());
return next;
}
@ -4413,11 +4413,11 @@ js::DelayCrossCompartmentGrayMarking(JSObject *src)
JSObject *dest = CrossCompartmentPointerReferent(src);
JSCompartment *comp = dest->compartment();
if (src->getReservedSlot(slot).isUndefined()) {
src->setCrossCompartmentSlot(slot, ObjectOrNullValue(comp->gcIncomingGrayPointers));
if (src->fakeNativeGetReservedSlot(slot).isUndefined()) {
src->fakeNativeSetCrossCompartmentSlot(slot, ObjectOrNullValue(comp->gcIncomingGrayPointers));
comp->gcIncomingGrayPointers = src;
} else {
MOZ_ASSERT(src->getReservedSlot(slot).isObjectOrNull());
MOZ_ASSERT(src->fakeNativeGetReservedSlot(slot).isObjectOrNull());
}
#ifdef DEBUG
@ -4487,11 +4487,11 @@ RemoveFromGrayList(JSObject *wrapper)
return false;
unsigned slot = ProxyObject::grayLinkSlot(wrapper);
if (wrapper->getReservedSlot(slot).isUndefined())
if (wrapper->fakeNativeGetReservedSlot(slot).isUndefined())
return false; /* Not on our list. */
JSObject *tail = wrapper->getReservedSlot(slot).toObjectOrNull();
wrapper->setReservedSlot(slot, UndefinedValue());
JSObject *tail = wrapper->fakeNativeGetReservedSlot(slot).toObjectOrNull();
wrapper->fakeNativeSetReservedSlot(slot, UndefinedValue());
JSCompartment *comp = CrossCompartmentPointerReferent(wrapper)->compartment();
JSObject *obj = comp->gcIncomingGrayPointers;
@ -4502,9 +4502,9 @@ RemoveFromGrayList(JSObject *wrapper)
while (obj) {
unsigned slot = ProxyObject::grayLinkSlot(obj);
JSObject *next = obj->getReservedSlot(slot).toObjectOrNull();
JSObject *next = obj->fakeNativeGetReservedSlot(slot).toObjectOrNull();
if (next == wrapper) {
obj->setCrossCompartmentSlot(slot, ObjectOrNullValue(tail));
obj->fakeNativeSetCrossCompartmentSlot(slot, ObjectOrNullValue(tail));
return true;
}
obj = next;

Просмотреть файл

@ -15,12 +15,13 @@
#include "mozilla/TypeTraits.h"
#include "jslock.h"
#include "jsobj.h"
#include "js/GCAPI.h"
#include "js/SliceBudget.h"
#include "js/Vector.h"
#include "vm/ObjectImpl.h"
namespace js {
namespace gc {
@ -215,7 +216,7 @@ GetGCArrayKind(size_t numSlots)
* unused.
*/
JS_STATIC_ASSERT(ObjectElements::VALUES_PER_HEADER == 2);
if (numSlots > JSObject::NELEMENTS_LIMIT || numSlots + 2 >= SLOTS_TO_THING_KIND_LIMIT)
if (numSlots > NativeObject::NELEMENTS_LIMIT || numSlots + 2 >= SLOTS_TO_THING_KIND_LIMIT)
return FINALIZE_OBJECT2;
return slotsToThingKind[numSlots + 2];
}
@ -1187,7 +1188,7 @@ class RelocationOverlay
static const uintptr_t Relocated = uintptr_t(0xbad0bad1);
// Putting the magic value after the forwarding pointer is a terrible hack
// to make ObjectImpl::zone() work on forwarded objects.
// to make JSObject::zone() work on forwarded objects.
/* The location |this| was moved to. */
Cell *newLocation_;
@ -1214,7 +1215,7 @@ class RelocationOverlay
void forwardTo(Cell *cell) {
MOZ_ASSERT(!isForwarded());
MOZ_ASSERT(ObjectImpl::offsetOfShape() == offsetof(RelocationOverlay, newLocation_));
MOZ_ASSERT(JSObject::offsetOfShape() == offsetof(RelocationOverlay, newLocation_));
newLocation_ = cell;
magic_ = Relocated;
next_ = nullptr;

Просмотреть файл

@ -606,7 +606,7 @@ AllocateObject(ThreadSafeContext *cx, AllocKind kind, size_t nDynamicSlots, Init
obj = static_cast<JSObject *>(js::gc::ArenaLists::refillFreeList<allowGC>(cx, kind));
if (obj)
obj->setInitialSlots(slots);
obj->fakeNativeSetInitialSlots(slots);
else
js_free(slots);

Просмотреть файл

@ -36,6 +36,7 @@
#include "jsscriptinlines.h"
#include "jit/ExecutionMode-inl.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::gc;
@ -1036,7 +1037,7 @@ TypeObjectKey::proto()
}
bool
ObjectImpl::hasTenuredProto() const
JSObject::hasTenuredProto() const
{
return type_->hasTenuredProto();
}
@ -1102,7 +1103,7 @@ TypeObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
if (!JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
if (JSObject *obj = singleton()) {
if (obj->isNative() && obj->nativeLookupPure(id))
if (obj->isNative() && obj->as<NativeObject>().containsPure(id))
EnsureTrackPropertyTypes(cx, obj, id);
}
}
@ -1822,11 +1823,11 @@ HeapTypeSetKey::constant(CompilerConstraintList *constraints, Value *valOut)
return false;
// Get the current value of the property.
Shape *shape = obj->nativeLookupPure(id());
Shape *shape = obj->as<NativeObject>().lookupPure(id());
if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot() || shape->hadOverwrite())
return false;
Value val = obj->nativeGetSlot(shape->slot());
Value val = obj->as<NativeObject>().getSlot(shape->slot());
// If the value is a pointer to an object in the nursery, don't optimize.
if (val.isGCThing() && IsInsideNursery(val.toGCThing()))
@ -2615,7 +2616,7 @@ TypeCompartment::setTypeToHomogenousArray(ExclusiveContext *cx,
}
void
TypeCompartment::fixArrayType(ExclusiveContext *cx, JSObject *obj)
TypeCompartment::fixArrayType(ExclusiveContext *cx, ArrayObject *obj)
{
AutoEnterAnalysis enter(cx);
@ -2625,7 +2626,6 @@ TypeCompartment::fixArrayType(ExclusiveContext *cx, JSObject *obj)
* If the array is heterogenous, keep the existing type object, which has
* unknown properties.
*/
MOZ_ASSERT(obj->is<ArrayObject>());
unsigned len = obj->getDenseInitializedLength();
if (len == 0)
@ -2647,13 +2647,13 @@ TypeCompartment::fixArrayType(ExclusiveContext *cx, JSObject *obj)
}
void
types::FixRestArgumentsType(ExclusiveContext *cx, JSObject *obj)
types::FixRestArgumentsType(ExclusiveContext *cx, ArrayObject *obj)
{
cx->compartment()->types.fixRestArgumentsType(cx, obj);
}
void
TypeCompartment::fixRestArgumentsType(ExclusiveContext *cx, JSObject *obj)
TypeCompartment::fixRestArgumentsType(ExclusiveContext *cx, ArrayObject *obj)
{
AutoEnterAnalysis enter(cx);
@ -2661,8 +2661,6 @@ TypeCompartment::fixRestArgumentsType(ExclusiveContext *cx, JSObject *obj)
* Tracking element types for rest argument arrays is not worth it, but we
* still want it to be known that it's a dense array.
*/
MOZ_ASSERT(obj->is<ArrayObject>());
setTypeToHomogenousArray(cx, obj, Type::UnknownType());
}
@ -2740,7 +2738,7 @@ UpdateObjectTableEntryTypes(ExclusiveContext *cx, ObjectTableEntry &entry,
}
void
TypeCompartment::fixObjectType(ExclusiveContext *cx, JSObject *obj)
TypeCompartment::fixObjectType(ExclusiveContext *cx, NativeObject *obj)
{
AutoEnterAnalysis enter(cx);
@ -2874,7 +2872,7 @@ TypeCompartment::newTypedObject(JSContext *cx, IdValuePair *properties, size_t n
if (!p)
return nullptr;
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
if (!obj) {
cx->clearPendingException();
return nullptr;
@ -2882,7 +2880,7 @@ TypeCompartment::newTypedObject(JSContext *cx, IdValuePair *properties, size_t n
MOZ_ASSERT(obj->getProto() == p->value().object->proto().toObject());
RootedShape shape(cx, p->value().shape);
if (!JSObject::setLastProperty(cx, obj, shape)) {
if (!NativeObject::setLastProperty(cx, obj, shape)) {
cx->clearPendingException();
return nullptr;
}
@ -2912,7 +2910,7 @@ TypeObject::setProto(JSContext *cx, TaggedProto proto)
}
static inline void
UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shape *shape,
UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, NativeObject *obj, Shape *shape,
bool indexed)
{
MOZ_ASSERT(obj->hasSingletonType() && !obj->hasLazyType());
@ -2927,7 +2925,7 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shap
if (!indexed && types->canSetDefinite(shape->slot()))
types->setDefinite(shape->slot());
const Value &value = obj->nativeGetSlot(shape->slot());
const Value &value = obj->getSlot(shape->slot());
/*
* Don't add initial undefined types for properties of global objects
@ -2961,6 +2959,8 @@ TypeObject::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *t
return;
}
NativeObject *obj = &singleton()->as<NativeObject>();
/*
* Fill the property in with any type the object already has in an own
* property. We are only interested in plain native properties and
@ -2970,16 +2970,16 @@ TypeObject::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *t
if (JSID_IS_VOID(id)) {
/* Go through all shapes on the object to get integer-valued properties. */
RootedShape shape(cx, singleton()->lastProperty());
RootedShape shape(cx, obj->lastProperty());
while (!shape->isEmptyShape()) {
if (JSID_IS_VOID(IdToTypeId(shape->propid())))
UpdatePropertyType(cx, types, singleton(), shape, true);
UpdatePropertyType(cx, types, obj, shape, true);
shape = shape->previous();
}
/* Also get values of any dense elements in the object. */
for (size_t i = 0; i < singleton()->getDenseInitializedLength(); i++) {
const Value &value = singleton()->getDenseElement(i);
for (size_t i = 0; i < obj->getDenseInitializedLength(); i++) {
const Value &value = obj->getDenseElement(i);
if (!value.isMagic(JS_ELEMENTS_HOLE)) {
Type type = GetValueType(value);
types->TypeSet::addType(type, &cx->typeLifoAlloc());
@ -2987,12 +2987,12 @@ TypeObject::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *t
}
} else if (!JSID_IS_EMPTY(id)) {
RootedId rootedId(cx, id);
Shape *shape = singleton()->nativeLookup(cx, rootedId);
Shape *shape = obj->lookup(cx, rootedId);
if (shape)
UpdatePropertyType(cx, types, singleton(), shape, false);
UpdatePropertyType(cx, types, obj, shape, false);
}
if (singleton()->watched()) {
if (obj->watched()) {
/*
* Mark the property as non-data, to inhibit optimizations on it
* and avoid bypassing the watchpoint handler.
@ -3014,7 +3014,7 @@ TypeObject::addDefiniteProperties(ExclusiveContext *cx, Shape *shape)
jsid id = IdToTypeId(shape->propid());
if (!JSID_IS_VOID(id)) {
MOZ_ASSERT_IF(shape->slot() >= shape->numFixedSlots(),
shape->numFixedSlots() == JSObject::MAX_FIXED_SLOTS);
shape->numFixedSlots() == NativeObject::MAX_FIXED_SLOTS);
TypeSet *types = getProperty(cx, id);
if (!types)
return false;
@ -3322,7 +3322,8 @@ TypeObject::print()
if (newScript()) {
if (newScript()->analyzed()) {
fprintf(stderr, "\n newScript %d properties", (int) newScript()->templateObject()->slotSpan());
fprintf(stderr, "\n newScript %d properties",
(int) newScript()->templateObject()->slotSpan());
if (newScript()->initializedType()) {
fprintf(stderr, " initializedType %p with %d properties",
newScript()->initializedType(), (int) newScript()->initializedShape()->slotSpan());
@ -3530,13 +3531,12 @@ types::FillBytecodeTypeMap(JSScript *script, uint32_t *bytecodeMap)
MOZ_ASSERT(added == script->nTypeSets());
}
JSObject *
ArrayObject *
types::GetOrFixupCopyOnWriteObject(JSContext *cx, HandleScript script, jsbytecode *pc)
{
// Make sure that the template object for script/pc has a type indicating
// that the object and its copies have copy on write elements.
RootedObject obj(cx, script->getObject(GET_UINT32_INDEX(pc)));
MOZ_ASSERT(obj->is<ArrayObject>());
RootedArrayObject obj(cx, &script->getObject(GET_UINT32_INDEX(pc))->as<ArrayObject>());
MOZ_ASSERT(obj->denseElementsAreCopyOnWrite());
if (obj->type()->fromAllocationSite()) {
@ -3561,7 +3561,7 @@ types::GetOrFixupCopyOnWriteObject(JSContext *cx, HandleScript script, jsbytecod
return obj;
}
JSObject *
ArrayObject *
types::GetCopyOnWriteObject(JSScript *script, jsbytecode *pc)
{
// GetOrFixupCopyOnWriteObject should already have been called for
@ -3569,8 +3569,7 @@ types::GetCopyOnWriteObject(JSScript *script, jsbytecode *pc)
// COPY_ON_WRITE flag. We don't assert this here, due to a corner case
// where this property doesn't hold. See jsop_newarray_copyonwrite in
// IonBuilder.
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
MOZ_ASSERT(obj->is<ArrayObject>());
ArrayObject *obj = &script->getObject(GET_UINT32_INDEX(pc))->as<ArrayObject>();
MOZ_ASSERT(obj->denseElementsAreCopyOnWrite());
return obj;
@ -3739,7 +3738,8 @@ TypeNewScript::make(JSContext *cx, TypeObject *type, JSFunction *fun)
newScript->fun = fun;
JSObject **preliminaryObjects = type->zone()->pod_calloc<JSObject *>(PRELIMINARY_OBJECT_COUNT);
NativeObject **preliminaryObjects =
type->zone()->pod_calloc<NativeObject *>(PRELIMINARY_OBJECT_COUNT);
if (!preliminaryObjects)
return;
@ -3750,7 +3750,7 @@ TypeNewScript::make(JSContext *cx, TypeObject *type, JSFunction *fun)
}
void
TypeNewScript::registerNewObject(JSObject *res)
TypeNewScript::registerNewObject(NativeObject *res)
{
MOZ_ASSERT(!analyzed());
@ -3762,7 +3762,7 @@ TypeNewScript::registerNewObject(JSObject *res)
// New script objects must have the maximum number of fixed slots, so that
// we can adjust their shape later to match the number of fixed slots used
// by the template object we eventually create.
MOZ_ASSERT(res->numFixedSlots() == JSObject::MAX_FIXED_SLOTS);
MOZ_ASSERT(res->numFixedSlots() == NativeObject::MAX_FIXED_SLOTS);
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
if (!preliminaryObjects[i]) {
@ -3775,7 +3775,7 @@ TypeNewScript::registerNewObject(JSObject *res)
}
void
TypeNewScript::unregisterNewObject(JSObject *res)
TypeNewScript::unregisterNewObject(NativeObject *res)
{
MOZ_ASSERT(!analyzed());
@ -3833,7 +3833,7 @@ CommonPrefix(Shape *first, Shape *second)
}
static bool
ChangeObjectFixedSlotCount(JSContext *cx, JSObject *obj, gc::AllocKind allocKind)
ChangeObjectFixedSlotCount(JSContext *cx, NativeObject *obj, gc::AllocKind allocKind)
{
MOZ_ASSERT(OnlyHasDataProperties(obj->lastProperty()));
@ -3901,7 +3901,7 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
Shape *prefixShape = nullptr;
size_t maxSlotSpan = 0;
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
JSObject *obj = preliminaryObjects[i];
NativeObject *obj = preliminaryObjects[i];
if (!obj)
continue;
@ -3929,7 +3929,7 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
gc::AllocKind kind = gc::GetGCObjectKind(maxSlotSpan);
if (kind != gc::GetGCObjectKind(JSObject::MAX_FIXED_SLOTS)) {
if (kind != gc::GetGCObjectKind(NativeObject::MAX_FIXED_SLOTS)) {
// The template object will have a different allocation kind from the
// preliminary objects that have already been constructed. Optimizing
// definite property accesses requires both that the property is
@ -3940,7 +3940,7 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
// old number of fixed slots.
Shape *newPrefixShape = nullptr;
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
JSObject *obj = preliminaryObjects[i];
NativeObject *obj = preliminaryObjects[i];
if (!obj)
continue;
if (!ChangeObjectFixedSlotCount(cx, obj, kind))
@ -3957,13 +3957,13 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
}
RootedTypeObject typeRoot(cx, type);
templateObject_ = NewObjectWithType(cx, typeRoot, cx->global(), kind, MaybeSingletonObject);
templateObject_ = NewNativeObjectWithType(cx, typeRoot, cx->global(), kind, MaybeSingletonObject);
if (!templateObject_)
return false;
Vector<Initializer> initializerVector(cx);
RootedObject templateRoot(cx, templateObject());
RootedNativeObject templateRoot(cx, templateObject());
if (!jit::AnalyzeNewScriptDefiniteProperties(cx, fun, type, templateRoot, &initializerVector))
return false;
@ -4097,7 +4097,7 @@ TypeNewScript::rollbackPartiallyInitializedObjects(JSContext *cx, TypeObject *ty
}
// Found a matching frame.
RootedObject obj(cx, &thisv.toObject());
RootedNativeObject obj(cx, &thisv.toObject().as<NativeObject>());
// Whether all identified 'new' properties have been initialized.
bool finished = false;
@ -4149,7 +4149,7 @@ TypeNewScript::rollbackPartiallyInitializedObjects(JSContext *cx, TypeObject *ty
}
if (!finished)
(void) JSObject::rollbackProperties(cx, obj, numProperties);
(void) NativeObject::rollbackProperties(cx, obj, numProperties);
}
}
@ -4175,7 +4175,7 @@ TypeNewScript::sweep(FreeOp *fop)
// are about to be destroyed.
if (preliminaryObjects) {
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
JSObject **ptr = &preliminaryObjects[i];
NativeObject **ptr = &preliminaryObjects[i];
if (*ptr && IsObjectAboutToBeFinalized(ptr))
*ptr = nullptr;
}

Просмотреть файл

@ -904,13 +904,13 @@ class TypeNewScript
// analyses are performed and this array is cleared. The pointers in this
// array are weak.
static const uint32_t PRELIMINARY_OBJECT_COUNT = 20;
JSObject **preliminaryObjects;
NativeObject **preliminaryObjects;
// After the new script properties analyses have been performed, a template
// object to use for newly constructed objects. The shape of this object
// reflects all definite properties the object will have, and the
// allocation kind to use.
HeapPtrObject templateObject_;
HeapPtrNativeObject templateObject_;
// Order in which definite properties become initialized. We need this in
// case the definite properties are invalidated (such as by adding a setter
@ -955,7 +955,7 @@ class TypeNewScript
return true;
}
JSObject *templateObject() const {
NativeObject *templateObject() const {
return templateObject_;
}
@ -974,8 +974,8 @@ class TypeNewScript
void fixupAfterMovingGC();
#endif
void registerNewObject(JSObject *res);
void unregisterNewObject(JSObject *res);
void registerNewObject(NativeObject *res);
void unregisterNewObject(NativeObject *res);
bool maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, bool force = false);
void rollbackPartiallyInitializedObjects(JSContext *cx, TypeObject *type);
@ -1402,10 +1402,10 @@ class TypeScript
void
FillBytecodeTypeMap(JSScript *script, uint32_t *bytecodeMap);
JSObject *
ArrayObject *
GetOrFixupCopyOnWriteObject(JSContext *cx, HandleScript script, jsbytecode *pc);
JSObject *
ArrayObject *
GetCopyOnWriteObject(JSScript *script, jsbytecode *pc);
class RecompileInfo;
@ -1629,9 +1629,9 @@ struct TypeCompartment
void setTypeToHomogenousArray(ExclusiveContext *cx, JSObject *obj, Type type);
public:
void fixArrayType(ExclusiveContext *cx, JSObject *obj);
void fixObjectType(ExclusiveContext *cx, JSObject *obj);
void fixRestArgumentsType(ExclusiveContext *cx, JSObject *obj);
void fixArrayType(ExclusiveContext *cx, ArrayObject *obj);
void fixObjectType(ExclusiveContext *cx, NativeObject *obj);
void fixRestArgumentsType(ExclusiveContext *cx, ArrayObject *obj);
JSObject *newTypedObject(JSContext *cx, IdValuePair *properties, size_t nproperties);
@ -1668,7 +1668,7 @@ struct TypeCompartment
size_t *objectTypeTables);
};
void FixRestArgumentsType(ExclusiveContext *cxArg, JSObject *obj);
void FixRestArgumentsType(ExclusiveContext *cxArg, ArrayObject *obj);
struct TypeZone
{

Просмотреть файл

@ -547,13 +547,13 @@ MarkObjectStateChange(ExclusiveContext *cx, JSObject *obj)
*/
inline void
FixArrayType(ExclusiveContext *cx, HandleObject obj)
FixArrayType(ExclusiveContext *cx, ArrayObject *obj)
{
cx->compartment()->types.fixArrayType(cx, obj);
}
inline void
FixObjectType(ExclusiveContext *cx, HandleObject obj)
FixObjectType(ExclusiveContext *cx, NativeObject *obj)
{
cx->compartment()->types.fixObjectType(cx, obj);
}

Просмотреть файл

@ -36,6 +36,7 @@
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Stack-inl.h"
#include "vm/String-inl.h"
@ -131,7 +132,7 @@ Enumerate(JSContext *cx, HandleObject pobj, jsid id,
}
static bool
EnumerateNativeProperties(JSContext *cx, HandleObject pobj, unsigned flags, IdSet &ht,
EnumerateNativeProperties(JSContext *cx, HandleNativeObject pobj, unsigned flags, IdSet &ht,
AutoIdVector *props)
{
bool enumerateSymbols;
@ -284,9 +285,9 @@ Snapshot(JSContext *cx, JSObject *pobj_, unsigned flags, AutoIdVector *props)
!pobj->getOps()->enumerate &&
!(clasp->flags & JSCLASS_NEW_ENUMERATE))
{
if (!clasp->enumerate(cx, pobj))
if (!clasp->enumerate(cx, pobj.as<NativeObject>()))
return false;
if (!EnumerateNativeProperties(cx, pobj, flags, ht, props))
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
} else {
if (pobj->is<ProxyObject>()) {
@ -322,7 +323,7 @@ Snapshot(JSContext *cx, JSObject *pobj_, unsigned flags, AutoIdVector *props)
if (!JSObject::enumerate(cx, pobj, op, &state, &id))
return false;
if (state.isMagic(JS_NATIVE_ENUMERATE)) {
if (!EnumerateNativeProperties(cx, pobj, flags, ht, props))
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
} else {
while (true) {
@ -480,8 +481,9 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
if (!shape)
return nullptr;
JSObject *obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp), shape, type);
NativeObject *obj =
MaybeNativeObject(JSObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp), shape, type));
if (!obj)
return nullptr;
@ -684,12 +686,12 @@ js::GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleVa
NativeIterator *lastni = last->getNativeIterator();
if (!(lastni->flags & (JSITER_ACTIVE|JSITER_UNREUSABLE)) &&
obj->isNative() &&
obj->hasEmptyElements() &&
obj->as<NativeObject>().hasEmptyElements() &&
obj->lastProperty() == lastni->shapes_array[0])
{
JSObject *proto = obj->getProto();
if (proto->isNative() &&
proto->hasEmptyElements() &&
proto->as<NativeObject>().hasEmptyElements() &&
proto->lastProperty() == lastni->shapes_array[1] &&
!proto->getProto())
{
@ -711,12 +713,12 @@ js::GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleVa
JSObject *pobj = obj;
do {
if (!pobj->isNative() ||
!pobj->hasEmptyElements() ||
!pobj->as<NativeObject>().hasEmptyElements() ||
IsAnyTypedArray(pobj) ||
pobj->hasUncacheableProto() ||
pobj->getOps()->enumerate ||
pobj->getClass()->enumerate != JS_EnumerateStub ||
pobj->nativeContainsPure(cx->names().iteratorIntrinsic))
pobj->as<NativeObject>().containsPure(cx->names().iteratorIntrinsic))
{
shapes.clear();
goto miss;
@ -1343,7 +1345,7 @@ ForOfIterator::init(HandleValue iterable, NonIterableBehavior nonIterableBehavio
return false;
bool optimized;
if (!stubChain->tryOptimizeArray(cx, iterableObj, &optimized))
if (!stubChain->tryOptimizeArray(cx, iterableObj.as<ArrayObject>(), &optimized))
return false;
if (optimized) {
@ -1412,10 +1414,9 @@ ForOfIterator::nextFromOptimizedArray(MutableHandleValue vp, bool *done)
if (!CheckForInterrupt(cx_))
return false;
MOZ_ASSERT(iterator->isNative());
MOZ_ASSERT(iterator->is<ArrayObject>());
ArrayObject *arr = &iterator->as<ArrayObject>();
if (index >= iterator->as<ArrayObject>().length()) {
if (index >= arr->length()) {
vp.setUndefined();
*done = true;
return true;
@ -1423,8 +1424,8 @@ ForOfIterator::nextFromOptimizedArray(MutableHandleValue vp, bool *done)
*done = false;
// Try to get array element via direct access.
if (index < iterator->getDenseInitializedLength()) {
vp.set(iterator->getDenseElement(index));
if (index < arr->getDenseInitializedLength()) {
vp.set(arr->getDenseElement(index));
if (!vp.isMagic(JS_ELEMENTS_HOLE)) {
++index;
return true;
@ -1704,7 +1705,7 @@ js_NewGenerator(JSContext *cx, const InterpreterRegs &stackRegs)
MOZ_ASSERT(stackfp->script()->isGenerator());
Rooted<GlobalObject*> global(cx, &stackfp->global());
RootedObject obj(cx);
RootedNativeObject obj(cx);
if (stackfp->script()->isStarGenerator()) {
RootedValue pval(cx);
RootedObject fun(cx, stackfp->fun());
@ -1718,13 +1719,13 @@ js_NewGenerator(JSContext *cx, const InterpreterRegs &stackRegs)
if (!proto)
return nullptr;
}
obj = NewObjectWithGivenProto(cx, &StarGeneratorObject::class_, proto, global);
obj = NewNativeObjectWithGivenProto(cx, &StarGeneratorObject::class_, proto, global);
} else {
MOZ_ASSERT(stackfp->script()->isLegacyGenerator());
JSObject *proto = GlobalObject::getOrCreateLegacyGeneratorObjectPrototype(cx, global);
if (!proto)
return nullptr;
obj = NewObjectWithGivenProto(cx, &LegacyGeneratorObject::class_, proto, global);
obj = NewNativeObjectWithGivenProto(cx, &LegacyGeneratorObject::class_, proto, global);
}
if (!obj)
return nullptr;

Просмотреть файл

@ -114,7 +114,7 @@ struct NativeIterator
}
};
class PropertyIteratorObject : public JSObject
class PropertyIteratorObject : public NativeObject
{
public:
static const Class class_;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,7 +25,6 @@
#include "jsinferinlines.h"
#include "gc/ForkJoinNursery-inl.h"
#include "vm/ObjectImpl-inl.h"
/* static */ inline bool
JSObject::setGenericAttributes(JSContext *cx, js::HandleObject obj,
@ -33,15 +32,9 @@ JSObject::setGenericAttributes(JSContext *cx, js::HandleObject obj,
{
js::types::MarkTypePropertyNonData(cx, obj, id);
js::GenericAttributesOp op = obj->getOps()->setGenericAttributes;
return (op ? op : js::baseops::SetAttributes)(cx, obj, id, attrsp);
}
/* static */ inline bool
JSObject::changePropertyAttributes(JSContext *cx, js::HandleObject obj,
js::HandleShape shape, unsigned attrs)
{
return !!changeProperty<js::SequentialExecution>(cx, obj, shape, attrs, 0,
shape->getter(), shape->setter());
if (op)
return op(cx, obj, id, attrsp);
return js::baseops::SetAttributes(cx, obj.as<js::NativeObject>(), id, attrsp);
}
/* static */ inline bool
@ -50,7 +43,9 @@ JSObject::deleteGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
{
js::types::MarkTypePropertyNonData(cx, obj, id);
js::DeleteGenericOp op = obj->getOps()->deleteGeneric;
return (op ? op : js::baseops::DeleteGeneric)(cx, obj, id, succeeded);
if (op)
return op(cx, obj, id, succeeded);
return js::baseops::DeleteGeneric(cx, obj.as<js::NativeObject>(), id, succeeded);
}
/* static */ inline bool
@ -96,281 +91,6 @@ JSObject::finalize(js::FreeOp *fop)
finish(fop);
}
inline void
JSObject::removeLastProperty(js::ExclusiveContext *cx)
{
MOZ_ASSERT(canRemoveLastProperty());
JS::RootedObject self(cx, this);
js::RootedShape prev(cx, lastProperty()->previous());
JS_ALWAYS_TRUE(setLastProperty(cx, self, prev));
}
inline bool
JSObject::canRemoveLastProperty()
{
/*
* Check that the information about the object stored in the last
* property's base shape is consistent with that stored in the previous
* shape. If not consistent, then the last property cannot be removed as it
* will induce a change in the object itself, and the object must be
* converted to dictionary mode instead. See BaseShape comment in jsscope.h
*/
MOZ_ASSERT(!inDictionaryMode());
js::Shape *previous = lastProperty()->previous().get();
return previous->getObjectParent() == lastProperty()->getObjectParent()
&& previous->getObjectMetadata() == lastProperty()->getObjectMetadata()
&& previous->getObjectFlags() == lastProperty()->getObjectFlags();
}
inline void
JSObject::setShouldConvertDoubleElements()
{
MOZ_ASSERT(is<js::ArrayObject>() && !hasEmptyElements());
getElementsHeader()->setShouldConvertDoubleElements();
}
inline void
JSObject::clearShouldConvertDoubleElements()
{
MOZ_ASSERT(is<js::ArrayObject>() && !hasEmptyElements());
getElementsHeader()->clearShouldConvertDoubleElements();
}
inline bool
JSObject::setDenseElementIfHasType(uint32_t index, const js::Value &val)
{
if (!js::types::HasTypePropertyId(this, JSID_VOID, val))
return false;
setDenseElementMaybeConvertDouble(index, val);
return true;
}
inline void
JSObject::setDenseElementWithType(js::ExclusiveContext *cx, uint32_t index,
const js::Value &val)
{
// Avoid a slow AddTypePropertyId call if the type is the same as the type
// of the previous element.
js::types::Type thisType = js::types::GetValueType(val);
if (index == 0 || js::types::GetValueType(elements[index - 1]) != thisType)
js::types::AddTypePropertyId(cx, this, JSID_VOID, thisType);
setDenseElementMaybeConvertDouble(index, val);
}
inline void
JSObject::initDenseElementWithType(js::ExclusiveContext *cx, uint32_t index,
const js::Value &val)
{
MOZ_ASSERT(!shouldConvertDoubleElements());
js::types::AddTypePropertyId(cx, this, JSID_VOID, val);
initDenseElement(index, val);
}
inline void
JSObject::setDenseElementHole(js::ExclusiveContext *cx, uint32_t index)
{
js::types::MarkTypeObjectFlags(cx, this, js::types::OBJECT_FLAG_NON_PACKED);
setDenseElement(index, js::MagicValue(JS_ELEMENTS_HOLE));
}
/* static */ inline void
JSObject::removeDenseElementForSparseIndex(js::ExclusiveContext *cx,
js::HandleObject obj, uint32_t index)
{
js::types::MarkTypeObjectFlags(cx, obj,
js::types::OBJECT_FLAG_NON_PACKED |
js::types::OBJECT_FLAG_SPARSE_INDEXES);
if (obj->containsDenseElement(index))
obj->setDenseElement(index, js::MagicValue(JS_ELEMENTS_HOLE));
}
inline bool
JSObject::writeToIndexWouldMarkNotPacked(uint32_t index)
{
return getElementsHeader()->initializedLength < index;
}
inline void
JSObject::markDenseElementsNotPacked(js::ExclusiveContext *cx)
{
MOZ_ASSERT(isNative());
MarkTypeObjectFlags(cx, this, js::types::OBJECT_FLAG_NON_PACKED);
}
inline void
JSObject::ensureDenseInitializedLengthNoPackedCheck(js::ThreadSafeContext *cx, uint32_t index,
uint32_t extra)
{
MOZ_ASSERT(cx->isThreadLocal(this));
MOZ_ASSERT(!denseElementsAreCopyOnWrite());
/*
* Ensure that the array's contents have been initialized up to index, and
* mark the elements through 'index + extra' as initialized in preparation
* for a write.
*/
MOZ_ASSERT(index + extra <= getDenseCapacity());
uint32_t &initlen = getElementsHeader()->initializedLength;
if (initlen < index + extra) {
size_t offset = initlen;
for (js::HeapSlot *sp = elements + initlen;
sp != elements + (index + extra);
sp++, offset++)
{
sp->init(this, js::HeapSlot::Element, offset, js::MagicValue(JS_ELEMENTS_HOLE));
}
initlen = index + extra;
}
}
inline void
JSObject::ensureDenseInitializedLength(js::ExclusiveContext *cx, uint32_t index, uint32_t extra)
{
if (writeToIndexWouldMarkNotPacked(index))
markDenseElementsNotPacked(cx);
ensureDenseInitializedLengthNoPackedCheck(cx, index, extra);
}
inline void
JSObject::ensureDenseInitializedLengthPreservePackedFlag(js::ThreadSafeContext *cx,
uint32_t index, uint32_t extra)
{
MOZ_ASSERT(!writeToIndexWouldMarkNotPacked(index));
ensureDenseInitializedLengthNoPackedCheck(cx, index, extra);
}
JSObject::EnsureDenseResult
JSObject::extendDenseElements(js::ThreadSafeContext *cx,
uint32_t requiredCapacity, uint32_t extra)
{
MOZ_ASSERT(cx->isThreadLocal(this));
MOZ_ASSERT(!denseElementsAreCopyOnWrite());
/*
* Don't grow elements for non-extensible objects or watched objects. Dense
* elements can be added/written with no extensible or watchpoint checks as
* long as there is capacity for them.
*/
if (!nonProxyIsExtensible() || watched()) {
MOZ_ASSERT(getDenseCapacity() == 0);
return ED_SPARSE;
}
/*
* Don't grow elements for objects which already have sparse indexes.
* This avoids needing to count non-hole elements in willBeSparseElements
* every time a new index is added.
*/
if (isIndexed())
return ED_SPARSE;
/*
* We use the extra argument also as a hint about number of non-hole
* elements to be inserted.
*/
if (requiredCapacity > MIN_SPARSE_INDEX &&
willBeSparseElements(requiredCapacity, extra)) {
return ED_SPARSE;
}
if (!growElements(cx, requiredCapacity))
return ED_FAILED;
return ED_OK;
}
inline JSObject::EnsureDenseResult
JSObject::ensureDenseElementsNoPackedCheck(js::ThreadSafeContext *cx, uint32_t index, uint32_t extra)
{
MOZ_ASSERT(isNative());
if (!maybeCopyElementsForWrite(cx))
return ED_FAILED;
uint32_t currentCapacity = getDenseCapacity();
uint32_t requiredCapacity;
if (extra == 1) {
/* Optimize for the common case. */
if (index < currentCapacity) {
ensureDenseInitializedLengthNoPackedCheck(cx, index, 1);
return ED_OK;
}
requiredCapacity = index + 1;
if (requiredCapacity == 0) {
/* Overflow. */
return ED_SPARSE;
}
} else {
requiredCapacity = index + extra;
if (requiredCapacity < index) {
/* Overflow. */
return ED_SPARSE;
}
if (requiredCapacity <= currentCapacity) {
ensureDenseInitializedLengthNoPackedCheck(cx, index, extra);
return ED_OK;
}
}
EnsureDenseResult edr = extendDenseElements(cx, requiredCapacity, extra);
if (edr != ED_OK)
return edr;
ensureDenseInitializedLengthNoPackedCheck(cx, index, extra);
return ED_OK;
}
inline JSObject::EnsureDenseResult
JSObject::ensureDenseElements(js::ExclusiveContext *cx, uint32_t index, uint32_t extra)
{
if (writeToIndexWouldMarkNotPacked(index))
markDenseElementsNotPacked(cx);
return ensureDenseElementsNoPackedCheck(cx, index, extra);
}
inline JSObject::EnsureDenseResult
JSObject::ensureDenseElementsPreservePackedFlag(js::ThreadSafeContext *cx, uint32_t index,
uint32_t extra)
{
MOZ_ASSERT(!writeToIndexWouldMarkNotPacked(index));
return ensureDenseElementsNoPackedCheck(cx, index, extra);
}
inline js::Value
JSObject::getDenseOrTypedArrayElement(uint32_t idx)
{
if (is<js::TypedArrayObject>())
return as<js::TypedArrayObject>().getElement(idx);
if (is<js::SharedTypedArrayObject>())
return as<js::SharedTypedArrayObject>().getElement(idx);
return getDenseElement(idx);
}
inline void
JSObject::initDenseElementsUnbarriered(uint32_t dstStart, const js::Value *src, uint32_t count) {
/*
* For use by parallel threads, which since they cannot see nursery
* things do not require a barrier.
*/
MOZ_ASSERT(dstStart + count <= getDenseCapacity());
MOZ_ASSERT(!denseElementsAreCopyOnWrite());
#if defined(DEBUG) && defined(JSGC_GENERATIONAL)
/*
* This asserts a global invariant: parallel code does not
* observe objects inside the generational GC's nursery.
*/
MOZ_ASSERT(!js::gc::IsInsideGGCNursery(this));
for (uint32_t index = 0; index < count; ++index) {
const JS::Value& value = src[index];
if (value.isMarkable())
MOZ_ASSERT(!js::gc::IsInsideGGCNursery(static_cast<js::gc::Cell *>(value.toGCThing())));
}
#endif
memcpy(&elements[dstStart], src, count * sizeof(js::HeapSlot));
}
/* static */ inline bool
JSObject::setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj)
{
@ -496,6 +216,19 @@ JSObject::setProto(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto,
return *succeeded;
}
/* static */ inline bool
JSObject::isExtensible(js::ExclusiveContext *cx, js::HandleObject obj, bool *extensible)
{
if (obj->is<js::ProxyObject>()) {
if (!cx->shouldBeJSContext())
return false;
return js::Proxy::isExtensible(cx->asJSContext(), obj, extensible);
}
*extensible = obj->nonProxyIsExtensible();
return true;
}
inline bool
JSObject::isQualifiedVarObj()
{
@ -512,6 +245,19 @@ JSObject::isUnqualifiedVarObj()
return lastProperty()->hasObjectFlag(js::BaseShape::UNQUALIFIED_VAROBJ);
}
inline bool
ClassCanHaveFixedData(const js::Class *clasp)
{
// Normally, the number of fixed slots given an object is the maximum
// permitted for its size class. For array buffers and non-shared typed
// arrays we only use enough to cover the class reserved slots, so that
// the remaining space in the object's allocation is available for the
// buffer's data.
return clasp == &js::ArrayBufferObject::class_
|| clasp == &js::InlineOpaqueTypedObject::class_
|| js::IsTypedArrayClass(clasp);
}
/* static */ inline JSObject *
JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type)
@ -525,7 +271,8 @@ JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::Initi
MOZ_ASSERT_IF(type->clasp()->finalize, heap == js::gc::TenuredHeap);
const js::Class *clasp = type->clasp();
size_t nDynamicSlots = dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp);
size_t nDynamicSlots =
js::NativeObject::dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp);
JSObject *obj = js::NewGCObject<js::CanGC>(cx, kind, nDynamicSlots, heap);
if (!obj)
@ -534,157 +281,32 @@ JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::Initi
obj->shape_.init(shape);
obj->type_.init(type);
// Note: slots are created and assigned internally by NewGCObject.
obj->elements = js::emptyObjectElements;
obj->fakeNativeElements() = js::emptyObjectElements;
if (clasp->hasPrivate())
obj->privateRef(shape->numFixedSlots()) = nullptr;
obj->fakeNativePrivateRef(shape->numFixedSlots()) = nullptr;
size_t span = shape->slotSpan();
if (span)
obj->initializeSlotRange(0, span);
obj->fakeNativeInitializeSlotRange(0, span);
// JSFunction's fixed slots expect POD-style initialization.
if (type->clasp()->isJSFunction())
memset(obj->fixedSlots(), 0, sizeof(js::HeapSlot) * GetGCKindSlots(kind));
memset(obj->as<JSFunction>().fixedSlots(), 0, sizeof(js::HeapSlot) * GetGCKindSlots(kind));
js::gc::TraceCreateObject(obj);
return obj;
}
/* static */ inline JSObject *
JSObject::copy(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleObject templateObject)
{
js::RootedShape shape(cx, templateObject->lastProperty());
js::RootedTypeObject type(cx, templateObject->type());
MOZ_ASSERT(!templateObject->denseElementsAreCopyOnWrite());
JSObject *obj = create(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
size_t span = shape->slotSpan();
if (span) {
uint32_t numFixed = templateObject->numFixedSlots();
const js::Value *fixed = &templateObject->getSlot(0);
MOZ_ASSERT(numFixed <= span);
obj->copySlotRange(0, fixed, numFixed);
if (numFixed < span) {
uint32_t numSlots = span - numFixed;
const js::Value *slots = &templateObject->getSlot(numFixed);
obj->copySlotRange(numFixed, slots, numSlots);
}
}
return obj;
}
/* static */ inline JSObject *
JSObject::createArrayInternal(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type)
{
// Create a new array and initialize everything except for its elements.
MOZ_ASSERT(shape && type);
MOZ_ASSERT(type->clasp() == shape->getObjectClass());
MOZ_ASSERT(type->clasp() == &js::ArrayObject::class_);
MOZ_ASSERT_IF(type->clasp()->finalize, heap == js::gc::TenuredHeap);
// Arrays can use their fixed slots to store elements, so can't have shapes
// which allow named properties to be stored in the fixed slots.
MOZ_ASSERT(shape->numFixedSlots() == 0);
size_t nDynamicSlots = dynamicSlotsCount(0, shape->slotSpan(), type->clasp());
JSObject *obj = js::NewGCObject<js::CanGC>(cx, kind, nDynamicSlots, heap);
if (!obj)
return nullptr;
obj->shape_.init(shape);
obj->type_.init(type);
return obj;
}
/* static */ inline js::ArrayObject *
JSObject::finishCreateArray(JSObject *obj, js::HandleShape shape)
{
size_t span = shape->slotSpan();
if (span)
obj->initializeSlotRange(0, span);
js::gc::TraceCreateObject(obj);
return &obj->as<js::ArrayObject>();
}
/* static */ inline js::ArrayObject *
JSObject::createArray(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type,
uint32_t length)
{
JSObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
uint32_t capacity = js::gc::GetGCKindSlots(kind) - js::ObjectElements::VALUES_PER_HEADER;
obj->setFixedElements();
new (obj->getElementsHeader()) js::ObjectElements(capacity, length);
return finishCreateArray(obj, shape);
}
/* static */ inline js::ArrayObject *
JSObject::createArray(js::ExclusiveContext *cx, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type,
js::HeapSlot *elements)
{
// Use the smallest allocation kind for the array, as it can't have any
// fixed slots (see the assert in createArrayInternal) and will not be using
// its fixed elements.
js::gc::AllocKind kind = js::gc::FINALIZE_OBJECT0_BACKGROUND;
JSObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
obj->elements = elements;
return finishCreateArray(obj, shape);
}
/* static */ inline js::ArrayObject *
JSObject::createCopyOnWriteArray(js::ExclusiveContext *cx, js::gc::InitialHeap heap,
js::HandleShape shape,
js::HandleObject sharedElementsOwner)
{
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->isCopyOnWrite());
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->ownerObject() == sharedElementsOwner);
// Use the smallest allocation kind for the array, as it can't have any
// fixed slots (see the assert in createArrayInternal) and will not be using
// its fixed elements.
js::gc::AllocKind kind = js::gc::FINALIZE_OBJECT0_BACKGROUND;
js::RootedTypeObject type(cx, sharedElementsOwner->type());
JSObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
obj->elements = sharedElementsOwner->getDenseElementsAllowCopyOnWrite();
return finishCreateArray(obj, shape);
}
inline void
JSObject::finish(js::FreeOp *fop)
{
if (hasDynamicSlots())
fop->free_(slots);
if (fakeNativeHasDynamicSlots())
fop->free_(fakeNativeSlots());
if (hasDynamicElements()) {
js::ObjectElements *elements = getElementsHeader();
if (fakeNativeHasDynamicElements()) {
js::ObjectElements *elements = fakeNativeGetElementsHeader();
if (elements->isCopyOnWrite()) {
if (elements->ownerObject() == this) {
// Don't free the elements until object finalization finishes,
@ -718,31 +340,6 @@ JSObject::hasProperty(JSContext *cx, js::HandleObject obj,
return true;
}
inline bool
JSObject::nativeSetSlotIfHasType(js::Shape *shape, const js::Value &value, bool overwriting)
{
if (!js::types::HasTypePropertyId(this, shape->propid(), value))
return false;
nativeSetSlot(shape->slot(), value);
if (overwriting)
shape->setOverwritten();
return true;
}
inline void
JSObject::nativeSetSlotWithType(js::ExclusiveContext *cx, js::Shape *shape,
const js::Value &value, bool overwriting)
{
nativeSetSlot(shape->slot(), value);
if (overwriting)
shape->setOverwritten();
js::types::AddTypePropertyId(cx, this, shape->propid(), value);
}
/* static */ inline bool
JSObject::getElement(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
uint32_t index, js::MutableHandleValue vp)
@ -855,15 +452,14 @@ IsNativeFunction(const js::Value &v, JSNative native)
* TODO: a per-thread shape-based cache would be faster and simpler.
*/
static MOZ_ALWAYS_INLINE bool
ClassMethodIsNative(JSContext *cx, JSObject *obj, const Class *clasp, jsid methodid, JSNative native)
ClassMethodIsNative(JSContext *cx, NativeObject *obj, const Class *clasp, jsid methodid, JSNative native)
{
MOZ_ASSERT(!obj->is<ProxyObject>());
MOZ_ASSERT(obj->getClass() == clasp);
Value v;
if (!HasDataProperty(cx, obj, methodid, &v)) {
JSObject *proto = obj->getProto();
if (!proto || proto->getClass() != clasp || !HasDataProperty(cx, proto, methodid, &v))
if (!proto || proto->getClass() != clasp || !HasDataProperty(cx, &proto->as<NativeObject>(), methodid, &v))
return false;
}
@ -882,7 +478,7 @@ HasObjectValueOf(JSObject *obj, JSContext *cx)
jsid valueOf = NameToId(cx->names().valueOf);
Value v;
while (!HasDataProperty(cx, obj, valueOf, &v)) {
while (!HasDataProperty(cx, &obj->as<NativeObject>(), valueOf, &v)) {
obj = obj->getProto();
if (!obj || obj->is<ProxyObject>() || !obj->isNative())
return false;
@ -903,8 +499,9 @@ ToPrimitive(JSContext *cx, MutableHandleValue vp)
/* Optimize new String(...).valueOf(). */
if (obj->is<StringObject>()) {
jsid id = NameToId(cx->names().valueOf);
if (ClassMethodIsNative(cx, obj, &StringObject::class_, id, js_str_toString)) {
vp.setString(obj->as<StringObject>().unbox());
StringObject *nobj = &obj->as<StringObject>();
if (ClassMethodIsNative(cx, nobj, &StringObject::class_, id, js_str_toString)) {
vp.setString(nobj->unbox());
return true;
}
}
@ -912,8 +509,9 @@ ToPrimitive(JSContext *cx, MutableHandleValue vp)
/* Optimize new Number(...).valueOf(). */
if (obj->is<NumberObject>()) {
jsid id = NameToId(cx->names().valueOf);
if (ClassMethodIsNative(cx, obj, &NumberObject::class_, id, js_num_valueOf)) {
vp.setNumber(obj->as<NumberObject>().unbox());
NumberObject *nobj = &obj->as<NumberObject>();
if (ClassMethodIsNative(cx, nobj, &NumberObject::class_, id, js_num_valueOf)) {
vp.setNumber(nobj->unbox());
return true;
}
}
@ -1090,31 +688,6 @@ NewBuiltinClassInstance(ExclusiveContext *cx, gc::AllocKind allocKind, NewObject
bool
NewObjectScriptedCall(JSContext *cx, MutableHandleObject obj);
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
static inline JSObject *
CopyInitializerObject(JSContext *cx, HandleObject baseobj, NewObjectKind newKind = GenericObject)
{
MOZ_ASSERT(baseobj->getClass() == &JSObject::class_);
MOZ_ASSERT(!baseobj->inDictionaryMode());
gc::AllocKind allocKind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
allocKind = gc::GetBackgroundAllocKind(allocKind);
MOZ_ASSERT_IF(baseobj->isTenured(), allocKind == baseobj->asTenured().getAllocKind());
RootedObject obj(cx);
obj = NewBuiltinClassInstance(cx, &JSObject::class_, allocKind, newKind);
if (!obj)
return nullptr;
RootedObject metadata(cx, obj->getMetadata());
RootedShape lastProp(cx, baseobj->lastProperty());
if (!JSObject::setLastProperty(cx, obj, lastProp))
return nullptr;
if (metadata && !JSObject::setMetadata(cx, obj, metadata))
return nullptr;
return obj;
}
JSObject *
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject);
@ -1225,7 +798,8 @@ NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
}
inline bool
DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj,
PropertyName *name, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
Rooted<jsid> id(cx, NameToId(name));
@ -1235,7 +809,7 @@ DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name,
namespace baseops {
inline bool
LookupProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name,
LookupProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
MutableHandleObject objp, MutableHandleShape propp)
{
Rooted<jsid> id(cx, NameToId(name));
@ -1243,7 +817,7 @@ LookupProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name,
}
inline bool
DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
DefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name, HandleValue value,
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
{
Rooted<jsid> id(cx, NameToId(name));
@ -1254,12 +828,12 @@ DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, Handl
} /* namespace js */
extern JSObject *
extern js::NativeObject *
js_InitClass(JSContext *cx, js::HandleObject obj, JSObject *parent_proto,
const js::Class *clasp, JSNative constructor, unsigned nargs,
const JSPropertySpec *ps, const JSFunctionSpec *fs,
const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs,
JSObject **ctorp = nullptr,
js::NativeObject **ctorp = nullptr,
js::gc::AllocKind ctorKind = JSFunction::FinalizeKind);
#endif /* jsobjinlines_h */

Просмотреть файл

@ -24,7 +24,8 @@
#include "jsatominlines.h"
#include "jsboolinlines.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::gc;
@ -565,7 +566,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
uint32_t len;
JS_ALWAYS_TRUE(GetLengthProperty(cx, replacer, &len));
if (replacer->is<ArrayObject>() && !replacer->isIndexed())
len = Min(len, replacer->getDenseInitializedLength());
len = Min(len, replacer->as<ArrayObject>().getDenseInitializedLength());
// Cap the initial size to a moderately small value. This avoids
// ridiculous over-allocation if an array with bogusly-huge length
@ -662,7 +663,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
}
/* Step 9. */
RootedObject wrapper(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedNativeObject wrapper(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_));
if (!wrapper)
return false;

Просмотреть файл

@ -18,7 +18,7 @@
#include "vm/StringBuffer.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
@ -596,7 +596,7 @@ JSONParserBase::createFinishedObject(PropertyVector &properties)
* shape in manually.
*/
gc::AllocKind allocKind = gc::GetGCObjectKind(properties.length());
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
if (!obj)
return nullptr;
@ -643,7 +643,7 @@ JSONParserBase::finishArray(MutableHandleValue vp, ElementVector &elements)
{
MOZ_ASSERT(&elements == &stack.back().elements());
JSObject *obj = NewDenseCopiedArray(cx, elements.length(), elements.begin());
ArrayObject *obj = NewDenseCopiedArray(cx, elements.length(), elements.begin());
if (!obj)
return false;

Просмотреть файл

@ -423,9 +423,9 @@ js::XDRScriptConst(XDRState<mode> *xdr, MutableHandleValue vp)
vp.set(NullValue());
break;
case SCRIPT_OBJECT: {
RootedObject obj(cx);
RootedNativeObject obj(cx);
if (mode == XDR_ENCODE)
obj = &vp.toObject();
obj = &vp.toObject().as<NativeObject>();
if (!XDRObjectLiteral(xdr, &obj))
return false;
@ -533,7 +533,7 @@ static inline uint32_t
FindScopeObjectIndex(JSScript *script, NestedScopeObject &scope)
{
ObjectArray *objects = script->objects();
HeapPtrObject *vector = objects->vector;
HeapPtrNativeObject *vector = objects->vector;
unsigned length = objects->length;
for (unsigned i = 0; i < length; ++i) {
if (vector[i] == &scope)
@ -892,7 +892,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
* after the enclosing block has been XDR'd.
*/
for (i = 0; i != nobjects; ++i) {
HeapPtrObject *objp = &script->objects()->vector[i];
HeapPtrNativeObject *objp = &script->objects()->vector[i];
XDRClassKind classk;
if (mode == XDR_ENCODE) {
@ -988,7 +988,9 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
}
// Code nested function and script.
RootedObject tmp(cx, *objp);
RootedFunction tmp(cx);
if (mode == XDR_ENCODE)
tmp = &(*objp)->as<JSFunction>();
if (!XDRInterpretedFunction(xdr, funEnclosingScope, script, &tmp))
return false;
*objp = tmp;
@ -997,7 +999,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
case CK_JSObject: {
/* Code object literal. */
RootedObject tmp(cx, *objp);
RootedNativeObject tmp(cx, *objp);
if (!XDRObjectLiteral(xdr, &tmp))
return false;
*objp = tmp;
@ -1012,8 +1014,13 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
}
for (i = 0; i != nregexps; ++i) {
if (!XDRScriptRegExpObject(xdr, &script->regexps()->vector[i]))
Rooted<RegExpObject*> regexp(cx);
if (mode == XDR_ENCODE)
regexp = &script->regexps()->vector[i]->as<RegExpObject>();
if (!XDRScriptRegExpObject(xdr, &regexp))
return false;
if (mode == XDR_DECODE)
script->regexps()->vector[i] = regexp;
}
if (ntrynotes != 0) {
@ -1117,7 +1124,7 @@ js::XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript
// Code inner functions.
{
RootedObject func(cx);
RootedFunction func(cx);
HeapPtrFunction *innerFunctions = lazy->innerFunctions();
size_t numInnerFunctions = lazy->numInnerFunctions();
for (size_t i = 0; i < numInnerFunctions; i++) {
@ -1128,7 +1135,7 @@ js::XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript
return false;
if (mode == XDR_DECODE)
innerFunctions[i] = &func->as<JSFunction>();
innerFunctions[i] = func;
}
}
@ -2330,9 +2337,9 @@ ScriptDataSize(uint32_t nbindings, uint32_t nconsts, uint32_t nobjects, uint32_t
if (nconsts != 0)
size += sizeof(ConstArray) + nconsts * sizeof(Value);
if (nobjects != 0)
size += sizeof(ObjectArray) + nobjects * sizeof(JSObject *);
size += sizeof(ObjectArray) + nobjects * sizeof(NativeObject *);
if (nregexps != 0)
size += sizeof(ObjectArray) + nregexps * sizeof(JSObject *);
size += sizeof(ObjectArray) + nregexps * sizeof(NativeObject *);
if (ntrynotes != 0)
size += sizeof(TryNoteArray) + ntrynotes * sizeof(JSTryNote);
if (nblockscopes != 0)
@ -2456,13 +2463,13 @@ JSScript::partiallyInit(ExclusiveContext *cx, HandleScript script, uint32_t ncon
if (nobjects != 0) {
script->objects()->length = nobjects;
script->objects()->vector = (HeapPtrObject *)cursor;
script->objects()->vector = (HeapPtrNativeObject *)cursor;
cursor += nobjects * sizeof(script->objects()->vector[0]);
}
if (nregexps != 0) {
script->regexps()->length = nregexps;
script->regexps()->vector = (HeapPtrObject *)cursor;
script->regexps()->vector = (HeapPtrNativeObject *)cursor;
cursor += nregexps * sizeof(script->regexps()->vector[0]);
}
@ -2943,7 +2950,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
AutoObjectVector objects(cx);
if (nobjects != 0) {
HeapPtrObject *vector = src->objects()->vector;
HeapPtrNativeObject *vector = src->objects()->vector;
for (unsigned i = 0; i < nobjects; i++) {
RootedObject obj(cx, vector[i]);
RootedObject clone(cx);
@ -2998,7 +3005,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
AutoObjectVector regexps(cx);
for (unsigned i = 0; i < nregexps; i++) {
HeapPtrObject *vector = src->regexps()->vector;
HeapPtrNativeObject *vector = src->regexps()->vector;
for (unsigned i = 0; i < nregexps; i++) {
JSObject *clone = CloneScriptRegExpObject(cx, vector[i]->as<RegExpObject>());
if (!clone || !regexps.append(clone))
@ -3093,16 +3100,16 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
MOZ_ASSERT_IF(vector[i].isMarkable(), vector[i].toString()->isAtom());
}
if (nobjects != 0) {
HeapPtrObject *vector = Rebase<HeapPtrObject>(dst, src, src->objects()->vector);
HeapPtrNativeObject *vector = Rebase<HeapPtrNativeObject>(dst, src, src->objects()->vector);
dst->objects()->vector = vector;
for (unsigned i = 0; i < nobjects; ++i)
vector[i].init(objects[i]);
vector[i].init(&objects[i]->as<NativeObject>());
}
if (nregexps != 0) {
HeapPtrObject *vector = Rebase<HeapPtrObject>(dst, src, src->regexps()->vector);
HeapPtrNativeObject *vector = Rebase<HeapPtrNativeObject>(dst, src, src->regexps()->vector);
dst->regexps()->vector = vector;
for (unsigned i = 0; i < nregexps; ++i)
vector[i].init(regexps[i]);
vector[i].init(&regexps[i]->as<NativeObject>());
}
if (ntrynotes != 0)
dst->trynotes()->vector = Rebase<JSTryNote>(dst, src, src->trynotes()->vector);

Просмотреть файл

@ -15,7 +15,6 @@
#include "jsatom.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jstypes.h"
@ -23,6 +22,7 @@
#include "gc/Rooting.h"
#include "jit/IonCode.h"
#include "js/UbiNode.h"
#include "vm/ObjectImpl.h"
#include "vm/Shape.h"
namespace JS {
@ -113,8 +113,8 @@ struct ConstArray {
};
struct ObjectArray {
js::HeapPtrObject *vector; // Array of indexed objects.
uint32_t length; // Count of indexed objects.
js::HeapPtrNativeObject *vector; // Array of indexed objects.
uint32_t length; // Count of indexed objects.
};
struct TryNoteArray {
@ -651,7 +651,7 @@ struct CompressedSourceHasher
typedef HashSet<ScriptSource *, CompressedSourceHasher, SystemAllocPolicy> CompressedSourceSet;
class ScriptSourceObject : public JSObject
class ScriptSourceObject : public NativeObject
{
public:
static const Class class_;
@ -1545,7 +1545,7 @@ class JSScript : public js::gc::TenuredCell
return getAtom(GET_UINT32_INDEX(pc))->asPropertyName();
}
JSObject *getObject(size_t index) {
js::NativeObject *getObject(size_t index) {
js::ObjectArray *arr = objects();
MOZ_ASSERT(index < arr->length);
return arr->vector[index];
@ -1556,7 +1556,7 @@ class JSScript : public js::gc::TenuredCell
return savedCallerFun() ? 1 : 0;
}
JSObject *getObject(jsbytecode *pc) {
js::NativeObject *getObject(jsbytecode *pc) {
MOZ_ASSERT(containsPC(pc) && containsPC(pc + sizeof(uint32_t)));
return getObject(GET_UINT32_INDEX(pc));
}

Просмотреть файл

@ -452,9 +452,10 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
if (call.thisv().isObject()) {
RootedObject obj(cx, &call.thisv().toObject());
if (obj->is<StringObject>()) {
StringObject *nobj = &obj->as<StringObject>();
Rooted<jsid> id(cx, NameToId(cx->names().toString));
if (ClassMethodIsNative(cx, obj, &StringObject::class_, id, js_str_toString)) {
JSString *str = obj->as<StringObject>().unbox();
if (ClassMethodIsNative(cx, nobj, &StringObject::class_, id, js_str_toString)) {
JSString *str = nobj->unbox();
call.setThis(StringValue(str));
return str;
}
@ -2257,9 +2258,12 @@ class MOZ_STACK_CLASS StringRegExpGuard
// Use a fast path for same-global RegExp objects with writable
// lastIndex.
if (obj_->is<RegExpObject>() && obj_->nativeLookup(cx, cx->names().lastIndex)->writable()) {
obj_->as<RegExpObject>().zeroLastIndex();
return true;
if (obj_->is<RegExpObject>()) {
RegExpObject *nobj = &obj_->as<RegExpObject>();
if (nobj->lookup(cx, cx->names().lastIndex)->writable()) {
nobj->zeroLastIndex();
return true;
}
}
// Handle everything else generically (including throwing if .lastIndex is non-writable).
@ -2591,7 +2595,7 @@ struct ReplaceData
RootedString str; /* 'this' parameter object as a string */
StringRegExpGuard g; /* regexp parameter object and private data */
RootedObject lambda; /* replacement function object or null */
RootedObject elembase; /* object for function(a){return b[a]} replace */
RootedNativeObject elembase; /* object for function(a){return b[a]} replace */
RootedLinearString repstr; /* replacement string */
uint32_t dollarIndex; /* index of first $ in repstr, or UINT32_MAX */
int leftIndex; /* left context index in str->chars */
@ -3501,7 +3505,7 @@ str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, c
* code patterns generated by such packers here.
*/
static bool
LambdaIsGetElem(JSContext *cx, JSObject &lambda, MutableHandleObject pobj)
LambdaIsGetElem(JSContext *cx, JSObject &lambda, MutableHandleNativeObject pobj)
{
if (!lambda.is<JSFunction>())
return true;
@ -3553,7 +3557,7 @@ LambdaIsGetElem(JSContext *cx, JSObject &lambda, MutableHandleObject pobj)
if (!clasp->isNative() || clasp->ops.lookupProperty || clasp->ops.getProperty)
return true;
pobj.set(&bobj);
pobj.set(&bobj.as<NativeObject>());
return true;
}
@ -4303,7 +4307,7 @@ static const JSFunctionSpec string_static_methods[] = {
/* static */ Shape *
StringObject::assignInitialShape(ExclusiveContext *cx, Handle<StringObject*> obj)
{
MOZ_ASSERT(obj->nativeEmpty());
MOZ_ASSERT(obj->empty());
return obj->addDataProperty(cx, cx->names().length, LENGTH_SLOT,
JSPROP_PERMANENT | JSPROP_READONLY);

Просмотреть файл

@ -129,9 +129,10 @@ WatchpointMap::triggerWatchpoint(JSContext *cx, HandleObject obj, HandleId id, M
Value old;
old.setUndefined();
if (obj->isNative()) {
if (Shape *shape = obj->nativeLookup(cx, id)) {
NativeObject *nobj = &obj->as<NativeObject>();
if (Shape *shape = nobj->lookup(cx, id)) {
if (shape->hasSlot())
old = obj->nativeGetSlot(shape->slot());
old = nobj->getSlot(shape->slot());
}
}

Просмотреть файл

@ -271,7 +271,7 @@ ExtractPerfMeasurement(jsval wrapper)
if (obj->getClass() != js::Valueify(&pm_class))
return 0;
return (PerfMeasurement*) obj->getPrivate();
return (PerfMeasurement*) obj->as<js::NativeObject>().getPrivate();
}
} // namespace JS

Просмотреть файл

@ -868,9 +868,9 @@ ProxyObject::renew(JSContext *cx, const BaseProxyHandler *handler, Value priv)
MOZ_ASSERT(getTaggedProto().isLazy());
setHandler(handler);
setCrossCompartmentSlot(PRIVATE_SLOT, priv);
setSlot(EXTRA_SLOT + 0, UndefinedValue());
setSlot(EXTRA_SLOT + 1, UndefinedValue());
fakeNativeSetCrossCompartmentSlot(PRIVATE_SLOT, priv);
fakeNativeSetSlot(EXTRA_SLOT + 0, UndefinedValue());
fakeNativeSetSlot(EXTRA_SLOT + 1, UndefinedValue());
}
JS_FRIEND_API(JSObject *)

Просмотреть файл

@ -346,7 +346,7 @@ ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, un
"object");
return nullptr;
}
RootedObject obj(cx, &proxy->as<ProxyObject>().extra(0).toObject().getReservedSlot(0).toObject());
RootedObject obj(cx, &proxy->as<ProxyObject>().extra(0).toObject().as<NativeObject>().getReservedSlot(0).toObject());
return fun_toStringHelper(cx, obj, indent);
}
@ -358,7 +358,7 @@ CallableScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, co
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
RootedObject ccHolder(cx, &proxy->as<ProxyObject>().extra(0).toObject());
MOZ_ASSERT(ccHolder->getClass() == &CallConstructHolder);
RootedValue call(cx, ccHolder->getReservedSlot(0));
RootedValue call(cx, ccHolder->as<NativeObject>().getReservedSlot(0));
MOZ_ASSERT(call.isObject() && call.toObject().isCallable());
return Invoke(cx, args.thisv(), call, args.length(), args.array(), args.rval());
}
@ -369,7 +369,7 @@ CallableScriptedIndirectProxyHandler::construct(JSContext *cx, HandleObject prox
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
RootedObject ccHolder(cx, &proxy->as<ProxyObject>().extra(0).toObject());
MOZ_ASSERT(ccHolder->getClass() == &CallConstructHolder);
RootedValue construct(cx, ccHolder->getReservedSlot(1));
RootedValue construct(cx, ccHolder->as<NativeObject>().getReservedSlot(1));
MOZ_ASSERT(construct.isObject() && construct.toObject().isCallable());
return InvokeConstructor(cx, construct, args.length(), args.array(), args.rval());
}
@ -445,8 +445,8 @@ js::proxy_createFunction(JSContext *cx, unsigned argc, Value *vp)
js::NullPtr(), cx->global()));
if (!ccHolder)
return false;
ccHolder->setReservedSlot(0, ObjectValue(*call));
ccHolder->setReservedSlot(1, ObjectValue(*construct));
ccHolder->as<NativeObject>().setReservedSlot(0, ObjectValue(*call));
ccHolder->as<NativeObject>().setReservedSlot(1, ObjectValue(*construct));
RootedValue priv(cx, ObjectValue(*handler));
JSObject *proxy =

Просмотреть файл

@ -2802,7 +2802,7 @@ ShapeOf(JSContext *cx, unsigned argc, JS::Value *vp)
* non-native referent may be simplified to data properties.
*/
static bool
CopyProperty(JSContext *cx, HandleObject obj, HandleObject referent, HandleId id,
CopyProperty(JSContext *cx, HandleNativeObject obj, HandleObject referent, HandleId id,
MutableHandleObject objp)
{
RootedShape shape(cx);
@ -2811,13 +2811,13 @@ CopyProperty(JSContext *cx, HandleObject obj, HandleObject referent, HandleId id
objp.set(nullptr);
if (referent->isNative()) {
if (!LookupNativeProperty(cx, referent, id, &obj2, &shape))
if (!LookupNativeProperty(cx, referent.as<NativeObject>(), id, &obj2, &shape))
return false;
if (obj2 != referent)
return true;
if (shape->hasSlot()) {
desc.value().set(referent->nativeGetSlot(shape->slot()));
desc.value().set(referent->as<NativeObject>().getSlot(shape->slot()));
} else {
desc.value().setUndefined();
}
@ -2861,7 +2861,7 @@ resolver_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObje
{
jsval v = JS_GetReservedSlot(obj, 0);
Rooted<JSObject*> vobj(cx, &v.toObject());
return CopyProperty(cx, obj, vobj, id, objp);
return CopyProperty(cx, obj.as<NativeObject>(), vobj, id, objp);
}
static bool
@ -2875,7 +2875,7 @@ resolver_enumerate(JSContext *cx, HandleObject obj)
RootedObject ignore(cx);
for (size_t i = 0; ok && i < ida.length(); i++) {
Rooted<jsid> id(cx, ida[i]);
ok = CopyProperty(cx, obj, referent, id, &ignore);
ok = CopyProperty(cx, obj.as<NativeObject>(), referent, id, &ignore);
}
return ok;
}

Просмотреть файл

@ -34,7 +34,7 @@ CopyStackFrameArguments(const AbstractFramePtr frame, HeapValue *dst, unsigned t
}
/* static */ void
ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame, JSObject *obj,
ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame, ArgumentsObject *obj,
ArgumentsData *data)
{
JSScript *script = frame.script();
@ -47,7 +47,7 @@ ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame, JSObject *obj,
/* static */ void
ArgumentsObject::MaybeForwardToCallObject(jit::IonJSFrameLayout *frame, HandleObject callObj,
JSObject *obj, ArgumentsData *data)
ArgumentsObject *obj, ArgumentsData *data)
{
JSFunction *callee = jit::CalleeTokenToFunction(frame->calleeToken());
JSScript *script = callee->nonLazyScript();
@ -75,7 +75,7 @@ struct CopyFrameArgs
* If a call object exists and the arguments object aliases formals, the
* call object is the canonical location for formals.
*/
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
void maybeForwardToCallObject(ArgumentsObject *obj, ArgumentsData *data) {
ArgumentsObject::MaybeForwardToCallObject(frame_, obj, data);
}
};
@ -114,7 +114,7 @@ struct CopyIonJSFrameArgs
* If a call object exists and the arguments object aliases formals, the
* call object is the canonical location for formals.
*/
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
void maybeForwardToCallObject(ArgumentsObject *obj, ArgumentsData *data) {
ArgumentsObject::MaybeForwardToCallObject(frame_, callObj_, obj, data);
}
};
@ -149,7 +149,7 @@ struct CopyScriptFrameIterArgs
* Ion frames are copying every argument onto the stack, other locations are
* invalid.
*/
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
void maybeForwardToCallObject(ArgumentsObject *obj, ArgumentsData *data) {
if (!iter_.isIon())
ArgumentsObject::MaybeForwardToCallObject(iter_.abstractFramePtr(), obj, data);
}
@ -193,8 +193,10 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
if (!data)
return nullptr;
RootedObject obj(cx);
obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp), shape, type);
RootedNativeObject obj(cx);
obj = MaybeNativeObject(JSObject::create(cx, FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp),
shape, type));
if (!obj) {
js_free(data);
return nullptr;
@ -220,7 +222,7 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));
copy.maybeForwardToCallObject(obj, data);
copy.maybeForwardToCallObject(&obj->as<ArgumentsObject>(), data);
ArgumentsObject &argsobj = obj->as<ArgumentsObject>();
MOZ_ASSERT(argsobj.initialLength() == numActuals);
@ -321,20 +323,20 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHand
{
if (!obj->is<NormalArgumentsObject>())
return true;
Handle<NormalArgumentsObject*> argsobj = obj.as<NormalArgumentsObject>();
unsigned attrs;
if (!baseops::GetAttributes(cx, obj, id, &attrs))
if (!baseops::GetAttributes(cx, argsobj, id, &attrs))
return false;
MOZ_ASSERT(!(attrs & JSPROP_READONLY));
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
NormalArgumentsObject &argsobj = obj->as<NormalArgumentsObject>();
RootedScript script(cx, argsobj.containingScript());
RootedScript script(cx, argsobj->containingScript());
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));
if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg)) {
argsobj.setElement(cx, arg, vp);
if (arg < argsobj->initialLength() && !argsobj->isElementDeleted(arg)) {
argsobj->setElement(cx, arg, vp);
if (arg < script->functionNonDelazifying()->nargs())
types::TypeScript::SetArgument(cx, script, arg, vp);
return true;
@ -352,8 +354,8 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHand
* that has a setter for this id.
*/
bool succeeded;
return baseops::DeleteGeneric(cx, obj, id, &succeeded) &&
baseops::DefineGeneric(cx, obj, id, vp, nullptr, nullptr, attrs);
return baseops::DeleteGeneric(cx, argsobj, id, &succeeded) &&
baseops::DefineGeneric(cx, argsobj, id, vp, nullptr, nullptr, attrs);
}
static bool
@ -443,15 +445,14 @@ StrictArgSetter(JSContext *cx, HandleObject obj, HandleId id, bool strict, Mutab
{
if (!obj->is<StrictArgumentsObject>())
return true;
Handle<StrictArgumentsObject*> argsobj = obj.as<StrictArgumentsObject>();
unsigned attrs;
if (!baseops::GetAttributes(cx, obj, id, &attrs))
if (!baseops::GetAttributes(cx, argsobj, id, &attrs))
return false;
MOZ_ASSERT(!(attrs & JSPROP_READONLY));
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
Rooted<StrictArgumentsObject*> argsobj(cx, &obj->as<StrictArgumentsObject>());
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));
if (arg < argsobj->initialLength()) {

Просмотреть файл

@ -9,9 +9,8 @@
#include "mozilla/MemoryReporting.h"
#include "jsobj.h"
#include "gc/Barrier.h"
#include "vm/ObjectImpl.h"
namespace js {
@ -108,7 +107,7 @@ static const unsigned ARGS_LENGTH_MAX = 500 * 1000;
* DATA_SLOT
* Stores an ArgumentsData*, described above.
*/
class ArgumentsObject : public JSObject
class ArgumentsObject : public NativeObject
{
protected:
static const uint32_t INITIAL_LENGTH_SLOT = 0;
@ -271,9 +270,10 @@ class ArgumentsObject : public JSObject
return getFixedSlotOffset(INITIAL_LENGTH_SLOT);
}
static void MaybeForwardToCallObject(AbstractFramePtr frame, JSObject *obj, ArgumentsData *data);
static void MaybeForwardToCallObject(AbstractFramePtr frame, ArgumentsObject *obj,
ArgumentsData *data);
static void MaybeForwardToCallObject(jit::IonJSFrameLayout *frame, HandleObject callObj,
JSObject *obj, ArgumentsData *data);
ArgumentsObject *obj, ArgumentsData *data);
};
class NormalArgumentsObject : public ArgumentsObject

Просмотреть файл

@ -48,6 +48,7 @@
#include "jsinferinlines.h"
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Shape-inl.h"
using mozilla::DebugOnly;
@ -347,7 +348,7 @@ ArrayBufferObject::changeViewContents(JSContext *cx, ArrayBufferViewObject *view
MOZ_ASSERT(newContents);
ptrdiff_t offset = viewDataPointer - oldDataPointer;
viewDataPointer = static_cast<uint8_t *>(newContents.data()) + offset;
view->setPrivate(viewDataPointer);
view->fakeNativeSetPrivate(viewDataPointer);
}
// Notify compiled jit code that the base pointer has moved.
@ -598,7 +599,7 @@ ArrayBufferObject::create(JSContext *cx, uint32_t nbytes, BufferContents content
nAllocated = JS_ROUNDUP(nbytes, js::gc::SystemPageSize());
cx->zone()->updateMallocCounter(nAllocated);
} else {
size_t usableSlots = JSObject::MAX_FIXED_SLOTS - reservedSlots;
size_t usableSlots = NativeObject::MAX_FIXED_SLOTS - reservedSlots;
if (nbytes <= usableSlots * sizeof(Value)) {
int newSlots = (nbytes - 1) / sizeof(Value) + 1;
MOZ_ASSERT(int(nbytes) <= newSlots * int(sizeof(Value)));
@ -797,8 +798,13 @@ ArrayBufferObject::setFirstView(ArrayBufferViewObject *view)
}
bool
ArrayBufferObject::addView(JSContext *cx, ArrayBufferViewObject *view)
ArrayBufferObject::addView(JSContext *cx, JSObject *viewArg)
{
// Note: we don't pass in an ArrayBufferViewObject as the argument due to
// tricky inheritance in the various view classes. View classes do not
// inherit from ArrayBufferViewObject so won't be upcast automatically.
ArrayBufferViewObject *view = &viewArg->as<ArrayBufferViewObject>();
if (!firstView()) {
setFirstView(view);
return true;
@ -965,8 +971,9 @@ InnerViewTable::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
* stores its data inline.
*/
/* static */ void
ArrayBufferViewObject::trace(JSTracer *trc, JSObject *obj)
ArrayBufferViewObject::trace(JSTracer *trc, JSObject *objArg)
{
NativeObject *obj = &objArg->as<NativeObject>();
HeapSlot &bufSlot = obj->getReservedSlotRef(TypedArrayLayout::BUFFER_SLOT);
MarkSlot(trc, &bufSlot, "typedarray.buffer");

Просмотреть файл

@ -63,7 +63,7 @@ uint32_t AnyArrayBufferByteLength(const ArrayBufferObjectMaybeShared *buf);
uint8_t *AnyArrayBufferDataPointer(const ArrayBufferObjectMaybeShared *buf);
ArrayBufferObjectMaybeShared &AsAnyArrayBuffer(HandleValue val);
class ArrayBufferObjectMaybeShared : public JSObject
class ArrayBufferObjectMaybeShared : public NativeObject
{
public:
uint32_t byteLength() {
@ -224,7 +224,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
// and non-incrementalized sweep time.
ArrayBufferViewObject *firstView();
bool addView(JSContext *cx, ArrayBufferViewObject *view);
bool addView(JSContext *cx, JSObject *view);
void setNewOwnedData(FreeOp* fop, BufferContents newContents);
void changeContents(JSContext *cx, BufferContents newContents);
@ -325,7 +325,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
/*
* ArrayBufferViewObject
*
* Common definitions shared by all ArrayBufferViews.
* Common definitions shared by all array buffer views.
*/
class ArrayBufferViewObject : public JSObject
@ -355,7 +355,7 @@ PostBarrierTypedArrayObject(JSObject *obj)
}
inline void
InitArrayBufferViewDataPointer(ArrayBufferViewObject *obj, ArrayBufferObject *buffer, size_t byteOffset)
InitArrayBufferViewDataPointer(JSObject *obj, ArrayBufferObject *buffer, size_t byteOffset)
{
/*
* N.B. The base of the array's data is stored in the object's
@ -363,7 +363,7 @@ InitArrayBufferViewDataPointer(ArrayBufferViewObject *obj, ArrayBufferObject *bu
* private Values that are pointers must have the low bits clear.
*/
MOZ_ASSERT(buffer->dataPointer() != nullptr);
obj->initPrivate(buffer->dataPointer() + byteOffset);
obj->as<NativeObject>().initPrivate(buffer->dataPointer() + byteOffset);
PostBarrierTypedArrayObject(obj);
}

Просмотреть файл

@ -28,7 +28,102 @@ ArrayObject::setLength(ExclusiveContext *cx, uint32_t length)
getElementsHeader()->length = length;
}
/* static */ inline ArrayObject *
ArrayObject::createArrayInternal(ExclusiveContext *cx, gc::AllocKind kind, gc::InitialHeap heap,
HandleShape shape, HandleTypeObject type)
{
// Create a new array and initialize everything except for its elements.
MOZ_ASSERT(shape && type);
MOZ_ASSERT(type->clasp() == shape->getObjectClass());
MOZ_ASSERT(type->clasp() == &ArrayObject::class_);
MOZ_ASSERT_IF(type->clasp()->finalize, heap == gc::TenuredHeap);
// Arrays can use their fixed slots to store elements, so can't have shapes
// which allow named properties to be stored in the fixed slots.
MOZ_ASSERT(shape->numFixedSlots() == 0);
size_t nDynamicSlots = dynamicSlotsCount(0, shape->slotSpan(), type->clasp());
JSObject *obj = NewGCObject<CanGC>(cx, kind, nDynamicSlots, heap);
if (!obj)
return nullptr;
static_cast<ArrayObject *>(obj)->shape_.init(shape);
static_cast<ArrayObject *>(obj)->type_.init(type);
return &obj->as<ArrayObject>();
}
/* static */ inline ArrayObject *
ArrayObject::finishCreateArray(ArrayObject *obj, HandleShape shape)
{
size_t span = shape->slotSpan();
if (span)
obj->initializeSlotRange(0, span);
gc::TraceCreateObject(obj);
return obj;
}
/* static */ inline ArrayObject *
ArrayObject::createArray(ExclusiveContext *cx, gc::AllocKind kind, gc::InitialHeap heap,
HandleShape shape, HandleTypeObject type,
uint32_t length)
{
ArrayObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
uint32_t capacity = gc::GetGCKindSlots(kind) - ObjectElements::VALUES_PER_HEADER;
obj->setFixedElements();
new (obj->getElementsHeader()) ObjectElements(capacity, length);
return finishCreateArray(obj, shape);
}
/* static */ inline ArrayObject *
ArrayObject::createArray(ExclusiveContext *cx, gc::InitialHeap heap,
HandleShape shape, HandleTypeObject type,
HeapSlot *elements)
{
// Use the smallest allocation kind for the array, as it can't have any
// fixed slots (see the assert in createArrayInternal) and will not be using
// its fixed elements.
gc::AllocKind kind = gc::FINALIZE_OBJECT0_BACKGROUND;
ArrayObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
obj->elements = elements;
return finishCreateArray(obj, shape);
}
/* static */ inline ArrayObject *
ArrayObject::createCopyOnWriteArray(ExclusiveContext *cx, gc::InitialHeap heap,
HandleShape shape,
HandleNativeObject sharedElementsOwner)
{
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->isCopyOnWrite());
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->ownerObject() == sharedElementsOwner);
// Use the smallest allocation kind for the array, as it can't have any
// fixed slots (see the assert in createArrayInternal) and will not be using
// its fixed elements.
gc::AllocKind kind = gc::FINALIZE_OBJECT0_BACKGROUND;
RootedTypeObject type(cx, sharedElementsOwner->type());
ArrayObject *obj = createArrayInternal(cx, kind, heap, shape, type);
if (!obj)
return nullptr;
obj->elements = sharedElementsOwner->getDenseElementsAllowCopyOnWrite();
return finishCreateArray(obj, shape);
}
} // namespace js
#endif // vm_ArrayObject_inl_h

Просмотреть файл

@ -7,11 +7,11 @@
#ifndef vm_ArrayObject_h
#define vm_ArrayObject_h
#include "jsobj.h"
#include "vm/ObjectImpl.h"
namespace js {
class ArrayObject : public JSObject
class ArrayObject : public NativeObject
{
public:
// Array(x) eagerly allocates dense elements if x <= this value. Without
@ -37,6 +37,43 @@ class ArrayObject : public JSObject
MOZ_ASSERT(length <= INT32_MAX);
getElementsHeader()->length = length;
}
// Make an array object with the specified initial state.
static inline ArrayObject *
createArray(ExclusiveContext *cx,
gc::AllocKind kind,
gc::InitialHeap heap,
HandleShape shape,
HandleTypeObject type,
uint32_t length);
// Make an array object with the specified initial state and elements.
static inline ArrayObject *
createArray(ExclusiveContext *cx,
gc::InitialHeap heap,
HandleShape shape,
HandleTypeObject type,
HeapSlot *elements);
// Make a copy-on-write array object which shares the elements of an
// existing object.
static inline ArrayObject *
createCopyOnWriteArray(ExclusiveContext *cx,
gc::InitialHeap heap,
HandleShape shape,
HandleNativeObject sharedElementsOwner);
private:
// Helper for the above methods.
static inline ArrayObject *
createArrayInternal(ExclusiveContext *cx,
gc::AllocKind kind,
gc::InitialHeap heap,
HandleShape shape,
HandleTypeObject type);
static inline ArrayObject *
finishCreateArray(ArrayObject *obj, HandleShape shape);
};
} // namespace js

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше