diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index 4726787326ae8074dab37dbc0f7dfe46963244c6..ba53d7574f1b22f882cdd37d0b2fb93d2d7f4684 100644 --- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -6106,24 +6106,37 @@ bool CacheIRCompiler::emitNewPlainObjectResult(uint32_t numFixedSlots, gc::AllocKind allocKind, uint32_t shapeOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); + AutoCallVM callvm(masm, this, allocator); AutoScratchRegister obj(allocator, masm); AutoScratchRegister scratch(allocator, masm); - AutoScratchRegisterMaybeOutput shape(allocator, masm, output); + AutoScratchRegisterMaybeOutput shape(allocator, masm, callvm.output()); StubFieldOffset shapeSlot(shapeOffset, StubField::Type::Shape); - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } + Label success; + Label fail; emitLoadStubField(shapeSlot, shape); masm.createPlainGCObject(obj, shape, scratch, shape, numFixedSlots, - numDynamicSlots, allocKind, gc::DefaultHeap, - failure->label()); + numDynamicSlots, allocKind, gc::DefaultHeap, &fail); + masm.tagValue(JSVAL_TYPE_OBJECT, obj, callvm.output().valueReg()); + masm.jump(&success); - masm.tagValue(JSVAL_TYPE_OBJECT, obj, output.valueReg()); + masm.bind(&fail); + + // We get here if the nursery is full (unlikely) but also if the current arena + // is full and we need to allocate a new one (fairly common). + + callvm.prepare(); + masm.Push(Imm32(gc::DefaultHeap)); + masm.Push(Imm32(int32_t(allocKind))); + masm.Push(shape); + + using Fn = + JSObject* (*)(JSContext*, HandleShape, gc::AllocKind, gc::InitialHeap); + callvm.call<Fn, NewPlainObject>(); + + masm.bind(&success); return true; } diff --git a/js/src/jit/VMFunctionList-inl.h b/js/src/jit/VMFunctionList-inl.h index f63afca394097daa8ddb34cba84d933208e6ff17..9a0ecb82c038a89aecc970df783745faec41a374 100644 --- a/js/src/jit/VMFunctionList-inl.h +++ b/js/src/jit/VMFunctionList-inl.h @@ -192,6 +192,7 @@ namespace jit { _(NewCallObject, js::jit::NewCallObject) \ _(NewObjectOperation, js::NewObjectOperation) \ _(NewObjectOperationWithTemplate, js::NewObjectOperationWithTemplate) \ + _(NewPlainObject, js::NewPlainObject) \ _(NewRegExpStringIterator, js::NewRegExpStringIterator) \ _(NewStringIterator, js::NewStringIterator) \ _(NewStringObject, js::jit::NewStringObject) \ diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index c7eceb3aa313059688e397e97825c081f7d90056..dcfd9e33a190f1e41d1601b36dd347185e3d6006 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -5051,6 +5051,14 @@ JSObject* js::NewObjectOperationWithTemplate(JSContext* cx, return CopyTemplateObject(cx, templateObject.as<PlainObject>(), newKind); } +JSObject* js::NewPlainObject(JSContext* cx, HandleShape shape, + gc::AllocKind allocKind, + gc::InitialHeap initialHeap) { + MOZ_ASSERT(shape->getObjectClass() == &PlainObject::class_); + auto r = NativeObject::create(cx, allocKind, initialHeap, shape); + return cx->resultToPtr(r); +} + JSObject* js::CreateThisWithTemplate(JSContext* cx, HandleObject templateObject) { mozilla::Maybe<AutoRealm> ar; diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h index c6d3f2fd58d95afecbcc5fe102450ab4b3a3b924..98e655646f894329085e258df4031d56acc0718d 100644 --- a/js/src/vm/Interpreter.h +++ b/js/src/vm/Interpreter.h @@ -620,6 +620,10 @@ JSObject* NewObjectOperation(JSContext* cx, HandleScript script, jsbytecode* pc, JSObject* NewObjectOperationWithTemplate(JSContext* cx, HandleObject templateObject); + +JSObject* NewPlainObject(JSContext* cx, HandleShape shape, + gc::AllocKind allocKind, gc::InitialHeap initialHeap); + JSObject* CreateThisWithTemplate(JSContext* cx, HandleObject templateObject); ArrayObject* NewArrayOperation(JSContext* cx, uint32_t length, diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h index 873d8a860ad56ed839e29bd95cb907a86b4ea05f..5f0d0b346c8e9c51c8722cc9072a2a20f4a6522d 100644 --- a/js/src/vm/JSContext.h +++ b/js/src/vm/JSContext.h @@ -422,7 +422,7 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext, } template <typename V, typename E> - V* resultToPtr(const JS::Result<V*, E>& result) { + V* resultToPtr(JS::Result<V*, E>& result) { return result.isOk() ? result.unwrap() : nullptr; }