Project

General

Profile

Feature #14605 ยป 0001-Remove-original_iseq-from-rb_iseq_constant_body.patch

tenderlovemaking (Aaron Patterson), 03/15/2018 12:32 AM

View differences:

compile.c
761 761
}
762 762
#endif
763 763

  
764
VALUE *
765
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
764
typedef void * iseq_original_seq_t(void *ctx, const rb_iseq_t *iseq, VALUE * original_code);
765

  
766
void *
767
rb_iseq_with_original_iseq(const rb_iseq_t *iseq, iseq_original_seq_t * cb, void *ctx)
766 768
{
767 769
    VALUE *original_code;
768 770

  
769
    if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq);
770
    original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->body->iseq_size);
771
    VALUE str = rb_str_tmp_new(iseq->body->iseq_size * sizeof(VALUE));
772
    original_code = (VALUE *)RSTRING_PTR(str);
771 773
    MEMCPY(original_code, iseq->body->iseq_encoded, VALUE, iseq->body->iseq_size);
772 774

  
773 775
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
......
783 785
	}
784 786
    }
785 787
#endif
786
    return original_code;
788
    return cb(ctx, iseq, original_code);
787 789
}
788 790

  
789 791
/*********************************************/
......
8330 8332
    return (VALUE)rb_global_entry(gid);
8331 8333
}
8332 8334

  
8333
static VALUE *
8334
ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
8335
static void *
8336
ibf_dump_code_i(void *ctx, const rb_iseq_t *iseq, VALUE * orig_code)
8335 8337
{
8338
    struct ibf_dump *dump = (struct ibf_dump *)ctx;
8336 8339
    const int iseq_size = iseq->body->iseq_size;
8337 8340
    int code_index;
8338 8341
    VALUE *code;
8339
    const VALUE *orig_code = rb_iseq_original_iseq(iseq);
8340 8342

  
8341 8343
    code = ALLOCA_N(VALUE, iseq_size);
8342 8344

  
......
8395 8397
    return IBF_W(code, VALUE, iseq_size);
8396 8398
}
8397 8399

  
8400
static VALUE *
8401
ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
8402
{
8403
    return (VALUE *)(rb_iseq_with_original_iseq(iseq, ibf_dump_code_i, (void *)dump));
8404
}
8405

  
8398 8406
static VALUE *
8399 8407
ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct rb_iseq_constant_body *body)
8400 8408
{
......
8726 8734
    dump_body.ci_entries =           ibf_dump_ci_entries(dump, iseq);
8727 8735
    dump_body.cc_entries =           NULL;
8728 8736
    dump_body.variable.coverage      = Qnil;
8729
    dump_body.variable.original_iseq = Qnil;
8730 8737

  
8731 8738
    return ibf_dump_write(dump, &dump_body, sizeof(dump_body));
8732 8739
}
......
8759 8766
    load_body->insns_info.size = body->insns_info.size;
8760 8767

  
8761 8768
    ISEQ_COVERAGE_SET(iseq, Qnil);
8762
    ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
8763 8769
    iseq->body->variable.flip_count = body->variable.flip_count;
8764 8770

  
8765 8771
    {
iseq.c
222 222
	}
223 223

  
224 224
	rb_gc_mark(body->variable.coverage);
225
	rb_gc_mark(body->variable.original_iseq);
226 225
	rb_gc_mark(body->location.label);
227 226
	rb_gc_mark(body->location.base_label);
228 227
	rb_gc_mark(body->location.pathobj);
......
432 431
	RB_OBJ_WRITE(iseq, &iseq->body->location.base_label, iseq->body->local_iseq->body->location.label);
433 432
    }
434 433
    ISEQ_COVERAGE_SET(iseq, Qnil);
435
    ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
436 434
    iseq->body->variable.flip_count = 0;
437 435

  
438 436
    ISEQ_COMPILE_DATA_ALLOC(iseq);
......
1897 1895
    }
