summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2020-09-03 12:06:53 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:22 -0400
commit16c5ce863c06dd3ae5562f4ed86fb40ced670c69 (patch)
treea5153dbef5775eab4a7d28ca05fda694bdfac2ff /iseq.c
parentcec197696f3edcff553373e9597130fde2d1f7be (diff)
Yeah, this actually works!
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/iseq.c b/iseq.c
index 6928a711ed..67af3371dd 100644
--- a/iseq.c
+++ b/iseq.c
@@ -42,6 +42,10 @@
#include "builtin.h"
#include "insns.inc"
#include "insns_info.inc"
+#include <sys/mman.h>
+#include "ujit_examples.h"
+
+uint8_t *native_pop_code; // TODO: hack. see addr2insn
VALUE rb_cISeq;
static VALUE iseqw_new(const rb_iseq_t *iseq);
@@ -3205,6 +3209,22 @@ rb_vm_encoded_insn_data_table_init(void)
st_add_direct(encoded_insn_data, key1, (st_data_t)&insn_data[insn]);
st_add_direct(encoded_insn_data, key2, (st_data_t)&insn_data[insn]);
}
+
+ native_pop_code = mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
+ if (native_pop_code == MAP_FAILED) rb_bug("mmap failed");
+ uint8_t *head = native_pop_code;
+ memcpy(head, ujit_pre_call_bytes, sizeof(ujit_pre_call_bytes));
+ head += sizeof(ujit_pre_call_bytes);
+ const uint8_t handmade_pop[] = { // TODO assmeble this from a separate file
+ 0x48, 0x83, 0x6f, 0x08, 0x08, // subq $8, 8(%rdi)
+ 0x48, 0x83, 0xc6, 0x08, // addq $8, %rsi
+ 0x48, 0x89, 0x37, // movq %rsi, (%rdi)
+ 0x48, 0x89, 0xf0 // movq %rsi, %rax
+ };
+ memcpy(head, handmade_pop, sizeof(handmade_pop));
+ head += sizeof(handmade_pop);
+ memcpy(head, ujit_post_call_bytes, sizeof(ujit_post_call_bytes));
+ // TODO this is small enough to fit in the page we allocated but that can change
}
int
@@ -3218,6 +3238,12 @@ rb_vm_insn_addr2insn(const void *addr)
return (int)e->insn;
}
+ // TODO this is a hack. The proper way to do this is to refactor this so that it takes
+ // the iseq body.
+ if (addr && addr == native_pop_code) {
+ return BIN(pop);
+ }
+
rb_bug("rb_vm_insn_addr2insn: invalid insn address: %p", addr);
}
@@ -3248,6 +3274,12 @@ encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon,
return e->insn_len;
}
+ // TODO this is a hack. The proper way to do this is to refactor this so that it takes
+ // the iseq body.
+ if (key && (uint8_t *)key == native_pop_code) {
+ return insn_len(BIN(pop));
+ }
+
rb_bug("trace_instrument: invalid insn address: %p", (void *)*iseq_encoded_insn);
}
@@ -3456,7 +3488,7 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data)
}
VALUE *
-rb_ujit_empty_func(rb_control_frame_t *cfp)
+rb_ujit_empty_func(rb_control_frame_t *cfp, const VALUE *pc)
{
// okay, not really empty, so maybe think of another name.
// it's put in this file instead of say, compile.c to dodge long C compile time.