#465: gc, jsobj, RegExp

This commit is contained in:
Cameron Kaiser 2018-02-16 23:10:14 -08:00
parent 52a30155ff
commit b25a781014
5 changed files with 42 additions and 42 deletions

View File

@ -189,7 +189,7 @@ GCRuntime::tryNewTenuredObject(ExclusiveContext* cx, AllocKind kind, size_t thin
JSObject* obj = tryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize); JSObject* obj = tryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize);
if (obj) if (MOZ_LIKELY(obj))
obj->setInitialSlotsMaybeNonNative(slots); obj->setInitialSlotsMaybeNonNative(slots);
else else
js_free(slots); js_free(slots);
@ -262,7 +262,7 @@ GCRuntime::tryNewTenuredThing(ExclusiveContext* cx, AllocKind kind, size_t thing
rt->gc.waitBackgroundSweepOrAllocEnd(); rt->gc.waitBackgroundSweepOrAllocEnd();
t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize); t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize);
if (!t) if (MOZ_UNLIKELY(!t))
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
} }
} }

View File

@ -215,7 +215,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const
/* Make the object allocation. */ /* Make the object allocation. */
JSObject* obj = static_cast<JSObject*>(allocate(size)); JSObject* obj = static_cast<JSObject*>(allocate(size));
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
/* If we want external slots, add them. */ /* If we want external slots, add them. */
@ -223,7 +223,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const
if (numDynamic) { if (numDynamic) {
MOZ_ASSERT(clasp->isNative()); MOZ_ASSERT(clasp->isNative());
slots = static_cast<HeapSlot*>(allocateBuffer(cx->zone(), numDynamic * sizeof(HeapSlot))); slots = static_cast<HeapSlot*>(allocateBuffer(cx->zone(), numDynamic * sizeof(HeapSlot)));
if (!slots) { if (MOZ_UNLIKELY(!slots)) {
/* /*
* It is safe to leave the allocated object uninitialized, since we * It is safe to leave the allocated object uninitialized, since we
* do not visit unallocated things in the nursery. * do not visit unallocated things in the nursery.

View File

@ -2095,7 +2095,7 @@ AllocRelocatedCell(Zone* zone, AllocKind thingKind, size_t thingSize)
void* dstAlloc = zone->arenas.allocateFromFreeList(thingKind, thingSize); void* dstAlloc = zone->arenas.allocateFromFreeList(thingKind, thingSize);
if (!dstAlloc) if (!dstAlloc)
dstAlloc = GCRuntime::refillFreeListInGC(zone, thingKind); dstAlloc = GCRuntime::refillFreeListInGC(zone, thingKind);
if (!dstAlloc) { if (MOZ_UNLIKELY(!dstAlloc)) {
// This can only happen in zeal mode or debug builds as we don't // This can only happen in zeal mode or debug builds as we don't
// otherwise relocate more cells than we have existing free space // otherwise relocate more cells than we have existing free space
// for. // for.
@ -4313,7 +4313,7 @@ js::gc::MarkingValidator::nonIncrementalMark()
for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) { for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) {
ChunkBitmap* bitmap = &chunk->bitmap; ChunkBitmap* bitmap = &chunk->bitmap;
ChunkBitmap* entry = js_new<ChunkBitmap>(); ChunkBitmap* entry = js_new<ChunkBitmap>();
if (!entry) if (MOZ_UNLIKELY(!entry))
return; return;
memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap)); memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap));

View File

@ -233,7 +233,7 @@ js::Throw(JSContext* cx, jsid id, unsigned errorNumber)
if (!idstr) if (!idstr)
return false; return false;
JSAutoByteString bytes(cx, idstr); JSAutoByteString bytes(cx, idstr);
if (!bytes) if (MOZ_UNLIKELY(!bytes))
return false; return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr()); JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr());
return false; return false;
@ -661,12 +661,12 @@ NewObject(ExclusiveContext* cx, HandleObjectGroup group, gc::AllocKind kind,
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, group->proto(), nfixed, RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, group->proto(), nfixed,
initialShapeFlags)); initialShapeFlags));
if (!shape) if (MOZ_UNLIKELY(!shape))
return nullptr; return nullptr;
gc::InitialHeap heap = GetInitialHeap(newKind, clasp); gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
JSObject* obj = JSObject::create(cx, kind, heap, shape, group); JSObject* obj = JSObject::create(cx, kind, heap, shape, group);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (newKind == SingletonObject) { if (newKind == SingletonObject) {
@ -723,11 +723,11 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext* cxArg, const Class* clasp,
} }
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, proto, nullptr)); RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, proto, nullptr));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
RootedObject obj(cxArg, NewObject(cxArg, group, allocKind, newKind, initialShapeFlags)); RootedObject obj(cxArg, NewObject(cxArg, group, allocKind, newKind, initialShapeFlags));
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -790,11 +790,11 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cxArg, const Class* clasp,
Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto)); Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto));
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, taggedProto)); RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, taggedProto));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
JSObject* obj = NewObject(cxArg, group, allocKind, newKind); JSObject* obj = NewObject(cxArg, group, allocKind, newKind);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -844,7 +844,7 @@ js::NewObjectWithGroupCommon(ExclusiveContext* cx, HandleObjectGroup group,
} }
JSObject* obj = NewObject(cx, group, allocKind, newKind); JSObject* obj = NewObject(cx, group, allocKind, newKind);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -957,7 +957,7 @@ js::CreateThisForFunctionWithProto(JSContext* cx, HandleObject callee, HandleObj
if (proto) { if (proto) {
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, nullptr, TaggedProto(proto), RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, nullptr, TaggedProto(proto),
newTarget)); newTarget));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
if (group->newScript() && !group->newScript()->analyzed()) { if (group->newScript() && !group->newScript()->analyzed()) {
@ -980,7 +980,7 @@ js::CreateThisForFunctionWithProto(JSContext* cx, HandleObject callee, HandleObj
if (res) { if (res) {
JSScript* script = callee->as<JSFunction>().getOrCreateScript(cx); JSScript* script = callee->as<JSFunction>().getOrCreateScript(cx);
if (!script) if (MOZ_UNLIKELY(!script))
return nullptr; return nullptr;
TypeScript::SetThis(cx, script, TypeSet::ObjectType(res)); TypeScript::SetThis(cx, script, TypeSet::ObjectType(res));
} }
@ -1145,7 +1145,7 @@ js::CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto)
RootedObject clone(cx); RootedObject clone(cx);
if (obj->isNative()) { if (obj->isNative()) {
clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto); clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto);
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
if (clone->is<JSFunction>() && (obj->compartment() != clone->compartment())) { if (clone->is<JSFunction>() && (obj->compartment() != clone->compartment())) {
@ -1161,7 +1161,7 @@ js::CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto)
options.setClass(obj->getClass()); options.setClass(obj->getClass());
clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, options); clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, options);
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
if (!CopyProxyObject(cx, obj.as<ProxyObject>(), clone.as<ProxyObject>())) if (!CopyProxyObject(cx, obj.as<ProxyObject>(), clone.as<ProxyObject>()))
@ -1345,13 +1345,13 @@ InitializePropertiesFromCompatibleNativeObject(JSContext* cx,
// dst's object flags are 0. // dst's object flags are 0.
shape = EmptyShape::getInitialShape(cx, dst->getClass(), dst->getTaggedProto(), shape = EmptyShape::getInitialShape(cx, dst->getClass(), dst->getTaggedProto(),
dst->numFixedSlots(), 0); dst->numFixedSlots(), 0);
if (!shape) if (MOZ_UNLIKELY(!shape))
return false; return false;
// Get an in-order list of the shapes in the src object. // Get an in-order list of the shapes in the src object.
Rooted<ShapeVector> shapes(cx, ShapeVector(cx)); Rooted<ShapeVector> shapes(cx, ShapeVector(cx));
for (Shape::Range<NoGC> r(src->lastProperty()); !r.empty(); r.popFront()) { for (Shape::Range<NoGC> r(src->lastProperty()); !r.empty(); r.popFront()) {
if (!shapes.append(&r.front())) if (MOZ_UNLIKELY(!shapes.append(&r.front())))
return false; return false;
} }
Reverse(shapes.begin(), shapes.end()); Reverse(shapes.begin(), shapes.end());
@ -1442,7 +1442,7 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj)
: ObjectGroup::NewArrayKind::Normal; : ObjectGroup::NewArrayKind::Normal;
obj.set(ObjectGroup::newArrayObject(cx, values.begin(), values.length(), obj.set(ObjectGroup::newArrayObject(cx, values.begin(), values.length(),
TenuredObject, arrayKind)); TenuredObject, arrayKind));
if (!obj) if (MOZ_UNLIKELY(!obj))
return false; return false;
} }
@ -1560,9 +1560,9 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
AutoCompartment ac(cx, a); AutoCompartment ac(cx, a);
if (!a->getGroup(cx)) if (MOZ_UNLIKELY(!a->getGroup(cx)))
oomUnsafe.crash("JSObject::swap"); oomUnsafe.crash("JSObject::swap");
if (!b->getGroup(cx)) if (MOZ_UNLIKELY(!b->getGroup(cx)))
oomUnsafe.crash("JSObject::swap"); oomUnsafe.crash("JSObject::swap");
/* /*
@ -1644,9 +1644,9 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
a->fixDictionaryShapeAfterSwap(); a->fixDictionaryShapeAfterSwap();
b->fixDictionaryShapeAfterSwap(); b->fixDictionaryShapeAfterSwap();
if (na && !b->as<NativeObject>().fillInAfterSwap(cx, avals, apriv)) if (MOZ_UNLIKELY(na && !b->as<NativeObject>().fillInAfterSwap(cx, avals, apriv)))
oomUnsafe.crash("fillInAfterSwap"); oomUnsafe.crash("fillInAfterSwap");
if (nb && !a->as<NativeObject>().fillInAfterSwap(cx, bvals, bpriv)) if (MOZ_UNLIKELY(nb && !a->as<NativeObject>().fillInAfterSwap(cx, bvals, bpriv)))
oomUnsafe.crash("fillInAfterSwap"); oomUnsafe.crash("fillInAfterSwap");
} }
@ -1758,7 +1758,7 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
* used because it won't let us use protoProto as the proto. * used because it won't let us use protoProto as the proto.
*/ */
RootedNativeObject proto(cx, NewNativeObjectWithClassProto(cx, clasp, protoProto, SingletonObject)); RootedNativeObject proto(cx, NewNativeObjectWithClassProto(cx, clasp, protoProto, SingletonObject));
if (!proto) if (MOZ_UNLIKELY(!proto))
return nullptr; return nullptr;
/* After this point, control must exit via label bad or out. */ /* After this point, control must exit via label bad or out. */
@ -1786,7 +1786,7 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
ctor = proto; ctor = proto;
} else { } else {
RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom, ctorKind)); RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom, ctorKind));
if (!fun) if (MOZ_UNLIKELY(!fun))
goto bad; goto bad;
/* /*
@ -1960,7 +1960,7 @@ js::SetClassAndProto(JSContext* cx, HandleObject obj,
} }
ObjectGroup* group = ObjectGroup::defaultNewGroup(cx, clasp, proto); ObjectGroup* group = ObjectGroup::defaultNewGroup(cx, clasp, proto);
if (!group) if (MOZ_UNLIKELY(!group))
return false; return false;
/* /*
@ -1987,7 +1987,7 @@ JSObject::changeToSingleton(JSContext* cx, HandleObject obj)
ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->getClass(), ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->getClass(),
obj->getTaggedProto()); obj->getTaggedProto());
if (!group) if (MOZ_UNLIKELY(!group))
return false; return false;
obj->group_ = group; obj->group_ = group;
@ -3656,12 +3656,12 @@ JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassIn
} }
// Other things may be measured in the future if DMD indicates it is worthwhile. // Other things may be measured in the future if DMD indicates it is worthwhile.
if (is<JSFunction>() || if (MOZ_LIKELY((is<JSFunction>() ||
is<PlainObject>() || is<PlainObject>() ||
is<ArrayObject>() || is<ArrayObject>() ||
is<CallObject>() || is<CallObject>() ||
is<RegExpObject>() || is<RegExpObject>() ||
is<ProxyObject>()) is<ProxyObject>())))
{ {
// Do nothing. But this function is hot, and we win by getting the // Do nothing. But this function is hot, and we win by getting the
// common cases out of the way early. Some stats on the most common // common cases out of the way early. Some stats on the most common

View File

@ -54,7 +54,7 @@ js::RegExpAlloc(ExclusiveContext* cx, HandleObject proto /* = nullptr */)
regexp->initPrivate(nullptr); regexp->initPrivate(nullptr);
if (!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, regexp)) if (MOZ_UNLIKELY(!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, regexp)))
return nullptr; return nullptr;
MOZ_ASSERT(regexp->lookupPure(cx->names().lastIndex)->slot() == MOZ_ASSERT(regexp->lookupPure(cx->names().lastIndex)->slot() ==
@ -70,7 +70,7 @@ MatchPairs::initArrayFrom(MatchPairs& copyFrom)
{ {
MOZ_ASSERT(copyFrom.pairCount() > 0); MOZ_ASSERT(copyFrom.pairCount() > 0);
if (!allocOrExpandArray(copyFrom.pairCount())) if (MOZ_UNLIKELY(!allocOrExpandArray(copyFrom.pairCount())))
return false; return false;
PodCopy(pairs_, copyFrom.pairs_, pairCount_); PodCopy(pairs_, copyFrom.pairs_, pairCount_);
@ -90,7 +90,7 @@ ScopedMatchPairs::allocOrExpandArray(size_t pairCount)
MOZ_ASSERT(!pairs_); MOZ_ASSERT(!pairs_);
pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount); pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount);
if (!pairs_) if (MOZ_UNLIKELY(!pairs_))
return false; return false;
pairCount_ = pairCount; pairCount_ = pairCount;
@ -224,7 +224,7 @@ RegExpObject::createNoStatics(ExclusiveContext* cx, HandleAtom source, RegExpFla
return nullptr; return nullptr;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx)); Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
if (!regexp) if (MOZ_UNLIKELY(!regexp))
return nullptr; return nullptr;
regexp->initAndZeroLastIndex(source, flags, cx); regexp->initAndZeroLastIndex(source, flags, cx);
@ -341,7 +341,7 @@ SetupBuffer(StringBuffer& sb, const CharT* oldChars, size_t oldLen, const CharT*
if (mozilla::IsSame<CharT, char16_t>::value && !sb.ensureTwoByteChars()) if (mozilla::IsSame<CharT, char16_t>::value && !sb.ensureTwoByteChars())
return false; return false;
if (!sb.reserve(oldLen + 1)) if (MOZ_UNLIKELY(!sb.reserve(oldLen + 1)))
return false; return false;
sb.infallibleAppend(oldChars, size_t(it - oldChars)); sb.infallibleAppend(oldChars, size_t(it - oldChars));
@ -837,10 +837,10 @@ RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGu
} }
ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags)); ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags));
if (!shared) if (MOZ_UNLIKELY(!shared))
return false; return false;
if (!set_.add(p, shared)) { if (MOZ_UNLIKELY(!set_.add(p, shared))) {
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
return false; return false;
} }
@ -885,18 +885,18 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
// in the tenured heap to simplify embedding them in JIT code. // in the tenured heap to simplify embedding them in JIT code.
RootedObjectGroup group(cx, regex->group()); RootedObjectGroup group(cx, regex->group());
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject)); Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
clone->initPrivate(nullptr); clone->initPrivate(nullptr);
if (!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, clone)) if (MOZ_UNLIKELY(!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, clone)))
return nullptr; return nullptr;
Rooted<JSAtom*> source(cx, regex->getSource()); Rooted<JSAtom*> source(cx, regex->getSource());
// Check that the RegExpShared for |regex| is okay to reuse in the clone. // Check that the RegExpShared for |regex| is okay to reuse in the clone.
RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx); RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx);
if (!currentStatics) if (MOZ_UNLIKELY(!currentStatics))
return nullptr; return nullptr;
RegExpFlag origFlags = regex->getFlags(); RegExpFlag origFlags = regex->getFlags();
@ -969,7 +969,7 @@ bool
js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut) js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut)
{ {
JSLinearString* linear = flagStr->ensureLinear(cx); JSLinearString* linear = flagStr->ensureLinear(cx);
if (!linear) if (MOZ_UNLIKELY(!linear))
return false; return false;
size_t len = linear->length(); size_t len = linear->length();