From 149c050c0399629efad21ff43da4df27f97d7917 Mon Sep 17 00:00:00 2001 From: Jon Coppeard <jcoppeard@mozilla.com> Date: Tue, 13 Apr 2021 15:51:45 +0000 Subject: [PATCH] Bug 1704576 - Make the CacheIR plain object op handle failure by calling into the VM rather than failing the stub r=jandem Differential Revision: https://phabricator.services.mozilla.com/D111687 --- js/src/jit/CacheIRCompiler.cpp | 31 ++++++++++++++++++++++--------- js/src/jit/VMFunctionList-inl.h | 1 + js/src/vm/Interpreter.cpp | 8 ++++++++ js/src/vm/Interpreter.h | 4 ++++ js/src/vm/JSContext.h | 2 +- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index 4726787326ae8..ba53d7574f1b2 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 f63afca394097..9a0ecb82c038a 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 c7eceb3aa3130..dcfd9e33a190f 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 c6d3f2fd58d95..98e655646f894 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 873d8a860ad56..5f0d0b346c8e9 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; } -- GitLab