Skip to content

Commit

Permalink
RJIT: Avoid retaining unrelated local variables in memory
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Dec 22, 2023
1 parent ef4797b commit f263e44
Showing 1 changed file with 87 additions and 63 deletions.
150 changes: 87 additions & 63 deletions lib/ruby_vm/rjit/insn_compiler.rb
Expand Up @@ -1924,26 +1924,30 @@ def branchif(jit, ctx, asm)
end

# Jump to target0 on jnz
branch_stub.compile = proc do |branch_asm|
branch_asm.comment("branchif #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.jnz(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jz(branch_stub.target1.address)
in Next1
branch_asm.jnz(branch_stub.target0.address)
end
end
end
branch_stub.compile = compile_branchif(branch_stub)
branch_stub.compile.call(asm)
end

EndBlock
end

def compile_branchif(branch_stub) # Proc escapes arguments in memory
proc do |branch_asm|
branch_asm.comment("branchif #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.jnz(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jz(branch_stub.target1.address)
in Next1
branch_asm.jnz(branch_stub.target0.address)
end
end
end
end

# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
Expand Down Expand Up @@ -1985,26 +1989,30 @@ def branchunless(jit, ctx, asm)
end

# Jump to target0 on jz
branch_stub.compile = proc do |branch_asm|
branch_asm.comment("branchunless #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.jz(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jnz(branch_stub.target1.address)
in Next1
branch_asm.jz(branch_stub.target0.address)
end
end
end
branch_stub.compile = compile_branchunless(branch_stub)
branch_stub.compile.call(asm)
end

EndBlock
end

def compile_branchunless(branch_stub) # Proc escapes arguments in memory
proc do |branch_asm|
branch_asm.comment("branchunless #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.jz(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jnz(branch_stub.target1.address)
in Next1
branch_asm.jz(branch_stub.target0.address)
end
end
end
end

# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
Expand Down Expand Up @@ -2045,26 +2053,30 @@ def branchnil(jit, ctx, asm)
end

# Jump to target0 on je
branch_stub.compile = proc do |branch_asm|
branch_asm.comment("branchnil #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.je(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jne(branch_stub.target1.address)
in Next1
branch_asm.je(branch_stub.target0.address)
end
end
end
branch_stub.compile = compile_branchnil(branch_stub)
branch_stub.compile.call(asm)
end

EndBlock
end

def compile_branchnil(branch_stub) # Proc escapes arguments in memory
proc do |branch_asm|
branch_asm.comment("branchnil #{branch_stub.shape}")
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.je(branch_stub.target0.address)
branch_asm.jmp(branch_stub.target1.address)
in Next0
branch_asm.jne(branch_stub.target1.address)
in Next1
branch_asm.je(branch_stub.target0.address)
end
end
end
end

# once

# @param jit [RubyVM::RJIT::JITState]
Expand Down Expand Up @@ -3625,21 +3637,25 @@ def jit_chain_guard(opcode, jit, ctx, asm, side_exit, limit: 20)
@exit_compiler.compile_branch_stub(deeper, ocb_asm, branch_stub, true)
@ocb.write(ocb_asm)
end
branch_stub.compile = proc do |branch_asm|
# Not using `asm.comment` here since it's usually put before cmp/test before this.
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.public_send(opcode, branch_stub.target0.address)
end
end
end
branch_stub.compile = compile_jit_chain_guard(branch_stub, opcode:)
branch_stub.compile.call(asm)
else
asm.public_send(opcode, side_exit)
end
end

def compile_jit_chain_guard(branch_stub, opcode:) # Proc escapes arguments in memory
proc do |branch_asm|
# Not using `asm.comment` here since it's usually put before cmp/test before this.
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.public_send(opcode, branch_stub.target0.address)
end
end
end
end

# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
Expand Down Expand Up @@ -5628,16 +5644,7 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
@exit_compiler.compile_branch_stub(return_ctx, ocb_asm, branch_stub, true)
@ocb.write(ocb_asm)
end
branch_stub.compile = proc do |branch_asm|
branch_asm.comment('set jit_return to callee CFP')
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.mov(:rax, branch_stub.target0.address)
branch_asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:jit_return)], :rax)
end
end
end
branch_stub.compile = compile_jit_return(branch_stub, cfp_offset:)
branch_stub.compile.call(asm)
end

Expand All @@ -5648,6 +5655,19 @@ def jit_push_frame(jit, ctx, asm, cme, flags, argc, frame_type, block_handler, i
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], cfp_reg)
end

def compile_jit_return(branch_stub, cfp_offset:) # Proc escapes arguments in memory
proc do |branch_asm|
branch_asm.comment('set jit_return to callee CFP')
branch_asm.stub(branch_stub) do
case branch_stub.shape
in Default
branch_asm.mov(:rax, branch_stub.target0.address)
branch_asm.mov([CFP, cfp_offset + C.rb_control_frame_t.offsetof(:jit_return)], :rax)
end
end
end
end

# CALLER_SETUP_ARG: Return CantCompile if not supported
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
Expand Down Expand Up @@ -5868,7 +5888,12 @@ def jit_direct_jump(iseq, pc, ctx, asm, comment: 'jit_direct_jump')
@exit_compiler.compile_branch_stub(ctx, ocb_asm, branch_stub, true)
@ocb.write(ocb_asm)
end
branch_stub.compile = proc do |branch_asm|
branch_stub.compile = compile_jit_direct_jump(branch_stub, comment:)
branch_stub.compile.call(asm)
end

def compile_jit_direct_jump(branch_stub, comment:) # Proc escapes arguments in memory
proc do |branch_asm|
branch_asm.comment(comment)
branch_asm.stub(branch_stub) do
case branch_stub.shape
Expand All @@ -5879,7 +5904,6 @@ def jit_direct_jump(iseq, pc, ctx, asm, comment: 'jit_direct_jump')
end
end
end
branch_stub.compile.call(asm)
end

# @param jit [RubyVM::RJIT::JITState]
Expand Down

0 comments on commit f263e44

Please sign in to comment.