Skip to content

Commit

Permalink
Enable Wasm IPInt
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=285025
rdar://113768719

Reviewed by Yusuke Suzuki.

With IPInt having feature parity with LLInt and being tested on
ARM64 and x86_64, we can now enable it.

* Source/JavaScriptCore/runtime/Options.h:
(JSC::Options::ipintEnabledByDefault):
* Source/JavaScriptCore/runtime/OptionsList.h:

Canonical link: https://commits.webkit.org/288385@main
  • Loading branch information
Daniel Liu authored and Constellation committed Jan 3, 2025
1 parent e6357e8 commit 5749df7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 45 deletions.
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/llint/InPlaceInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ do { \

void initialize()
{
#if !ENABLE(C_LOOP) && ((CPU(ADDRESS64) && (CPU(ARM64) || (CPU(X86_64) && !OS(WINDOWS)))) || (CPU(ADDRESS32) && CPU(ARM_THUMB2)))
#if !ENABLE(C_LOOP) && ((CPU(ADDRESS64) && (CPU(ARM64) || CPU(X86_64))) || (CPU(ADDRESS32) && CPU(ARM_THUMB2)))
FOR_EACH_IPINT_OPCODE(VALIDATE_IPINT_OPCODE);
FOR_EACH_IPINT_0xFB_OPCODE(VALIDATE_IPINT_0xFB_OPCODE);
FOR_EACH_IPINT_0xFC_TRUNC_OPCODE(VALIDATE_IPINT_0xFC_OPCODE);
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/llint/InPlaceInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern "C" void SYSV_ABI ipint_table_catch_all_entry();
extern "C" void SYSV_ABI ipint_table_catch_allref_entry();

#define IPINT_VALIDATE_DEFINE_FUNCTION(opcode, name) \
extern "C" void ipint_ ## name ## _validate() REFERENCED_FROM_ASM WTF_INTERNAL NO_REORDER;
extern "C" void SYSV_ABI ipint_ ## name ## _validate() REFERENCED_FROM_ASM WTF_INTERNAL NO_REORDER;

#define FOR_EACH_IPINT_OPCODE(m) \
m(0x00, unreachable) \
Expand Down Expand Up @@ -784,7 +784,7 @@ extern "C" void SYSV_ABI ipint_table_catch_allref_entry();
m(0x10, uint_stack) \
m(0x11, uint_ret) \

#if !ENABLE(C_LOOP) && (CPU(ADDRESS64) && (CPU(ARM64) || (CPU(X86_64) && !OS(WINDOWS))) || (CPU(ADDRESS32) && CPU(ARM_THUMB2)))
#if !ENABLE(C_LOOP) && (CPU(ADDRESS64) && (CPU(ARM64) || CPU(X86_64)) || (CPU(ADDRESS32) && CPU(ARM_THUMB2)))
FOR_EACH_IPINT_OPCODE(IPINT_VALIDATE_DEFINE_FUNCTION);
FOR_EACH_IPINT_0xFB_OPCODE(IPINT_VALIDATE_DEFINE_FUNCTION);
FOR_EACH_IPINT_0xFC_TRUNC_OPCODE(IPINT_VALIDATE_DEFINE_FUNCTION);
Expand Down
91 changes: 50 additions & 41 deletions Source/JavaScriptCore/llint/InPlaceInterpreter64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,14 @@ if ARM64 or ARM64E
# ws3 = x12
emit "br x12"
elsif X86_64
loadb [MC], sc2
loadb [MC], sc1
addq 1, MC
bilt sc2, 0x12, .safe
bilt sc1, 0x12, .safe
break
.safe:
lshiftq 6, sc2
leap (_uint_begin - _mint_entry_relativePCBase)[PC, sc2], sc2
jmp sc2
lshiftq 6, sc1
leap (_uint_begin - _mint_entry_relativePCBase)[PC, sc1], sc1
jmp sc1
end
end

Expand Down Expand Up @@ -733,7 +733,7 @@ instructionLabel(_select_t)
.ipint_select_t_val2:
popQuad(t1)
popQuad(t0)
pushQuadPair(t2, t1)
pushQuad(t1)
loadb IPInt::InstructionLengthMetadata::length[MC], t0
advancePCByReg(t0)
advanceMC(constexpr (sizeof(IPInt::InstructionLengthMetadata)))
Expand Down Expand Up @@ -5458,165 +5458,174 @@ macro atomicCmpxchgOp(boundsAndAlignmentCheck, cmpxchg)
addp t2, t3
boundsAndAlignmentCheck(t3, t2)
addq memoryBase, t3
cmpxchg(t3, t1, t0, t2)
cmpxchg(t3, t1, t0, t2, t4)

loadb IPInt::Const32Metadata::instructionLength[MC], t0
advancePCByReg(t0)
advanceMC(constexpr (sizeof(IPInt::Const32Metadata)))
nextIPIntInstruction()
end

macro weakCASExchangeByte(mem, value, expected, scratch)
macro weakCASExchangeByte(mem, value, expected, scratch, scratch2)
if ARM64
.loop:
loadlinkacqb [mem], scratch
bqneq expected, scratch, .fail
loadlinkacqb [mem], scratch2
bqneq expected, scratch2, .fail
storecondrelb scratch, value, [mem]
bieq scratch, 0, .done
jmp .loop
.fail:
emit "clrex"
move scratch, expected
storecondrelb scratch, scratch2, [mem]
bieq scratch, 0, .done
jmp .loop
.done:
move scratch2, expected
else
error
end
end

macro weakCASExchangeHalf(mem, value, expected, scratch)
macro weakCASExchangeHalf(mem, value, expected, scratch, scratch2)
if ARM64
.loop:
loadlinkacqh [mem], scratch
bqneq expected, scratch, .fail
loadlinkacqh [mem], scratch2
bqneq expected, scratch2, .fail
storecondrelh scratch, value, [mem]
bieq scratch, 0, .done
jmp .loop
.fail:
emit "clrex"
move scratch, expected
storecondrelh scratch, scratch2, [mem]
bieq scratch, 0, .done
jmp .loop
.done:
move scratch2, expected
else
error
end
end

macro weakCASExchangeInt(mem, value, expected, scratch)
macro weakCASExchangeInt(mem, value, expected, scratch, scratch2)
if ARM64
.loop:
loadlinkacqi [mem], scratch
bqneq expected, scratch, .fail
loadlinkacqi [mem], scratch2
bqneq expected, scratch2, .fail
storecondreli scratch, value, [mem]
bieq scratch, 0, .done
jmp .loop
.fail:
emit "clrex"
move scratch, expected
storecondreli scratch, scratch2, [mem]
bieq scratch, 0, .done
jmp .loop
.done:
move scratch2, expected
else
error
end
end

macro weakCASExchangeQuad(mem, value, expected, scratch)
macro weakCASExchangeQuad(mem, value, expected, scratch, scratch2)
if ARM64
.loop:
loadlinkacqq [mem], scratch
bqneq expected, scratch, .fail
loadlinkacqq [mem], scratch2
bqneq expected, scratch2, .fail
storecondrelq scratch, value, [mem]
bieq scratch, 0, .done
jmp .loop
.fail:
emit "clrex"
move scratch, expected
storecondrelq scratch, scratch2, [mem]
bieq scratch, 0, .done
jmp .loop
.done:
move scratch2, expected
else
error
end
end

instructionLabel(_i32_atomic_rmw_cmpxchg)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck4, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck4, macro(mem, value, expected, scratch, scratch2)
andq 0xffffffff, expected
if ARM64E or X86_64
atomicweakcasi expected, value, [mem]
elsif ARM64
weakCASExchangeInt(mem, value, expected, scratch2)
weakCASExchangeInt(mem, value, expected, scratch, scratch2)
else
error
end
pushInt32(expected)
end)

instructionLabel(_i64_atomic_rmw_cmpxchg)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck8, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck8, macro(mem, value, expected, scratch, scratch2)
if ARM64E or X86_64
atomicweakcasq expected, value, [mem]
elsif ARM64
weakCASExchangeQuad(mem, value, expected, scratch2)
weakCASExchangeQuad(mem, value, expected, scratch, scratch2)
else
error
end
pushInt64(expected)
end)

