Bug 1753692 - wasm: Re-order Instance fields and add assert for compact encodings. r=lth

This re-orders some Instance fields for clarity, and adds comments
and assertions that the first fields of Instance are reserved for
critical data that should be accessable using compact encodings.

Differential Revision: https://phabricator.services.mozilla.com/D140232
This commit is contained in:
Ryan Hunt 2022-03-11 15:58:31 +00:00
Родитель 19b46a32aa
Коммит 589c7ce531
2 изменённых файлов: 39 добавлений и 9 удалений

Просмотреть файл

@ -67,13 +67,24 @@ using CheckedU32 = CheckedInt<uint32_t>;
// 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<WasmInstanceObject*> 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)),

Просмотреть файл

@ -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<uint32_t, mozilla::Relaxed> 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.