1898 1896
}
1899 1897

  
1898
struct iseq_disasm_iter_ctx {
1899
    VALUE str;
1900
    VALUE child;
1901
};
1902

  
1903
static void *
1904
iseq_disasm_iter(void *ctx, const rb_iseq_t *iseq, VALUE *code)
1905
{
1906
    size_t n;
1907
    unsigned int size;
1908

  
1909
    struct iseq_disasm_iter_ctx *ictx = (struct iseq_disasm_iter_ctx *)ctx;
1910
    VALUE str = ictx->str;
1911
    VALUE child = ictx->child;
1912
    size = iseq->body->iseq_size;
1913

  
1914
    for (n = 0; n < size;) {
1915
	n += rb_iseq_disasm_insn(str, code, n, iseq, child);
1916
    }
1917

  
1918
    return NULL;
1919
}
1920

  
1900 1921
VALUE
1901 1922
rb_iseq_disasm(const rb_iseq_t *iseq)
1902 1923
{
1903 1924
    VALUE *code;
1904 1925
    VALUE str = rb_str_new(0, 0);
1905 1926
    VALUE child = rb_ary_tmp_new(3);
1906
    unsigned int size;
1907 1927
    unsigned int i;
1908 1928
    long l;
1909 1929
    size_t n;
......
1912 1932

  
1913 1933
    rb_secure(1);
1914 1934

  
1915
    size = iseq->body->iseq_size;
1916

  
1917 1935
    rb_str_cat2(str, "== disasm: ");
1918 1936

  
1919 1937
    rb_str_concat(str, iseq_inspect(iseq));
......
1995 2013
    }
1996 2014

  
1997 2015
    /* show each line */
1998
    code = rb_iseq_original_iseq(iseq);
1999
    for (n = 0; n < size;) {
2000
	n += rb_iseq_disasm_insn(str, code, n, iseq, child);
2001
    }
2016
    struct iseq_disasm_iter_ctx ctx;
2017
    ctx.str = str;
2018
    ctx.child = child;
2019

  
2020
    rb_iseq_with_original_iseq(iseq, iseq_disasm_iter, (void *)&ctx);
2002 2021

  
2003 2022
    for (l = 0; l < RARRAY_LEN(child); l++) {
2004 2023
	VALUE isv = rb_ary_entry(child, l);
......
2010 2029
    return str;
2011 2030
}
2012 2031

  
2013
static VALUE
2014
rb_iseq_all_children(const rb_iseq_t *iseq)
2032
static void *
2033
rb_iseq_all_children_i(void *ctx, const rb_iseq_t *iseq, VALUE * code)
2015 2034
{
2016 2035
    unsigned int i;
2017
    VALUE *code = rb_iseq_original_iseq(iseq);
2018 2036
    VALUE all_children = rb_obj_hide(rb_ident_hash_new());
2019 2037
    VALUE child;
2020 2038

  
......
2047 2065
	}
2048 2066
	i += len;
2049 2067
    }
2050
    return all_children;
2068
    return (void *)all_children;
2069
}
2070

  
2071
static VALUE
2072
rb_iseq_all_children(const rb_iseq_t *iseq)
2073
{
2074
    return (VALUE)rb_iseq_with_original_iseq(iseq, rb_iseq_all_children_i, NULL);
2051 2075
}
2052 2076

  
2053 2077
/*
......
2300 2324
    return ST_CONTINUE;
2301 2325
}
2302 2326

  
2327
struct iseq_data_to_ary_ctx {
2328
    VALUE * insn_syms;
2329
    struct st_table *labels_table;
2330
    VALUE body;
2331
};
2332

  
2333
static void *
2334
iseq_data_to_ary_i(void * _ctx, const rb_iseq_t *iseq, VALUE * iseq_original)
2335
{
2336
    struct iseq_data_to_ary_ctx * ctx;
2337
    VALUE *seq;
2338
    VALUE *insn_syms;
2339
    VALUE body;
2340
    struct st_table *labels_table;
2341

  
2342
    ctx = (struct iseq_data_to_ary_ctx *)_ctx;
2343
    body = rb_ary_new(); /* [[:insn1, ...], ...] */
