diff --git a/js/src/wasm/WasmInstance.cpp b/js/src/wasm/WasmInstance.cpp index 4749b1bd620b..af81e07c6cd8 100644 --- a/js/src/wasm/WasmInstance.cpp +++ b/js/src/wasm/WasmInstance.cpp @@ -67,13 +67,24 @@ using CheckedU32 = CheckedInt; // Instance must be aligned at least as much as any of the integer, float, // or SIMD values that we'd like to store in it. static_assert(alignof(Instance) >= - std::max(sizeof(Registers::RegisterContent), sizeof(FloatRegisters::RegisterContent))); + std::max(sizeof(Registers::RegisterContent), + sizeof(FloatRegisters::RegisterContent))); // The globalArea must be aligned at least as much as an instance. This is // guaranteed to be sufficient for all data types we care about, including // SIMD values. See the above assertion. static_assert(Instance::offsetOfGlobalArea() % alignof(Instance) == 0); +// We want the memory base to be the first field, and accessible with no +// offset. This incidentally is also an assertion that there is no superclass +// with fields. +static_assert(Instance::offsetOfMemoryBase() == 0); + +// We want instance fields that are commonly accessed by the JIT to have +// compact encodings. A limit of less than 128 bytes is chosen to fit within +// the signed 8-bit mod r/m x86 encoding. +static_assert(Instance::offsetOfLastCommonJitField() < 128); + ////////////////////////////////////////////////////////////////////////////// // // Functions and invocation. @@ -1307,13 +1318,13 @@ Instance::Instance(JSContext* cx, Handle object, HandleWasmMemoryObject memory, SharedTableVector&& tables, UniqueDebugState maybeDebug) : realm_(cx->realm()), - object_(object), jsJitArgsRectifier_( cx->runtime()->jitRuntime()->getArgumentsRectifier().value), jsJitExceptionHandler_( cx->runtime()->jitRuntime()->getExceptionTail().value), preBarrierCode_( cx->runtime()->jitRuntime()->preBarrier(MIRType::Object).value), + object_(object), code_(std::move(code)), memory_(memory), tables_(std::move(tables)), diff --git a/js/src/wasm/WasmInstance.h b/js/src/wasm/WasmInstance.h index 43c8c9092b49..39f02f5fbc09 100644 --- a/js/src/wasm/WasmInstance.h +++ b/js/src/wasm/WasmInstance.h @@ -64,6 +64,10 @@ struct TagDesc; // but have now been unified. Extant references to 'TlsData' will be cleaned // up over time. class alignas(16) Instance { + // NOTE: The first fields of Instance are reserved for commonly accessed data + // from the JIT, such that they have as small an offset as possible. See the + // next note for the end of this region. + // Pointer to the base of the default memory (or null if there is none). uint8_t* memoryBase_; @@ -80,9 +84,6 @@ class alignas(16) Instance { // The containing JSContext. JSContext* cx_; - // The class_ of WasmValueBox, this is a per-process value. - const JSClass* valueBoxClass_; - #ifdef ENABLE_WASM_EXCEPTIONS // The pending exception that was found during stack unwinding after a throw. // @@ -104,11 +105,21 @@ class alignas(16) Instance { // Set to 1 when wasm should call CheckForInterrupt. Atomic interrupt_; + // The address of the realm()->zone()->needsIncrementalBarrier(). This is + // specific to this instance and not a process wide field, and so it cannot + // be linked into code. const JS::shadow::Zone::BarrierState* addressOfNeedsIncrementalBarrier_; - // Pointer that should be freed (due to padding before the Instance). - void* allocatedBase_; + public: + // NOTE: All fields commonly accessed by the JIT must be above this method, + // and this method adapted for the last field present. This method is used + // to assert that we can use compact offsets on x86(-64) for these fields. + // We cannot have the assertion here, due to C++ 'offsetof' rules. + static constexpr size_t offsetOfLastCommonJitField() { + return offsetof(Instance, addressOfNeedsIncrementalBarrier_); + } + private: // When compiling with tiering, the jumpTable has one entry for each // baseline-compiled function. void** jumpTable_; @@ -117,8 +128,10 @@ class alignas(16) Instance { // the stack for this. uint32_t baselineScratch_[2]; - // Weak pointer to WasmInstanceObject that owns this instance - WeakHeapPtrWasmInstanceObject object_; + // The class_ of WasmValueBox, this is a per-process value. We could patch + // this into code, but the only use-sites are register restricted and cannot + // easily use a symbolic address. + const JSClass* valueBoxClass_; // Address of the JitRuntime's arguments rectifier trampoline void* jsJitArgsRectifier_; @@ -129,6 +142,9 @@ class alignas(16) Instance { // Address of the JitRuntime's object prebarrier trampoline void* preBarrierCode_; + // Weak pointer to WasmInstanceObject that owns this instance + WeakHeapPtrWasmInstanceObject object_; + // The wasm::Code for this instance const SharedCode code_; @@ -153,6 +169,9 @@ class alignas(16) Instance { bool hasGcTypes_; #endif + // Pointer that should be freed (due to padding before the Instance). + void* allocatedBase_; + // The globalArea must be the last field. Globals for the module start here // and are inline in this structure. 16-byte alignment is required for SIMD // data.