instructionLabel(_i32_atomic_rmw8_cmpxchg_u)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck1, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck1, macro(mem, value, expected, scratch, scratch2)
andq 0xff, expected
if ARM64E or X86_64
atomicweakcasb expected, value, [mem]
elsif ARM64
weakCASExchangeByte(mem, value, expected, scratch2)
weakCASExchangeByte(mem, value, expected, scratch, scratch2)
else
error
end
pushInt32(expected)
end)

instructionLabel(_i32_atomic_rmw16_cmpxchg_u)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck2, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck2, macro(mem, value, expected, scratch, scratch2)
andq 0xffff, expected
if ARM64E or X86_64
atomicweakcash expected, value, [mem]
elsif ARM64
weakCASExchangeHalf(mem, value, expected, scratch2)
weakCASExchangeHalf(mem, value, expected, scratch, scratch2)
else
error
end
pushInt32(expected)
end)

instructionLabel(_i64_atomic_rmw8_cmpxchg_u)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck1, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck1, macro(mem, value, expected, scratch, scratch2)
andq 0xff, expected
if ARM64E or X86_64
atomicweakcasb expected, value, [mem]
elsif ARM64
weakCASExchangeByte(mem, value, expected, scratch2)
weakCASExchangeByte(mem, value, expected, scratch, scratch2)
else
error
end
pushInt64(expected)
end)

