diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-06 22:35:38 -0800 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-06 23:44:01 -0800 |
commit | eaccdc1941304d6273397b21c25213174d892185 (patch) | |
tree | 93a2ab9455ccf56c55cd01370007703d75b80627 /rjit_c.c | |
parent | 854546fcc468fc6a49588bdbf6df77aa185493a1 (diff) | |
download | ruby-eaccdc1941304d6273397b21c25213174d892185.tar.gz |
Rename MJIT filenames to RJIT
Diffstat (limited to 'rjit_c.c')
-rw-r--r-- | rjit_c.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/rjit_c.c b/rjit_c.c new file mode 100644 index 0000000000..9af89c649d --- /dev/null +++ b/rjit_c.c @@ -0,0 +1,125 @@ +/********************************************************************** + + mjit_c.c - C helpers for MJIT + + Copyright (C) 2017 Takashi Kokubun <k0kubun@ruby-lang.org>. + +**********************************************************************/ + +#include "ruby/internal/config.h" // defines USE_MJIT + +// ISO C requires a translation unit to contain at least one declaration +void rb_mjit_c(void) {} + +#if USE_MJIT + +#include "mjit.h" +#include "mjit_c.h" +#include "internal.h" +#include "internal/compile.h" +#include "internal/fixnum.h" +#include "internal/hash.h" +#include "internal/sanitizers.h" +#include "internal/gc.h" +#include "yjit.h" +#include "vm_insnhelper.h" + +#include "insns.inc" +#include "insns_info.inc" + +#if SIZEOF_LONG == SIZEOF_VOIDP +#define NUM2PTR(x) NUM2ULONG(x) +#define PTR2NUM(x) ULONG2NUM(x) +#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP +#define NUM2PTR(x) NUM2ULL(x) +#define PTR2NUM(x) ULL2NUM(x) +#endif + +// An offsetof implementation that works for unnamed struct and union. +// Multiplying 8 for compatibility with libclang's offsetof. +#define OFFSETOF(ptr, member) RB_SIZE2NUM(((char *)&ptr.member - (char*)&ptr) * 8) + +#define SIZEOF(type) RB_SIZE2NUM(sizeof(type)) +#define SIGNED_TYPE_P(type) RBOOL((type)(-1) < (type)(1)) + +#if MJIT_STATS +// Insn side exit counters +static size_t mjit_insn_exits[VM_INSTRUCTION_SIZE] = { 0 }; +#endif // YJIT_STATS + +// macOS: brew install capstone +// Ubuntu/Debian: apt-get install libcapstone-dev +// Fedora: dnf -y install capstone-devel +#ifdef HAVE_LIBCAPSTONE +#include <capstone/capstone.h> +#endif + +// Return an array of [address, mnemonic, op_str] +static VALUE +dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to) +{ + VALUE result = rb_ary_new(); +#ifdef HAVE_LIBCAPSTONE + // Prepare for calling cs_disasm + static csh handle; + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) { + rb_raise(rb_eRuntimeError, "failed to make Capstone handle"); + } + size_t from_addr = NUM2SIZET(from); + size_t to_addr = NUM2SIZET(to); + + // Call cs_disasm and convert results to a Ruby array + cs_insn *insns; + size_t count = cs_disasm(handle, (const uint8_t *)from_addr, to_addr - from_addr, from_addr, 0, &insns); + for (size_t i = 0; i < count; i++) { + VALUE vals = rb_ary_new_from_args(3, LONG2NUM(insns[i].address), rb_str_new2(insns[i].mnemonic), rb_str_new2(insns[i].op_str)); + rb_ary_push(result, vals); + } + + // Free memory used by capstone + cs_free(insns, count); + cs_close(&handle); +#endif + return result; +} + +// Same as `RubyVM::MJIT.enabled?`, but this is used before it's defined. +static VALUE +mjit_enabled_p(rb_execution_context_t *ec, VALUE self) +{ + return RBOOL(mjit_enabled); +} + +static int +for_each_iseq_i(void *vstart, void *vend, size_t stride, void *data) +{ + VALUE block = (VALUE)data; + VALUE v = (VALUE)vstart; + for (; v != (VALUE)vend; v += stride) { + void *ptr = asan_poisoned_object_p(v); + asan_unpoison_object(v, false); + + if (rb_obj_is_iseq(v)) { + extern VALUE rb_mjit_iseq_new(rb_iseq_t *iseq); + rb_iseq_t *iseq = (rb_iseq_t *)v; + rb_funcall(block, rb_intern("call"), 1, rb_mjit_iseq_new(iseq)); + } + + asan_poison_object_if(ptr, v); + } + return 0; +} + +static VALUE +mjit_for_each_iseq(rb_execution_context_t *ec, VALUE self, VALUE block) +{ + rb_objspace_each_objects(for_each_iseq_i, (void *)block); + return Qnil; +} + +extern bool rb_simple_iseq_p(const rb_iseq_t *iseq); +extern ID rb_get_symbol_id(VALUE name); + +#include "mjit_c.rbinc" + +#endif // USE_MJIT |