2344
    insn_syms = ctx->insn_syms;
2345
    labels_table = ctx->labels_table;
2346

  
2347
    for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
2348
	VALUE insn = *seq++;
2349
	int j, len = insn_len(insn);
2350
	VALUE *nseq = seq + len - 1;
2351
	VALUE ary = rb_ary_new2(len);
2352

  
2353
	rb_ary_push(ary, insn_syms[insn%numberof(insn_syms)]);
2354
	for (j=0; j<len-1; j++, seq++) {
2355
	    switch (insn_op_type(insn, j)) {
2356
	      case TS_OFFSET: {
2357
		unsigned long idx = nseq - iseq_original + *seq;
2358
		rb_ary_push(ary, register_label(labels_table, idx));
2359
		break;
2360
	      }
2361
	      case TS_LINDEX:
2362
	      case TS_NUM:
2363
		rb_ary_push(ary, INT2FIX(*seq));
2364
		break;
2365
	      case TS_VALUE:
2366
		rb_ary_push(ary, obj_resurrect(*seq));
2367
		break;
2368
	      case TS_ISEQ:
2369
		{
2370
		    const rb_iseq_t *iseq = (rb_iseq_t *)*seq;
2371
		    if (iseq) {
2372
			VALUE val = iseq_data_to_ary(rb_iseq_check(iseq));
2373
			rb_ary_push(ary, val);
2374
		    }
2375
		    else {
2376
			rb_ary_push(ary, Qnil);
2377
		    }
2378
		}
2379
		break;
2380
	      case TS_GENTRY:
2381
		{
2382
		    struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
2383
		    rb_ary_push(ary, ID2SYM(entry->id));
2384
		}
2385
		break;
2386
	      case TS_IC:
2387
	      case TS_ISE:
2388
		{
2389
		    union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
2390
		    rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
2391
		}
2392
		break;
2393
	      case TS_CALLINFO:
2394
		{
2395
		    struct rb_call_info *ci = (struct rb_call_info *)*seq;
2396
		    VALUE e = rb_hash_new();
2397
		    int orig_argc = ci->orig_argc;
2398

  
2399
		    rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
2400
		    rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
2401

  
2402
		    if (ci->flag & VM_CALL_KWARG) {
2403
			struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
2404
			int i;
2405
			VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
2406

  
2407
			orig_argc -= ci_kw->kw_arg->keyword_len;
2408
			for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
2409
			    rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
2410
			}
2411
			rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
2412
		    }
2413

  
2414
		    rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")),
2415
				INT2FIX(orig_argc));
2416
		    rb_ary_push(ary, e);
2417
	        }
2418
		break;
2419
	      case TS_CALLCACHE:
2420
		rb_ary_push(ary, Qfalse);
2421
		break;
2422
	      case TS_ID:
2423
		rb_ary_push(ary, ID2SYM(*seq));
2424
		break;
2425
	      case TS_CDHASH:
2426
		{
2427
		    VALUE hash = *seq;
2428
		    VALUE val = rb_ary_new();
2429
		    int i;
2430

  
2431
		    rb_hash_foreach(hash, cdhash_each, val);
2432

  
2433
		    for (i=0; i<RARRAY_LEN(val); i+=2) {
2434
			VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
2435
			unsigned long idx = nseq - iseq_original + pos;
2436

  
2437
			rb_ary_store(val, i+1,
2438
				     register_label(labels_table, idx));
2439
		    }
2440
		    rb_ary_push(ary, val);
2441
		}
2442
		break;
2443
	      case TS_FUNCPTR:
2444
		{
2445
#if SIZEOF_VALUE <= SIZEOF_LONG
2446
		    VALUE val = LONG2NUM((SIGNED_VALUE)*seq);
2447
#else
2448
		    VALUE val = LL2NUM((SIGNED_VALUE)*seq);
2449
#endif
2450
		    rb_ary_push(ary, val);
2451
		}
2452
		break;
2453
	      default:
2454
		rb_bug("unknown operand: %c", insn_op_type(insn, j));
2455
	    }
2456
	}
2457
	rb_ary_push(body, ary);
2458
    }
2459
    return (void *)body;
2460
}
2461

  
2303 2462
static VALUE
2304 2463
iseq_data_to_ary(const rb_iseq_t *iseq)
2305 2464
{
......
2308 2467
    const struct iseq_insn_info_entry *prev_insn_info;
2309 2468
    unsigned int pos;
2310 2469
    int last_line = 0;
2311
    VALUE *seq, *iseq_original;
2312 2470

  
2313 2471
    VALUE val = rb_ary_new();
2314 2472
    VALUE type; /* Symbol */
2315 2473
    VALUE locals = rb_ary_new();
2316 2474
    VALUE params = rb_hash_new();
2317
    VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
2475
    VALUE body;
2318 2476
    VALUE nbody;
2319 2477
    VALUE exception = rb_ary_new(); /* [[....]] */
2320 2478
    VALUE misc = rb_hash_new();
......
2422 2580
    }
2423 2581

  
2424 2582
    /* body */
2425
    iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
2426

  
2427
    for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
2428
	VALUE insn = *seq++;
2429
	int j, len = insn_len(insn);
2430
	VALUE *nseq = seq + len - 1;
2431
	VALUE ary = rb_ary_new2(len);
2432

  
2433
	rb_ary_push(ary, insn_syms[insn%numberof(insn_syms)]);
2434
	for (j=0; j<len-1; j++, seq++) {
2435
	    switch (insn_op_type(insn, j)) {
2436
	      case TS_OFFSET: {
2437
		unsigned long idx = nseq - iseq_original + *seq;
2438
		rb_ary_push(ary, register_label(labels_table, idx));
2439
		break;
2440
	      }
2441
	      case TS_LINDEX:
2442
	      case TS_NUM:
2443
		rb_ary_push(ary, INT2FIX(*seq));
2444
		break;
2445
	      case TS_VALUE:
2446
		rb_ary_push(ary, obj_resurrect(*seq));
2447
		break;
2448
	      case TS_ISEQ:
2449
		{
2450
		    const rb_iseq_t *iseq = (rb_iseq_t *)*seq;
2451
		    if (iseq) {
2452
			VALUE val = iseq_data_to_ary(rb_iseq_check(iseq));
2453
			rb_ary_push(ary, val);
2454
		    }
2455
		    else {
2456
			rb_ary_push(ary, Qnil);
2457
		    }
2458
		}
2459
		break;
2460
	      case TS_GENTRY:
2461
		{
2462
		    struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
2463
		    rb_ary_push(ary, ID2SYM(entry->id));
2464
		}
2465
		break;
2466
	      case TS_IC:
2467
	      case TS_ISE:
2468
		{
2469
		    union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
2470
		    rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
2471
		}
2472
		break;
2473
	      case TS_CALLINFO:
2474
		{
2475
		    struct rb_call_info *ci = (struct rb_call_info *)*seq;
2476
		    VALUE e = rb_hash_new();
2477
		    int orig_argc = ci->orig_argc;
2478

  
2479
		    rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
2480
		    rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
2481

  
2482
		    if (ci->flag & VM_CALL_KWARG) {
2483
			struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
2484
			int i;
2485
			VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
2486

  
2487
			orig_argc -= ci_kw->kw_arg->keyword_len;
2488
			for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
2489
			    rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
2490
			}
2491
			rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
2492
		    }
2493

  
2494
		    rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")),
2495
				INT2FIX(orig_argc));
2496
		    rb_ary_push(ary, e);
2497
	        }
