summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/compile.c b/compile.c
index 434d385aa8..5b778e0ccf 100644
--- a/compile.c
+++ b/compile.c
@@ -569,21 +569,56 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
const void * const *table = rb_vm_get_insns_address_table();
unsigned int i;
- iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
- MEMCPY(iseq->iseq_encoded, iseq->iseq, VALUE, iseq->iseq_size);
-
for (i = 0; i < iseq->iseq_size; /* */ ) {
int insn = (int)iseq->iseq_encoded[i];
int len = insn_len(insn);
iseq->iseq_encoded[i] = (VALUE)table[insn];
i += len;
}
-#else
- iseq->iseq_encoded = iseq->iseq;
#endif
return COMPILE_OK;
}
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+static int
+rb_vm_addr2insn(const void *addr) /* cold path */
+{
+ int insn;
+ const void * const *table = rb_vm_get_insns_address_table();
+
+ for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
+ if (table[insn] == addr)
+ return insn;
+ }
+ rb_bug("rb_vm_addr2insn: invalid insn address: %p", addr);
+}
+#endif
+
+VALUE *
+rb_iseq_original_iseq(rb_iseq_t *iseq) /* cold path */
+{
+ if (iseq->iseq) return iseq->iseq;
+
+ iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
+
+ MEMCPY(iseq->iseq, iseq->iseq_encoded, VALUE, iseq->iseq_size);
+
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ {
+ unsigned int i;
+
+ for (i = 0; i < iseq->iseq_size; /* */ ) {
+ const void *addr = (const void *)iseq->iseq[i];
+ int insn = (VALUE)rb_vm_addr2insn(addr);
+
+ iseq->iseq[i] = insn;
+ i += insn_len(insn);
+ }
+ }
+#endif
+ return iseq->iseq;
+}
+
/*********************************************/
/* definition of data structure for compiler */
/*********************************************/
@@ -1645,7 +1680,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
}
#endif
- iseq->iseq = (void *)generated_iseq;
+ iseq->iseq_encoded = (void *)generated_iseq;
iseq->iseq_size = pos;
iseq->stack_max = stack_max;