diff options
Diffstat (limited to 'deps/v8/src/wasm/jump-table-assembler.h')
-rw-r--r-- | deps/v8/src/wasm/jump-table-assembler.h | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/deps/v8/src/wasm/jump-table-assembler.h b/deps/v8/src/wasm/jump-table-assembler.h index 1ef1a82f41b..a83a7d5b210 100644 --- a/deps/v8/src/wasm/jump-table-assembler.h +++ b/deps/v8/src/wasm/jump-table-assembler.h @@ -12,38 +12,122 @@ namespace v8 { namespace internal { namespace wasm { +// The jump table is the central dispatch point for all (direct and indirect) +// invocations in WebAssembly. It holds one slot per function in a module, with +// each slot containing a dispatch to the currently published {WasmCode} that +// corresponds to the function. +// +// Note that the table is split into lines of fixed size, with lines laid out +// consecutively within the executable memory of the {NativeModule}. The slots +// in turn are consecutive within a line, but do not cross line boundaries. +// +// +- L1 -------------------+ +- L2 -------------------+ +- L3 ... +// | S1 | S2 | ... | Sn | x | | S1 | S2 | ... | Sn | x | | S1 ... +// +------------------------+ +------------------------+ +---- ... +// +// The above illustrates jump table lines {Li} containing slots {Si} with each +// line containing {n} slots and some padding {x} for alignment purposes. class JumpTableAssembler : public TurboAssembler { public: + // Translate an offset into the continuous jump table to a jump table index. + static uint32_t SlotOffsetToIndex(uint32_t slot_offset) { + uint32_t line_index = slot_offset / kJumpTableLineSize; + uint32_t line_offset = slot_offset % kJumpTableLineSize; + DCHECK_EQ(0, line_offset % kJumpTableSlotSize); + return line_index * kJumpTableSlotsPerLine + + line_offset / kJumpTableSlotSize; + } + + // Translate a jump table index to an offset into the continuous jump table. + static uint32_t SlotIndexToOffset(uint32_t slot_index) { + uint32_t line_index = slot_index / kJumpTableSlotsPerLine; + uint32_t line_offset = + (slot_index % kJumpTableSlotsPerLine) * kJumpTableSlotSize; + return line_index * kJumpTableLineSize + line_offset; + } + + // Determine the size of a jump table containing the given number of slots. + static constexpr uint32_t SizeForNumberOfSlots(uint32_t slot_count) { + // TODO(wasm): Once the {RoundUp} utility handles non-powers of two values, + // use: {RoundUp<kJumpTableSlotsPerLine>(slot_count) * kJumpTableLineSize} + return ((slot_count + kJumpTableSlotsPerLine - 1) / + kJumpTableSlotsPerLine) * + kJumpTableLineSize; + } + + static void EmitLazyCompileJumpSlot(Address base, uint32_t slot_index, + uint32_t func_index, + Address lazy_compile_target, + WasmCode::FlushICache flush_i_cache) { + Address slot = base + SlotIndexToOffset(slot_index); + JumpTableAssembler jtasm(slot); + jtasm.EmitLazyCompileJumpSlot(func_index, lazy_compile_target); + jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset()); + if (flush_i_cache) { + Assembler::FlushICache(slot, kJumpTableSlotSize); + } + } + + static void PatchJumpTableSlot(Address base, uint32_t slot_index, + Address new_target, + WasmCode::FlushICache flush_i_cache) { + Address slot = base + SlotIndexToOffset(slot_index); + JumpTableAssembler jtasm(slot); + jtasm.EmitJumpSlot(new_target); + jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset()); + if (flush_i_cache) { + Assembler::FlushICache(slot, kJumpTableSlotSize); + } + } + + private: // Instantiate a {JumpTableAssembler} for patching. explicit JumpTableAssembler(Address slot_addr, int size = 256) : TurboAssembler(nullptr, JumpTableAssemblerOptions(), reinterpret_cast<void*>(slot_addr), size, CodeObjectRequired::kNo) {} +// To allow concurrent patching of the jump table entries, we need to ensure +// that the instruction containing the call target does not cross cache-line +// boundaries. The jump table line size has been chosen to satisfy this. #if V8_TARGET_ARCH_X64 + static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableSlotSize = 18; #elif V8_TARGET_ARCH_IA32 + static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableSlotSize = 10; #elif V8_TARGET_ARCH_ARM + static constexpr int kJumpTableLineSize = 5 * kInstrSize; static constexpr int kJumpTableSlotSize = 5 * kInstrSize; #elif V8_TARGET_ARCH_ARM64 - static constexpr int kJumpTableSlotSize = 3 * kInstructionSize; + static constexpr int kJumpTableLineSize = 3 * kInstrSize; + static constexpr int kJumpTableSlotSize = 3 * kInstrSize; #elif V8_TARGET_ARCH_S390X + static constexpr int kJumpTableLineSize = 20; static constexpr int kJumpTableSlotSize = 20; #elif V8_TARGET_ARCH_S390 + static constexpr int kJumpTableLineSize = 14; static constexpr int kJumpTableSlotSize = 14; #elif V8_TARGET_ARCH_PPC64 + static constexpr int kJumpTableLineSize = 48; static constexpr int kJumpTableSlotSize = 48; #elif V8_TARGET_ARCH_PPC + static constexpr int kJumpTableLineSize = 24; static constexpr int kJumpTableSlotSize = 24; #elif V8_TARGET_ARCH_MIPS + static constexpr int kJumpTableLineSize = 6 * kInstrSize; static constexpr int kJumpTableSlotSize = 6 * kInstrSize; #elif V8_TARGET_ARCH_MIPS64 + static constexpr int kJumpTableLineSize = 8 * kInstrSize; static constexpr int kJumpTableSlotSize = 8 * kInstrSize; #else + static constexpr int kJumpTableLineSize = 1; static constexpr int kJumpTableSlotSize = 1; #endif + static constexpr int kJumpTableSlotsPerLine = + kJumpTableLineSize / kJumpTableSlotSize; + // {JumpTableAssembler} is never used during snapshot generation, and its code // must be independent of the code range of any isolate anyway. Just ensure // that no relocation information is recorded, there is no buffer to store it @@ -60,16 +144,6 @@ class JumpTableAssembler : public TurboAssembler { void EmitJumpSlot(Address target); void NopBytes(int bytes); - - static void PatchJumpTableSlot(Address slot, Address new_target, - WasmCode::FlushICache flush_i_cache) { - JumpTableAssembler jsasm(slot); - jsasm.EmitJumpSlot(new_target); - jsasm.NopBytes(kJumpTableSlotSize - jsasm.pc_offset()); - if (flush_i_cache) { - Assembler::FlushICache(slot, kJumpTableSlotSize); - } - } }; } // namespace wasm |