2498
		break;
2499
	      case TS_CALLCACHE:
2500
		rb_ary_push(ary, Qfalse);
2501
		break;
2502
	      case TS_ID:
2503
		rb_ary_push(ary, ID2SYM(*seq));
2504
		break;
2505
	      case TS_CDHASH:
2506
		{
2507
		    VALUE hash = *seq;
2508
		    VALUE val = rb_ary_new();
2509
		    int i;
2510

  
2511
		    rb_hash_foreach(hash, cdhash_each, val);
2512

  
2513
		    for (i=0; i<RARRAY_LEN(val); i+=2) {
2514
			VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
2515
			unsigned long idx = nseq - iseq_original + pos;
2516

  
2517
			rb_ary_store(val, i+1,
2518
				     register_label(labels_table, idx));
2519
		    }
2520
		    rb_ary_push(ary, val);
2521
		}
2522
		break;
2523
	      case TS_FUNCPTR:
2524
		{
2525
#if SIZEOF_VALUE <= SIZEOF_LONG
2526
		    VALUE val = LONG2NUM((SIGNED_VALUE)*seq);
2527
#else
2528
		    VALUE val = LL2NUM((SIGNED_VALUE)*seq);
2529
#endif
2530
		    rb_ary_push(ary, val);
2531
		}
2532
		break;
2533
	      default:
2534
		rb_bug("unknown operand: %c", insn_op_type(insn, j));
2535
	    }
2536
	}
2537
	rb_ary_push(body, ary);
2538
    }
2539

  
2540
    nbody = body;
2583
    struct iseq_data_to_ary_ctx ctx;
2584
    ctx.insn_syms = insn_syms;
2585
    ctx.labels_table = labels_table;
2586
    nbody = (VALUE)rb_iseq_with_original_iseq(iseq, iseq_data_to_ary_i, &ctx);
2587
    RB_GC_GUARD(nbody);
2541 2588

  
2542 2589
    /* exception */
2543 2590
    if (iseq->body->catch_table) for (i=0; i<iseq->body->catch_table->size; i++) {
......
2766 2813
#define INSN_CODE(insn) (insn)
2767 2814
#endif
2768 2815

  
2816
static void *
2817
rb_iseq_trace_set_i(void * ctx, const rb_iseq_t *iseq, VALUE *code)
2818
{
2819
    unsigned int i;
2820
    rb_event_flag_t turnon_events = *(rb_event_flag_t*)ctx;
2821
    VALUE *iseq_encoded = (VALUE *)iseq->body->iseq_encoded;
2822
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
2823
    const void * const *table = rb_vm_get_insns_address_table();
2824
#endif
2825
    ((rb_iseq_t *)iseq)->aux.trace_events = turnon_events;
2826

  
2827
    for (i=0; i<iseq->body->iseq_size;) {
2828
	int insn = (int)code[i];
2829
	rb_event_flag_t events = rb_iseq_event_flags(iseq, i);
2830

  
2831
	/* code represents before transformation */
2832
	VM_ASSERT(insn < VM_INSTRUCTION_SIZE/2);
2833

  
2834
	if (events & turnon_events) {
2835
	    if (!TRACE_INSN_P(insn)) {
2836
		iseq_encoded[i] = INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
2837
	    }
2838
	}
2839
	else if (TRACE_INSN_P(insn)) {
2840
	    iseq_encoded[i] = INSN_CODE(insn - VM_INSTRUCTION_SIZE/2);
2841
	}
2842
	i += insn_len(insn);
2843
    }
2844
    return NULL;
2845
}
2846

  
2769 2847
void
2770 2848
rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
2771 2849
{
......
2779 2857
	return;
2780 2858
    }
2781 2859
    else {
2782
	unsigned int i;
2783
	VALUE *iseq_encoded = (VALUE *)iseq->body->iseq_encoded;
2784
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
2785
	VALUE *code = rb_iseq_original_iseq(iseq);
2786
	const void * const *table = rb_vm_get_insns_address_table();
2787
#else
2788
	const VALUE *code = iseq->body->iseq_encoded;
2789
#endif
2790
	((rb_iseq_t *)iseq)->aux.trace_events = turnon_events;
2791

  
2792
	for (i=0; i<iseq->body->iseq_size;) {
2793
	    int insn = (int)code[i];
2794
	    rb_event_flag_t events = rb_iseq_event_flags(iseq, i);
2795

  
2796
	    if (events & turnon_events) {
2797
		if (!TRACE_INSN_P(insn)) {
2798
		    iseq_encoded[i] = INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
2799
		}
2800
	    }
2801
	    else if (TRACE_INSN_P(insn)) {
2802
		iseq_encoded[i] = INSN_CODE(insn - VM_INSTRUCTION_SIZE/2);
2803
	    }
2804
	    i += insn_len(insn);
2805
	}
2806
	/* clear for debugging: ISEQ_ORIGINAL_ISEQ_CLEAR(iseq); */
2860
	rb_iseq_with_original_iseq(iseq, rb_iseq_trace_set_i, &turnon_events);
2807 2861
    }
2808 2862
}
2809 2863

  
iseq.h
43 43
    return cnt;
