Project

General

Profile

Feature #10185 » 0001-iseq-translate-iseq-inplace.patch

normalperson (Eric Wong), 09/09/2014 08:21 AM

View differences:

compile.c
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 */
/*********************************************/
......
}
#endif
iseq->iseq = (void *)generated_iseq;
iseq->iseq_encoded = (void *)generated_iseq;
iseq->iseq_size = pos;
iseq->stack_max = stack_max;
iseq.c
RSTRING_PTR(iseq->location.path));
}
if (iseq->iseq != iseq->iseq_encoded) {
RUBY_FREE_UNLESS_NULL(iseq->iseq_encoded);
}
RUBY_FREE_UNLESS_NULL(iseq->iseq);
RUBY_FREE_UNLESS_NULL(iseq->iseq_encoded);
RUBY_FREE_UNLESS_NULL(iseq->line_info_table);
RUBY_FREE_UNLESS_NULL(iseq->local_table);
RUBY_FREE_UNLESS_NULL(iseq->is_entries);
......
RUBY_FREE_UNLESS_NULL(iseq->arg_opt_table);
RUBY_FREE_UNLESS_NULL(iseq->arg_keyword_table);
compile_data_free(iseq->compile_data);
RUBY_FREE_UNLESS_NULL(iseq->iseq);
}
ruby_xfree(ptr);
}
......
if (ptr) {
iseq = ptr;
if (!iseq->orig) {
if (iseq->iseq != iseq->iseq_encoded) {
size += iseq->iseq_size * sizeof(VALUE);
}
size += iseq->iseq_size * sizeof(VALUE);
size += iseq->line_info_size * sizeof(struct iseq_line_info_entry);
size += iseq->local_table_size * sizeof(ID);
......
}
size += sizeof(struct iseq_compile_data);
}
if (iseq->iseq) {
size += iseq->iseq_size * sizeof(VALUE);
}
}
}
......
rb_secure(1);
iseq = iseqdat->iseq;
size = iseqdat->iseq_size;
rb_str_cat2(str, "== disasm: ");
......
}
/* show each line */
iseq = rb_iseq_original_iseq(iseqdat);
for (n = 0; n < size;) {
n += rb_iseq_disasm_insn(str, iseq, n, iseqdat, child);
}
......
size_t ti;
unsigned int pos;
unsigned int line = 0;
VALUE *seq;
VALUE *seq, *iseq_original;
VALUE val = rb_ary_new();
VALUE type; /* Symbol */
......
}
/* body */
for (seq = iseq->iseq; seq < iseq->iseq + iseq->iseq_size; ) {
iseq_original = rb_iseq_original_iseq(iseq);
for (seq = iseq_original; seq < iseq_original + iseq->iseq_size; ) {
VALUE insn = *seq++;
int j, len = insn_len(insn);
VALUE *nseq = seq + len - 1;
......
for (j=0; j<len-1; j++, seq++) {
switch (insn_op_type(insn, j)) {
case TS_OFFSET: {
unsigned long idx = nseq - iseq->iseq + *seq;
unsigned long idx = nseq - iseq_original + *seq;
rb_ary_push(ary, register_label(labels_table, idx));
break;
}
......
for (i=0; i<RARRAY_LEN(val); i+=2) {
VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
unsigned long idx = nseq - iseq->iseq + pos;
unsigned long idx = nseq - iseq_original + pos;
rb_ary_store(val, i+1,
register_label(labels_table, idx));
......
RB_OBJ_WRITE(iseq->self, &iseq->mark_ary, 0);
iseq->self = iseqval;
iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
for (i=0; i<iseq->iseq_size; i+=2) {
iseq->iseq[i] = BIN(opt_call_c_function);
iseq->iseq[i+1] = (VALUE)func;
iseq->iseq_encoded[i] = BIN(opt_call_c_function);
iseq->iseq_encoded[i+1] = (VALUE)func;
}
rb_iseq_translate_threaded_code(iseq);
......
size_t insn;
rb_iseq_t *iseq;
int cont = 1;
VALUE *iseq_original;
GetISeqPtr(iseqval, iseq);
iseq_original = rb_iseq_original_iseq(iseq);
for (pos = 0; cont && pos < iseq->iseq_size; pos += insn_len(insn)) {
insn = iseq->iseq[pos];
insn = iseq_original[pos];
if (insn == BIN(trace)) {
rb_event_flag_t current_events = (VALUE)iseq->iseq[pos+1];
rb_event_flag_t current_events = (VALUE)iseq_original[pos+1];
if (current_events & RUBY_EVENT_LINE) {
rb_event_flag_t events = current_events & RUBY_EVENT_SPECIFIED_LINE;
......
/* printf("line: %d\n", line); */
cont = (*func)(line, &events, data);
if (current_events != events) {
iseq->iseq[pos+1] = iseq->iseq_encoded[pos+1] =
iseq_original[pos+1] = iseq->iseq_encoded[pos+1] =
(VALUE)(current_events | (events & RUBY_EVENT_SPECIFIED_LINE));
}
}
iseq.h
/* compile.c */
VALUE rb_iseq_compile_node(VALUE self, NODE *node);
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
VALUE *rb_iseq_original_iseq(rb_iseq_t *iseq);
VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
VALUE exception, VALUE body);
vm_core.h
rb_iseq_location_t location;
VALUE *iseq; /* iseq (insn number and operands) */
VALUE *iseq_encoded; /* encoded iseq */
VALUE *iseq_encoded; /* encoded iseq (insn addr and operands) */
unsigned int iseq_size;
unsigned int line_info_size;
......
/* used at compile time */
struct iseq_compile_data *compile_data;
/* used for debug/dump (TODO: union with compile_data) */
VALUE *iseq;
};
enum ruby_special_exceptions {
vm_dump.c
#include "addr2line.h"
#include "vm_core.h"
#include "internal.h"
#include "iseq.h"
/* see vm_insnhelper.h for the values */
#ifndef VMDEBUG
......
rb_iseq_t *iseq = cfp->iseq;
if (iseq != 0) {
VALUE *seq = iseq->iseq;
ptrdiff_t pc = _pc - iseq->iseq_encoded;
int i;
......
/* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); */
if (pc >= 0) {
rb_iseq_disasm_insn(0, seq, (size_t)pc, iseq, 0);
const VALUE *iseq_original = rb_iseq_original_iseq(iseq);
rb_iseq_disasm_insn(0, iseq_original, (size_t)pc, iseq, 0);
}
}
-
(3-3/3)