mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
f6da559d5b
For upstreaming, we want functions we export either prefixed with "rb_" or made static. Historically we haven't been following this rule, so we were "leaking" a lot of symbols as `make leak-globals` would tell us. This change unifies everything YJIT into a single compilation unit, yjit.o, and makes everything unprefixed static to pass `make leak-globals`. This manual "unified build" setup is similar to that of vm.o. Having everything in one compilation unit allows static functions to be visible across YJIT files and removes the need for declarations in headers in some cases. Unnecessary declarations were removed. Other changes of note: - switched to MJIT_SYMBOL_EXPORT_BEGIN which indicates stuff as being off limits for native extensions - the first include of each YJIT file is change to be "internal.h" - undefined MAP_STACK before explicitly redefining it since it collide's with a definition in system headers. Consider renaming?
113 lines
2.1 KiB
C
113 lines
2.1 KiB
C
// This file is a fragment of the yjit.o compilation unit. See yjit.c.
|
|
|
|
// Save caller-save registers on the stack before a C call
|
|
static void
|
|
push_regs(codeblock_t *cb)
|
|
{
|
|
push(cb, RAX);
|
|
push(cb, RCX);
|
|
push(cb, RDX);
|
|
push(cb, RSI);
|
|
push(cb, RDI);
|
|
push(cb, R8);
|
|
push(cb, R9);
|
|
push(cb, R10);
|
|
push(cb, R11);
|
|
pushfq(cb);
|
|
}
|
|
|
|
// Restore caller-save registers from the after a C call
|
|
static void
|
|
pop_regs(codeblock_t *cb)
|
|
{
|
|
popfq(cb);
|
|
pop(cb, R11);
|
|
pop(cb, R10);
|
|
pop(cb, R9);
|
|
pop(cb, R8);
|
|
pop(cb, RDI);
|
|
pop(cb, RSI);
|
|
pop(cb, RDX);
|
|
pop(cb, RCX);
|
|
pop(cb, RAX);
|
|
}
|
|
|
|
static void
|
|
print_int_cfun(int64_t val)
|
|
{
|
|
fprintf(stderr, "%lld\n", (long long int)val);
|
|
}
|
|
|
|
RBIMPL_ATTR_MAYBE_UNUSED()
|
|
static void
|
|
print_int(codeblock_t *cb, x86opnd_t opnd)
|
|
{
|
|
push_regs(cb);
|
|
|
|
if (opnd.num_bits < 64 && opnd.type != OPND_IMM)
|
|
movsx(cb, RDI, opnd);
|
|
else
|
|
mov(cb, RDI, opnd);
|
|
|
|
// Call the print function
|
|
mov(cb, RAX, const_ptr_opnd((void*)&print_int_cfun));
|
|
call(cb, RAX);
|
|
|
|
pop_regs(cb);
|
|
}
|
|
|
|
static void
|
|
print_ptr_cfun(void *val)
|
|
{
|
|
fprintf(stderr, "%p\n", val);
|
|
}
|
|
|
|
RBIMPL_ATTR_MAYBE_UNUSED()
|
|
static void
|
|
print_ptr(codeblock_t *cb, x86opnd_t opnd)
|
|
{
|
|
assert (opnd.num_bits == 64);
|
|
|
|
push_regs(cb);
|
|
|
|
mov(cb, RDI, opnd);
|
|
mov(cb, RAX, const_ptr_opnd((void*)&print_ptr_cfun));
|
|
call(cb, RAX);
|
|
|
|
pop_regs(cb);
|
|
}
|
|
|
|
static void
|
|
print_str_cfun(const char *str)
|
|
{
|
|
fprintf(stderr, "%s\n", str);
|
|
}
|
|
|
|
// Print a constant string to stdout
|
|
static void
|
|
print_str(codeblock_t *cb, const char *str)
|
|
{
|
|
//as.comment("printStr(\"" ~ str ~ "\")");
|
|
size_t len = strlen(str);
|
|
|
|
push_regs(cb);
|
|
|
|
// Load the string address and jump over the string data
|
|
lea(cb, RDI, mem_opnd(8, RIP, 5));
|
|
jmp32(cb, (int32_t)len + 1);
|
|
|
|
// Write the string chars and a null terminator
|
|
for (size_t i = 0; i < len; ++i)
|
|
cb_write_byte(cb, (uint8_t)str[i]);
|
|
cb_write_byte(cb, 0);
|
|
|
|
push(cb, RSP); // Alignment
|
|
|
|
// Call the print function
|
|
mov(cb, RAX, const_ptr_opnd((void*)&print_str_cfun));
|
|
call(cb, RAX);
|
|
|
|
pop(cb, RSP); // Alignment
|
|
|
|
pop_regs(cb);
|
|
}
|