Ignore:
Timestamp:
Nov 27, 2020, 8:31:41 PM (4 years ago)
Author:
[email protected]
Message:

[JSC] Use ARM atomic ops in wasm
https://bugs.webkit.org/show_bug.cgi?id=219281

Reviewed by Filip Pizlo.

JSTests:

  • wasm/threads-spec-tests/atomic-signed.wast.js:
  • wasm/threads-spec-tests/resources/atomic-signed.wast:

Source/JavaScriptCore:

This patch uses ARM LSE Atomic instructions in wasm atomic operations. This includes support in MacroAssembler, offlineasm, Air and B3,
so that FTL atomic operations automatically leverage ARM LSE atomic instructions too. Later we can extend DFG JIT to use it too.

One interesting thing is that this includes a fix for cmpxchg wasm operation implementations. Unfortunately, current wasm cmpxchg ops
are not the same to ARM cas / X86 cmpxchg. For example, i64.atomic.rmw8.cmpxchg_u takes i64 expected value. And the spec requires that
we should perform i64-expected-value <cmp> loaded-zero-extended-1byte-value. For example, if the expected value is 0xffffffff_ffffff00,
and the value stored in the memory is 0x00, then the wasm op needs to fail since 0x00 is not 0xffffffff_ffffff00. But x86 and ARM
cmpxchg / cas ops behave differently since it truncates expected value to 1byte when performing 1byte cmpxchg. So we need to have a check
which performs the value is within 1byte range in this operation.

  • assembler/ARM64EAssembler.h:

(JSC::ARM64EAssembler::exoticAtomicLoadStore):
(JSC::ARM64EAssembler::exoticAtomicCAS):
(JSC::ARM64EAssembler::ldaddal):
(JSC::ARM64EAssembler::ldeoral):
(JSC::ARM64EAssembler::ldclral):
(JSC::ARM64EAssembler::ldsetal):
(JSC::ARM64EAssembler::swpal):
(JSC::ARM64EAssembler::casal):

  • assembler/MacroAssemblerARM64E.h:

(JSC::MacroAssemblerARM64E::atomicXchgAdd8):
(JSC::MacroAssemblerARM64E::atomicXchgAdd16):
(JSC::MacroAssemblerARM64E::atomicXchgAdd32):
(JSC::MacroAssemblerARM64E::atomicXchgAdd64):
(JSC::MacroAssemblerARM64E::atomicXchgXor8):
(JSC::MacroAssemblerARM64E::atomicXchgXor16):
(JSC::MacroAssemblerARM64E::atomicXchgXor32):
(JSC::MacroAssemblerARM64E::atomicXchgXor64):
(JSC::MacroAssemblerARM64E::atomicXchgOr8):
(JSC::MacroAssemblerARM64E::atomicXchgOr16):
(JSC::MacroAssemblerARM64E::atomicXchgOr32):
(JSC::MacroAssemblerARM64E::atomicXchgOr64):
(JSC::MacroAssemblerARM64E::atomicXchgClear8):
(JSC::MacroAssemblerARM64E::atomicXchgClear16):
(JSC::MacroAssemblerARM64E::atomicXchgClear32):
(JSC::MacroAssemblerARM64E::atomicXchgClear64):
(JSC::MacroAssemblerARM64E::atomicXchg8):
(JSC::MacroAssemblerARM64E::atomicXchg16):
(JSC::MacroAssemblerARM64E::atomicXchg32):
(JSC::MacroAssemblerARM64E::atomicXchg64):
(JSC::MacroAssemblerARM64E::atomicStrongCAS8):
(JSC::MacroAssemblerARM64E::atomicStrongCAS16):
(JSC::MacroAssemblerARM64E::atomicStrongCAS32):
(JSC::MacroAssemblerARM64E::atomicStrongCAS64):

  • b3/B3LowerMacros.cpp:
  • b3/B3LowerToAir.cpp:
  • b3/air/AirOpcode.opcodes:
  • b3/air/opcode_generator.rb:
  • disassembler/ARM64/A64DOpcode.cpp:

(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::format):
(JSC::ARM64Disassembler::A64DOpcodeSwapAtomic::format):
(JSC::ARM64Disassembler::A64DOpcodeCAS::format):

  • disassembler/ARM64/A64DOpcode.h:

(JSC::ARM64Disassembler::A64DOpcode::appendInstructionName):
(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::opName):
(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::rs):
(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::opc):
(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::ar):
(JSC::ARM64Disassembler::A64DOpcodeLoadAtomic::opNumber):
(JSC::ARM64Disassembler::A64DOpcodeSwapAtomic::opName):
(JSC::ARM64Disassembler::A64DOpcodeSwapAtomic::rs):
(JSC::ARM64Disassembler::A64DOpcodeSwapAtomic::ar):
(JSC::ARM64Disassembler::A64DOpcodeSwapAtomic::opNumber):
(JSC::ARM64Disassembler::A64DOpcodeCAS::opName):
(JSC::ARM64Disassembler::A64DOpcodeCAS::rs):
(JSC::ARM64Disassembler::A64DOpcodeCAS::o1):
(JSC::ARM64Disassembler::A64DOpcodeCAS::l):
(JSC::ARM64Disassembler::A64DOpcodeCAS::opNumber):

  • llint/WebAssembly.asm:
  • offlineasm/arm64.rb:
  • offlineasm/instructions.rb:
  • offlineasm/x86.rb:
  • wasm/WasmAirIRGenerator.cpp:

(JSC::Wasm::AirIRGenerator::sanitizeAtomicResult):
(JSC::Wasm::AirIRGenerator::appendGeneralAtomic):
(JSC::Wasm::AirIRGenerator::appendStrongCAS):
(JSC::Wasm::AirIRGenerator::emitAtomicLoadOp):
(JSC::Wasm::AirIRGenerator::emitAtomicStoreOp):
(JSC::Wasm::AirIRGenerator::emitAtomicBinaryRMWOp):
(JSC::Wasm::AirIRGenerator::emitAtomicCompareExchange):

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::emitAtomicCompareExchange):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/offlineasm/x86.rb

    r270208 r270214  
    11171117        when "noti"
    11181118            $asm.puts "not#{x86Suffix(:int)} #{x86Operands(:int)}"
     1119        when "notq"
     1120            $asm.puts "not#{x86Suffix(:quad)} #{x86Operands(:quad)}"
    11191121        when "ori"
    11201122            handleX86Op("or#{x86Suffix(:int)}", :int)
     
    11631165        when "leap"
    11641166            emitX86Lea(operands[0], operands[1], :ptr)
    1165         when "loadi"
     1167        when "loadi", "atomicloadi"
    11661168            $asm.puts "mov#{x86Suffix(:int)} #{x86LoadOperands(:int, :int)}"
    11671169        when "storei"
     
    11811183        when "storep"
    11821184            $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
    1183         when "loadq"
     1185        when "loadq", "atomicloadq"
    11841186            $asm.puts "mov#{x86Suffix(:quad)} #{x86LoadOperands(:quad, :quad)}"
    11851187        when "storeq"
    11861188            $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}"
    1187         when "loadb"
     1189        when "loadb", "atomicloadb"
    11881190            if !isIntelSyntax
    11891191                $asm.puts "movzbl #{x86LoadOperands(:byte, :int)}"
     
    12031205                $asm.puts "movsx #{x86LoadOperands(:byte, :quad)}"
    12041206            end
    1205         when "loadh"
     1207        when "loadh", "atomicloadh"
    12061208            if !isIntelSyntax
    12071209                $asm.puts "movzwl #{x86LoadOperands(:half, :int)}"
Note: See TracChangeset for help on using the changeset viewer.