Bug 949220 - Inline |ProxyObject::create| into its sole caller, and simplify the resulting code. r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D70515
This commit is contained in:
Jeff Walden 2020-04-18 01:44:56 +00:00
Родитель 650b69563f
Коммит e81bc1064b
2 изменённых файлов: 58 добавлений и 71 удалений

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

@ -69,12 +69,14 @@ ProxyObject* ProxyObject::New(JSContext* cx, const BaseProxyHandler* handler,
const JSClass* clasp) {
Rooted<TaggedProto> proto(cx, proto_);
#ifdef DEBUG
MOZ_ASSERT(clasp->isProxy());
MOZ_ASSERT(isValidProxyClass(clasp));
MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
MOZ_ASSERT_IF(proto.isObject(),
cx->compartment() == proto.toObject()->compartment());
MOZ_ASSERT(clasp->hasFinalize());
#ifdef DEBUG
if (priv.isGCThing()) {
JS::AssertCellIsNotGray(priv.toGCThing());
}
@ -95,22 +97,64 @@ ProxyObject* ProxyObject::New(JSContext* cx, const BaseProxyHandler* handler,
}
}
// Ensure that the wrapper has the same lifetime assumptions as the
// wrappee. Prefer to allocate in the nursery, when possible.
NewObjectKind newKind = NurseryAllocatedProxy;
if ((priv.isGCThing() && priv.toGCThing()->isTenured()) ||
!handler->canNurseryAllocate()) {
newKind = TenuredObject;
}
gc::AllocKind allocKind = GetProxyGCObjectKind(clasp, handler, priv);
Realm* realm = cx->realm();
AutoSetNewObjectMetadata metadata(cx);
// Note: this will initialize the object's |data| to strange values, but we
// will immediately overwrite those below.
ProxyObject* proxy;
JS_TRY_VAR_OR_RETURN_NULL(cx, proxy,
create(cx, clasp, proto, allocKind, newKind));
// Try to look up the group and shape in the NewProxyCache.
RootedObjectGroup group(cx);
RootedShape shape(cx);
if (!realm->newProxyCache.lookup(clasp, proto, group.address(),
shape.address())) {
group = ObjectGroup::defaultNewGroup(cx, clasp, proto, nullptr);
if (!group) {
return nullptr;
}
shape = EmptyShape::getInitialShape(cx, clasp, proto, /* nfixed = */ 0);
if (!shape) {
return nullptr;
}
realm->newProxyCache.add(group, shape);
}
MOZ_ASSERT(group->realm() == realm);
MOZ_ASSERT(shape->zone() == cx->zone());
MOZ_ASSERT(!IsAboutToBeFinalizedUnbarriered(group.address()));
MOZ_ASSERT(!IsAboutToBeFinalizedUnbarriered(shape.address()));
// Ensure that the wrapper has the same lifetime assumptions as the
// wrappee. Prefer to allocate in the nursery, when possible.
gc::InitialHeap heap;
{
AutoSweepObjectGroup sweep(group);
if (group->shouldPreTenure(sweep) ||
(priv.isGCThing() && priv.toGCThing()->isTenured()) ||
!handler->canNurseryAllocate()) {
heap = gc::TenuredHeap;
} else {
heap = gc::DefaultHeap;
}
}
debugCheckNewObject(group, shape, allocKind, heap);
JSObject* obj =
AllocateObject(cx, allocKind, /* nDynamicSlots = */ 0, heap, clasp);
if (!obj) {
return nullptr;
}
ProxyObject* proxy = static_cast<ProxyObject*>(obj);
proxy->initGroup(group);
proxy->initShape(shape);
MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
realm->setObjectPendingMetadata(cx, proxy);
gc::gcTracer.traceCreateObject(proxy);
proxy->init(handler, priv, cx);
@ -248,57 +292,6 @@ void ProxyObject::nuke() {
// to leak.
}
/* static */ JS::Result<ProxyObject*, JS::OOM&> ProxyObject::create(
JSContext* cx, const JSClass* clasp, Handle<TaggedProto> proto,
gc::AllocKind allocKind, NewObjectKind newKind) {
MOZ_ASSERT(clasp->isProxy());
Realm* realm = cx->realm();
RootedObjectGroup group(cx);
RootedShape shape(cx);
// Try to look up the group and shape in the NewProxyCache.
if (!realm->newProxyCache.lookup(clasp, proto, group.address(),
shape.address())) {
group = ObjectGroup::defaultNewGroup(cx, clasp, proto, nullptr);
if (!group) {
return cx->alreadyReportedOOM();
}
shape = EmptyShape::getInitialShape(cx, clasp, proto, /* nfixed = */ 0);
if (!shape) {
return cx->alreadyReportedOOM();
}
realm->newProxyCache.add(group, shape);
}
MOZ_ASSERT(group->realm() == realm);
MOZ_ASSERT(shape->zone() == cx->zone());
MOZ_ASSERT(!IsAboutToBeFinalizedUnbarriered(group.address()));
MOZ_ASSERT(!IsAboutToBeFinalizedUnbarriered(shape.address()));
gc::InitialHeap heap = GetInitialHeap(newKind, group);
debugCheckNewObject(group, shape, allocKind, heap);
JSObject* obj =
js::AllocateObject(cx, allocKind, /* nDynamicSlots = */ 0, heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}
ProxyObject* pobj = static_cast<ProxyObject*>(obj);
pobj->initGroup(group);
pobj->initShape(shape);
MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
cx->realm()->setObjectPendingMetadata(cx, pobj);
js::gc::gcTracer.traceCreateObject(pobj);
return pobj;
}
JS_FRIEND_API void js::detail::SetValueInProxy(Value* slot,
const Value& value) {
// Slots in proxies are not GCPtrValues, so do a cast whenever assigning

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

@ -37,12 +37,6 @@ class ProxyObject : public JSObject {
"Proxy reservedSlots must overlay native object slots field");
}
static JS::Result<ProxyObject*, JS::OOM&> create(JSContext* cx,
const JSClass* clasp,
Handle<TaggedProto> proto,
js::gc::AllocKind allocKind,
js::NewObjectKind newKind);
public:
static ProxyObject* New(JSContext* cx, const BaseProxyHandler* handler,
HandleValue priv, TaggedProto proto_,