instructionLabel(_i64_atomic_rmw16_cmpxchg_u)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck2, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck2, macro(mem, value, expected, scratch, scratch2)
andq 0xffff, expected
if ARM64E or X86_64
atomicweakcash expected, value, [mem]
elsif ARM64
weakCASExchangeHalf(mem, value, expected, scratch2)
weakCASExchangeHalf(mem, value, expected, scratch, scratch2)
else
error
end
pushInt64(expected)
end)

instructionLabel(_i64_atomic_rmw32_cmpxchg_u)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck4, macro(mem, value, expected, scratch2)
atomicCmpxchgOp(ipintCheckMemoryBoundWithAlignmentCheck4, macro(mem, value, expected, scratch, scratch2)
andq 0xffffffff, expected
if ARM64E or X86_64
atomicweakcasi expected, value, [mem]
elsif ARM64
weakCASExchangeInt(mem, value, expected, scratch2)
weakCASExchangeInt(mem, value, expected, scratch, scratch2)
else
error
end
Expand Down
1 change: 1 addition & 0 deletions Source/JavaScriptCore/runtime/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ public: \
static unsigned computeNumberOfWorkerThreads(int maxNumberOfWorkerThreads, int minimum = 1);
static int32_t computePriorityDeltaOfWorkerThreads(int32_t twoCorePriorityDelta, int32_t multiCorePriorityDelta);
static constexpr bool jitEnabledByDefault() { return is32Bit() || isAddress64Bit(); }
static constexpr bool ipintEnabledByDefault() { return isARM64() || isARM64E() || isX86_64(); }
};

} // namespace JSC
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/runtime/OptionsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ bool hasCapacityToUseLargeGigacage();
v(Bool, dumpWasmWarnings, false, Normal, nullptr) \
v(Bool, useRecursiveJSONParse, true, Normal, nullptr) \
v(Unsigned, thresholdForStringReplaceCache, 0x1000, Normal, nullptr) \
v(Bool, useWasmIPInt, false, Normal, "Use the in-place interpereter for WASM instead of LLInt."_s) \
v(Bool, useWasmIPInt, ipintEnabledByDefault(), Normal, "Use the in-place interpereter for WASM instead of LLInt."_s) \
v(Bool, useWasmIPIntPrologueOSR, true, Normal, "Allow IPInt to tier up during function prologues"_s) \
v(Bool, useWasmIPIntLoopOSR, true, Normal, "Allow IPInt to tier up during loop iterations"_s) \
v(Bool, useWasmIPIntEpilogueOSR, true, Normal, "Allow IPInt to tier up during function epilogues"_s) \
Expand Down

0 comments on commit 5749df7

Please sign in to comment.