44 44
}
45 45

  
46
static inline VALUE *
47
ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
48
{
49
    VALUE str = iseq->body->variable.original_iseq;
50
    if (RTEST(str)) return (VALUE *)RSTRING_PTR(str);
51
    return NULL;
52
}
53

  
54
static inline void
55
ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq)
56
{
57
    RB_OBJ_WRITE(iseq, &iseq->body->variable.original_iseq, Qnil);
58
}
59

  
60
static inline VALUE *
61
ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
62
{
63
    VALUE str = rb_str_tmp_new(size * sizeof(VALUE));
64
    RB_OBJ_WRITE(iseq, &iseq->body->variable.original_iseq, str);
65
    return (VALUE *)RSTRING_PTR(str);
66
}
67

  
68 46
#define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE  | \
69 47
			   RUBY_EVENT_CLASS | \
70 48
			   RUBY_EVENT_END   | \
......
150 128
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node);
151 129
VALUE rb_iseq_compile_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *ifunc);
152 130
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
153
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
131

  
132
typedef void * iseq_original_seq_t(void *ctx, const rb_iseq_t *iseq, VALUE * original_code);
133
void * rb_iseq_with_original_iseq(const rb_iseq_t *iseq, iseq_original_seq_t * cb, void *ctx);
134

  
154 135
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
155 136
			    VALUE locals, VALUE args,
156 137
			    VALUE exception, VALUE body);
vm_core.h
414 414
    struct {
415 415
      rb_snum_t flip_count;
416 416
      VALUE coverage;
417
      VALUE original_iseq;
418 417
    } variable;
419 418

  
420 419
    unsigned int local_table_size;
vm_dump.c
329 329
    rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec);
330 330
}
331 331

  
332
static void *
333
rb_vmdebug_debug_print_pre_i(void * ctx, const rb_iseq_t *iseq, VALUE * iseq_original)
334
{
335
    size_t pc = *(size_t *)ctx;
336
    rb_iseq_disasm_insn(0, iseq_original, (size_t)pc, iseq, 0);
337
    return NULL;
338
}
339

  
332 340
void
333 341
rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc)
334 342
{
......
346 354

  
347 355
	/* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(ec, cfp)); */
348 356
	if (pc >= 0) {
349
	    const VALUE *iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
350

  
351
	    rb_iseq_disasm_insn(0, iseq_original, (size_t)pc, iseq, 0);
357
	    rb_iseq_with_original_iseq(iseq, rb_vmdebug_debug_print_pre_i, &pc);
352 358
	}
353 359
    }
354 360