diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index 520db782ca4b..836904073423 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -9,6 +9,7 @@ #include "jit/CacheIR.h" #include "jit/Linker.h" #include "jit/SharedICHelpers.h" +#include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" #include "jit/MacroAssembler-inl.h" @@ -286,13 +287,19 @@ bool BaselineCacheIRCompiler::emitGuardCompartment() { Register obj = allocator.useRegister(masm, reader.objOperandId()); - reader.stubOffset(); // Read global wrapper. AutoScratchRegister scratch(allocator, masm); FailurePath* failure; if (!addFailurePath(&failure)) return false; + // Verify that the global wrapper is still valid, as + // it is pre-requisite for doing the compartment check. + Address globalWrapper(stubAddress(reader.stubOffset())); + masm.loadPtr(globalWrapper, scratch); + Address handlerAddr(scratch, ProxyObject::offsetOfHandler()); + masm.branchPtr(Assembler::Equal, handlerAddr, ImmPtr(&DeadObjectProxy::singleton), failure->label()); + Address addr(stubAddress(reader.stubOffset())); masm.branchTestObjCompartment(Assembler::NotEqual, obj, addr, scratch, failure->label()); return true; diff --git a/js/src/jit/IonCacheIRCompiler.cpp b/js/src/jit/IonCacheIRCompiler.cpp index b79422638fa7..5936487ee5ac 100644 --- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -13,6 +13,7 @@ #include "jit/JSJitFrameIter.h" #include "jit/Linker.h" #include "jit/SharedICHelpers.h" +#include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" #include "jit/JSJitFrameIter-inl.h" @@ -678,15 +679,20 @@ bool IonCacheIRCompiler::emitGuardCompartment() { Register obj = allocator.useRegister(masm, reader.objOperandId()); - objectStubField(reader.stubOffset()); // Read global wrapper. + JSObject* globalWrapper = objectStubField(reader.stubOffset()); JSCompartment* compartment = compartmentStubField(reader.stubOffset()); - AutoScratchRegister scratch(allocator, masm); FailurePath* failure; if (!addFailurePath(&failure)) return false; + // Verify that the global wrapper is still valid, as + // it is pre-requisite for doing the compartment check. + masm.movePtr(ImmGCPtr(globalWrapper), scratch); + Address handlerAddr(scratch, ProxyObject::offsetOfHandler()); + masm.branchPtr(Assembler::Equal, handlerAddr, ImmPtr(&DeadObjectProxy::singleton), failure->label()); + masm.branchTestObjCompartment(Assembler::NotEqual, obj, compartment, scratch, failure->label()); return true;