JIT: recognize unsafe-struct-ref argument sequences

A `struct-copy` form can generates a call for a constructor that
includes a sequence of `unsafe-struct-ref` arguments. Each
`unsafe-struct-ref` must still check for a chaperone. Make the JIT
recognize that pattern an turn it into a single test instead of
one test per `unsafe-struct-ref`.
This commit is contained in:
Matthew Flatt 2016-08-15 22:36:30 -06:00
parent 232c80e340
commit 36548ea289
10 changed files with 381 additions and 154 deletions

View File

@ -904,6 +904,32 @@
))
;; Check JIT handling of structure-reference sequencese
(parameterize ([current-namespace (make-base-namespace)]
[eval-jit-enabled #t])
(eval '(module paper racket/base
(provide (all-defined-out))
(struct paper (width height folds) #:transparent)
(define (fold-letter l)
(for/fold ([l l]) ([i (in-range 100)])
(and (paper? l)
(struct-copy paper l [folds i]))))
(define (refine-letter l)
(for/fold ([l l]) ([i (in-range 100)])
(and (paper? l)
(struct-copy paper l [width i]))))))
(eval '(require 'paper))
(eval '(define letter (paper 8.5 11 0)))
(eval '(define formal-letter (chaperone-struct letter paper-height
(lambda (s v)
(unless (equal? v 11)
(error "wrong"))
v))))
(test #t eval '(equal? (fold-letter letter) (paper 8.5 11 99)))
(test #t eval '(equal? (fold-letter formal-letter) (paper 8.5 11 99)))
(test #t eval '(equal? (refine-letter letter) (paper 99 11 0)))
(test #t eval '(equal? (refine-letter formal-letter) (paper 99 11 0))))
(define (comp=? c1 c2 want-same?)
(let ([s1 (open-output-bytes)]
[s2 (open-output-bytes)])

View File

@ -191,6 +191,7 @@
s_v
iSi_s
siS_v
Sii_s
z_p
si_s
sis_v

View File

@ -319,7 +319,7 @@ struct scheme_jit_common_record {
void *flvector_ref_check_index_code[JIT_NUM_FL_KINDS];
void *flvector_set_check_index_code[JIT_NUM_FL_KINDS], *flvector_set_flonum_check_index_code[JIT_NUM_FL_KINDS];
void *fxvector_ref_code, *fxvector_ref_check_index_code, *fxvector_set_code, *fxvector_set_check_index_code;
void *struct_raw_ref_code, *struct_raw_set_code;
void *struct_raw_ref_code, *struct_raw_set_code, *struct_raw_refs_code;
void *syntax_e_code;
void *on_demand_jit_arity_code, *in_progress_on_demand_jit_arity_code;
void *get_stack_pointer_code;

View File

@ -96,6 +96,7 @@ define_ts_ss_s(scheme_byte_string_eq_2, FSRC_MARKS)
define_ts_s_s(scheme_unbox, FSRC_MARKS)
define_ts_si_s(scheme_struct_ref, FSRC_MARKS)
define_ts_sis_v(scheme_struct_set, FSRC_MARKS)
define_ts_Sii_s(unsafe_struct_refs, FSRC_MARKS)
define_ts_iS_s(scheme_extract_checked_procedure, FSRC_MARKS)
define_ts_iS_s(scheme_procedure_arity_includes, FSRC_MARKS)
define_ts_ssi_s(vector_check_chaperone_of, FSRC_MARKS)
@ -219,6 +220,7 @@ define_ts_s_s(scheme_box, FSRC_OTHER)
# define ts_scheme_byte_string_length scheme_byte_string_length
# define ts_scheme_struct_ref scheme_struct_ref
# define ts_scheme_struct_set scheme_struct_set
# define ts_unsafe_struct_refs unsafe_struct_refs
# define ts_equal_as_bool equal_as_bool
# define ts_scheme_string_eq_2 scheme_string_eq_2
# define ts_scheme_byte_string_eq_2 scheme_byte_string_eq_2

View File

@ -187,59 +187,68 @@ static void ts_ ## id(Scheme_Object* g216, int g217, Scheme_Object** g218) \
else \
id(g216, g217, g218); \
}
#define define_ts_z_p(id, src_type) \
static void* ts_ ## id(size_t g219) \
#define define_ts_Sii_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object** g219, int g220, int g221) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_z_p("[" #id "]", src_type, id, g219); \
return scheme_rtcall_Sii_s("[" #id "]", src_type, id, g219, g220, g221); \
else \
return id(g219); \
return id(g219, g220, g221); \
}
#define define_ts_z_p(id, src_type) \
static void* ts_ ## id(size_t g222) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_z_p("[" #id "]", src_type, id, g222); \
else \
return id(g222); \
}
#define define_ts_si_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g220, int g221) \
static Scheme_Object* ts_ ## id(Scheme_Object* g223, int g224) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_si_s("[" #id "]", src_type, id, g220, g221); \
return scheme_rtcall_si_s("[" #id "]", src_type, id, g223, g224); \
else \
return id(g220, g221); \
return id(g223, g224); \
}
#define define_ts_sis_v(id, src_type) \
static void ts_ ## id(Scheme_Object* g222, int g223, Scheme_Object* g224) \
static void ts_ ## id(Scheme_Object* g225, int g226, Scheme_Object* g227) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_sis_v("[" #id "]", src_type, id, g222, g223, g224); \
scheme_rtcall_sis_v("[" #id "]", src_type, id, g225, g226, g227); \
else \
id(g222, g223, g224); \
id(g225, g226, g227); \
}
#define define_ts_ss_i(id, src_type) \
static int ts_ ## id(Scheme_Object* g225, Scheme_Object* g226) \
static int ts_ ## id(Scheme_Object* g228, Scheme_Object* g229) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g225, g226); \
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g228, g229); \
else \
return id(g225, g226); \
return id(g228, g229); \
}
#define define_ts_iSp_v(id, src_type) \
static void ts_ ## id(int g227, Scheme_Object** g228, void* g229) \
static void ts_ ## id(int g230, Scheme_Object** g231, void* g232) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g227, g228, g229); \
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g230, g231, g232); \
else \
id(g227, g228, g229); \
id(g230, g231, g232); \
}
#define define_ts_sss_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g230, Scheme_Object* g231, Scheme_Object* g232) \
static Scheme_Object* ts_ ## id(Scheme_Object* g233, Scheme_Object* g234, Scheme_Object* g235) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g230, g231, g232); \
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g233, g234, g235); \
else \
return id(g230, g231, g232); \
return id(g233, g234, g235); \
}
#define define_ts__v(id, src_type) \
static void ts_ ## id() \
@ -251,11 +260,11 @@ static void ts_ ## id() \
id(); \
}
#define define_ts_iS_v(id, src_type) \
static void ts_ ## id(int g233, Scheme_Object** g234) \
static void ts_ ## id(int g236, Scheme_Object** g237) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_iS_v("[" #id "]", src_type, id, g233, g234); \
scheme_rtcall_iS_v("[" #id "]", src_type, id, g236, g237); \
else \
id(g233, g234); \
id(g236, g237); \
}

View File

@ -1,4 +1,4 @@
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g235, int g236, Scheme_Object** g237)
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g238, int g239, Scheme_Object** g240)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -13,9 +13,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g235;
future->arg_i1 = g236;
future->arg_S2 = g237;
future->arg_s0 = g238;
future->arg_i1 = g239;
future->arg_S2 = g240;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -25,7 +25,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g238, Scheme_Object** g239, Scheme_Object* g240)
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g241, Scheme_Object** g242, Scheme_Object* g243)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -40,9 +40,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g238;
future->arg_S1 = g239;
future->arg_s2 = g240;
future->arg_i0 = g241;
future->arg_S1 = g242;
future->arg_s2 = g243;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -52,7 +52,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g241)
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g244)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -67,8 +67,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g241;
send_special_result(future, g241);
future->arg_s0 = g244;
send_special_result(future, g244);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -77,7 +77,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Lambda* g242)
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Lambda* g245)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -92,7 +92,7 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_n0 = g242;
future->arg_n0 = g245;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -127,7 +127,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g243, Scheme_Object* g244)
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g246, Scheme_Object* g247)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -142,8 +142,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g243;
future->arg_s1 = g244;
future->arg_s0 = g246;
future->arg_s1 = g247;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -153,7 +153,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g245, Scheme_Object* g246, int g247)
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g248, Scheme_Object* g249, int g250)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -168,9 +168,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g245;
future->arg_s1 = g246;
future->arg_i2 = g247;
future->arg_s0 = g248;
future->arg_s1 = g249;
future->arg_i2 = g250;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -180,7 +180,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g248, const Scheme_Object* g249)
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g251, const Scheme_Object* g252)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -195,8 +195,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_t0 = g248;
future->arg_t1 = g249;
future->arg_t0 = g251;
future->arg_t1 = g252;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -206,7 +206,7 @@
receive_special_result(future, retval, 1);
return retval;
}
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g250, Scheme_Object* g251)
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g253, Scheme_Object* g254)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -221,8 +221,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g250;
future->arg_s1 = g251;
future->arg_s0 = g253;
future->arg_s1 = g254;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -232,7 +232,7 @@
return retval;
}
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g252, intptr_t g253)
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g255, intptr_t g256)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -247,8 +247,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_S0 = g252;
future->arg_l1 = g253;
future->arg_S0 = g255;
future->arg_l1 = g256;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -258,7 +258,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g254)
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g257)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -273,7 +273,7 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_l0 = g254;
future->arg_l0 = g257;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -283,7 +283,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g255, Scheme_Object* g256, int g257)
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g258, Scheme_Object* g259, int g260)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -298,9 +298,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_b0 = g255;
future->arg_s1 = g256;
future->arg_i2 = g257;
future->arg_b0 = g258;
future->arg_s1 = g259;
future->arg_i2 = g260;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -310,7 +310,7 @@
}
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g258, int g259, Scheme_Object** g260)
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g261, int g262, Scheme_Object** g263)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -325,9 +325,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g258;
future->arg_i1 = g259;
future->arg_S2 = g260;
future->arg_i0 = g261;
future->arg_i1 = g262;
future->arg_S2 = g263;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -337,7 +337,7 @@
}
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g261, Scheme_Object* g262)
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g264, Scheme_Object* g265)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -352,8 +352,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g261;
future->arg_s1 = g262;
future->arg_s0 = g264;
future->arg_s1 = g265;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -363,7 +363,7 @@
}
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g263)
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g266)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -378,7 +378,7 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_b0 = g263;
future->arg_b0 = g266;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -388,7 +388,7 @@
}
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g264, intptr_t g265)
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g267, intptr_t g268)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -403,8 +403,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g264;
future->arg_l1 = g265;
future->arg_s0 = g267;
future->arg_l1 = g268;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -414,7 +414,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g266, Scheme_Object** g267)
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g269, Scheme_Object** g270)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -429,8 +429,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g266;
future->arg_S1 = g267;
future->arg_i0 = g269;
future->arg_S1 = g270;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -440,7 +440,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g268)
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g271)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -455,7 +455,7 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_S0 = g268;
future->arg_S0 = g271;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -465,7 +465,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g269)
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g272)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -480,8 +480,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g269;
send_special_result(future, g269);
future->arg_s0 = g272;
send_special_result(future, g272);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -490,7 +490,7 @@
}
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g270, Scheme_Object** g271, int g272)
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g273, Scheme_Object** g274, int g275)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -505,9 +505,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g270;
future->arg_S1 = g271;
future->arg_i2 = g272;
future->arg_i0 = g273;
future->arg_S1 = g274;
future->arg_i2 = g275;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -517,7 +517,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g273, int g274, Scheme_Object** g275)
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g276, int g277, Scheme_Object** g278)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -532,9 +532,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g273;
future->arg_i1 = g274;
future->arg_S2 = g275;
future->arg_s0 = g276;
future->arg_i1 = g277;
future->arg_S2 = g278;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -544,7 +544,34 @@
}
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g276)
Scheme_Object* scheme_rtcall_Sii_s(const char *who, int src_type, prim_Sii_s f, Scheme_Object** g279, int g280, int g281)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
future_t *future;
double tm;
Scheme_Object* retval;
future = fts->thread->current_ft;
future->prim_protocol = SIG_Sii_s;
future->prim_func = f;
tm = get_future_timestamp();
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_S0 = g279;
future->arg_i1 = g280;
future->arg_i2 = g281;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
future->retval_s = 0;
receive_special_result(future, retval, 1);
return retval;
}
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g282)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -559,7 +586,7 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_z0 = g276;
future->arg_z0 = g282;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -569,7 +596,7 @@
return retval;
}
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g277, int g278)
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g283, int g284)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -584,8 +611,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g277;
future->arg_i1 = g278;
future->arg_s0 = g283;
future->arg_i1 = g284;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -595,7 +622,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g279, int g280, Scheme_Object* g281)
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g285, int g286, Scheme_Object* g287)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -610,9 +637,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g279;
future->arg_i1 = g280;
future->arg_s2 = g281;
future->arg_s0 = g285;
future->arg_i1 = g286;
future->arg_s2 = g287;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -622,7 +649,7 @@
}
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g282, Scheme_Object* g283)
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g288, Scheme_Object* g289)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -637,8 +664,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g282;
future->arg_s1 = g283;
future->arg_s0 = g288;
future->arg_s1 = g289;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -648,7 +675,7 @@
return retval;
}
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g284, Scheme_Object** g285, void* g286)
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g290, Scheme_Object** g291, void* g292)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -663,9 +690,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g284;
future->arg_S1 = g285;
future->arg_p2 = g286;
future->arg_i0 = g290;
future->arg_S1 = g291;
future->arg_p2 = g292;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -675,7 +702,7 @@
}
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g287, Scheme_Object* g288, Scheme_Object* g289)
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g293, Scheme_Object* g294, Scheme_Object* g295)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -690,9 +717,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g287;
future->arg_s1 = g288;
future->arg_s2 = g289;
future->arg_s0 = g293;
future->arg_s1 = g294;
future->arg_s2 = g295;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
@ -727,7 +754,7 @@
}
void scheme_rtcall_iS_v(const char *who, int src_type, prim_iS_v f, int g290, Scheme_Object** g291)
void scheme_rtcall_iS_v(const char *who, int src_type, prim_iS_v f, int g296, Scheme_Object** g297)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -742,8 +769,8 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g290;
future->arg_S1 = g291;
future->arg_i0 = g296;
future->arg_S1 = g297;
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;

View File

@ -1,87 +1,90 @@
#define SIG_siS_s 11
typedef Scheme_Object* (*prim_siS_s)(Scheme_Object*, int, Scheme_Object**);
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g349, int g350, Scheme_Object** g351);
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g358, int g359, Scheme_Object** g360);
#define SIG_iSs_s 12
typedef Scheme_Object* (*prim_iSs_s)(int, Scheme_Object**, Scheme_Object*);
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g352, Scheme_Object** g353, Scheme_Object* g354);
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g361, Scheme_Object** g362, Scheme_Object* g363);
#define SIG_s_s 13
typedef Scheme_Object* (*prim_s_s)(Scheme_Object*);
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g355);
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g364);
#define SIG_n_s 14
typedef Scheme_Object* (*prim_n_s)(Scheme_Native_Lambda*);
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Lambda* g356);
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Lambda* g365);
#define SIG__s 15
typedef Scheme_Object* (*prim__s)();
Scheme_Object* scheme_rtcall__s(const char *who, int src_type, prim__s f );
#define SIG_ss_s 16
typedef Scheme_Object* (*prim_ss_s)(Scheme_Object*, Scheme_Object*);
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g357, Scheme_Object* g358);
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g366, Scheme_Object* g367);
#define SIG_ssi_s 17
typedef Scheme_Object* (*prim_ssi_s)(Scheme_Object*, Scheme_Object*, int);
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g359, Scheme_Object* g360, int g361);
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g368, Scheme_Object* g369, int g370);
#define SIG_tt_s 18
typedef Scheme_Object* (*prim_tt_s)(const Scheme_Object*, const Scheme_Object*);
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g362, const Scheme_Object* g363);
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g371, const Scheme_Object* g372);
#define SIG_ss_m 19
typedef MZ_MARK_STACK_TYPE (*prim_ss_m)(Scheme_Object*, Scheme_Object*);
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g364, Scheme_Object* g365);
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g373, Scheme_Object* g374);
#define SIG_Sl_s 20
typedef Scheme_Object* (*prim_Sl_s)(Scheme_Object**, intptr_t);
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g366, intptr_t g367);
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g375, intptr_t g376);
#define SIG_l_s 21
typedef Scheme_Object* (*prim_l_s)(intptr_t);
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g368);
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g377);
#define SIG_bsi_v 22
typedef void (*prim_bsi_v)(Scheme_Bucket*, Scheme_Object*, int);
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g369, Scheme_Object* g370, int g371);
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g378, Scheme_Object* g379, int g380);
#define SIG_iiS_v 23
typedef void (*prim_iiS_v)(int, int, Scheme_Object**);
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g372, int g373, Scheme_Object** g374);
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g381, int g382, Scheme_Object** g383);
#define SIG_ss_v 24
typedef void (*prim_ss_v)(Scheme_Object*, Scheme_Object*);
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g375, Scheme_Object* g376);
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g384, Scheme_Object* g385);
#define SIG_b_v 25
typedef void (*prim_b_v)(Scheme_Bucket*);
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g377);
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g386);
#define SIG_sl_s 26
typedef Scheme_Object* (*prim_sl_s)(Scheme_Object*, intptr_t);
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g378, intptr_t g379);
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g387, intptr_t g388);
#define SIG_iS_s 27
typedef Scheme_Object* (*prim_iS_s)(int, Scheme_Object**);
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g380, Scheme_Object** g381);
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g389, Scheme_Object** g390);
#define SIG_S_s 28
typedef Scheme_Object* (*prim_S_s)(Scheme_Object**);
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g382);
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g391);
#define SIG_s_v 29
typedef void (*prim_s_v)(Scheme_Object*);
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g383);
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g392);
#define SIG_iSi_s 30
typedef Scheme_Object* (*prim_iSi_s)(int, Scheme_Object**, int);
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g384, Scheme_Object** g385, int g386);
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g393, Scheme_Object** g394, int g395);
#define SIG_siS_v 31
typedef void (*prim_siS_v)(Scheme_Object*, int, Scheme_Object**);
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g387, int g388, Scheme_Object** g389);
#define SIG_z_p 32
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g396, int g397, Scheme_Object** g398);
#define SIG_Sii_s 32
typedef Scheme_Object* (*prim_Sii_s)(Scheme_Object**, int, int);
Scheme_Object* scheme_rtcall_Sii_s(const char *who, int src_type, prim_Sii_s f, Scheme_Object** g399, int g400, int g401);
#define SIG_z_p 33
typedef void* (*prim_z_p)(size_t);
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g390);
#define SIG_si_s 33
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g402);
#define SIG_si_s 34
typedef Scheme_Object* (*prim_si_s)(Scheme_Object*, int);
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g391, int g392);
#define SIG_sis_v 34
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g403, int g404);
#define SIG_sis_v 35
typedef void (*prim_sis_v)(Scheme_Object*, int, Scheme_Object*);
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g393, int g394, Scheme_Object* g395);
#define SIG_ss_i 35
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g405, int g406, Scheme_Object* g407);
#define SIG_ss_i 36
typedef int (*prim_ss_i)(Scheme_Object*, Scheme_Object*);
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g396, Scheme_Object* g397);
#define SIG_iSp_v 36
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g408, Scheme_Object* g409);
#define SIG_iSp_v 37
typedef void (*prim_iSp_v)(int, Scheme_Object**, void*);
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g398, Scheme_Object** g399, void* g400);
#define SIG_sss_s 37
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g410, Scheme_Object** g411, void* g412);
#define SIG_sss_s 38
typedef Scheme_Object* (*prim_sss_s)(Scheme_Object*, Scheme_Object*, Scheme_Object*);
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g401, Scheme_Object* g402, Scheme_Object* g403);
#define SIG__v 38
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g413, Scheme_Object* g414, Scheme_Object* g415);
#define SIG__v 39
typedef void (*prim__v)();
void scheme_rtcall__v(const char *who, int src_type, prim__v f );
#define SIG_iS_v 39
#define SIG_iS_v 40
typedef void (*prim_iS_v)(int, Scheme_Object**);
void scheme_rtcall_iS_v(const char *who, int src_type, prim_iS_v f, int g404, Scheme_Object** g405);
void scheme_rtcall_iS_v(const char *who, int src_type, prim_iS_v f, int g416, Scheme_Object** g417);

View File

@ -290,6 +290,20 @@ case SIG_siS_v:
f(arg_s0, arg_i1, arg_S2);
break;
}
case SIG_Sii_s:
{
prim_Sii_s f = (prim_Sii_s)future->prim_func;
GC_CAN_IGNORE Scheme_Object* retval;
JIT_TS_LOCALIZE(Scheme_Object**, arg_S0); JIT_TS_LOCALIZE(int, arg_i1); JIT_TS_LOCALIZE(int, arg_i2);
future->arg_S0 = NULL;
ADJUST_RS_ARG(future, arg_S0);
retval =
f(arg_S0, arg_i1, arg_i2);
future->retval_s = retval;
send_special_result(future, retval);
break;
}
case SIG_z_p:

View File

@ -36,6 +36,11 @@ static int generate_argument_boxing(mz_jit_state *jitter, Scheme_Lambda *lam,
Scheme_App_Rec *app, Scheme_Object **alt_rands);
#endif
static int detect_unsafe_struct_refs(Scheme_Object *arg, Scheme_Object **alt_rands, Scheme_App_Rec *app,
int i, int num_rands, int shift);
static int generate_unsafe_struct_ref_sequence(mz_jit_state *jitter, Scheme_Object *arg, Scheme_Object *last_arg,
int count, int stack_pos);
int scheme_direct_call_count, scheme_indirect_call_count;
struct jit_direct_arg {
@ -1783,7 +1788,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
If no_call is 2, then rator is not necssarily evaluated.
If no_call is 1, then rator is left in V1 and arguments are on runstack. */
{
int i, offset, need_safety = 0, apply_to_list = 0;
int i, offset, need_safety = 0, apply_to_list = 0, num_unsafe_struct_refs;
int direct_prim = 0, need_non_tail = 0, direct_native = 0, direct_self = 0, nontail_self = 0;
Scheme_Native_Closure *inline_direct_native = NULL;
int almost_inline_direct_native = 0;
@ -2113,10 +2118,26 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
need_safety = 0;
}
#ifdef USE_FLONUM_UNBOXING
if (direct_lam
&& (SCHEME_LAMBDA_FLAGS(direct_lam) & LAMBDA_HAS_TYPED_ARGS)
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_lam, i+args_already_in_place)
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_lam, i+args_already_in_place))) {
if (direct_lam)
num_unsafe_struct_refs = 0;
else
#endif
num_unsafe_struct_refs = detect_unsafe_struct_refs(arg, alt_rands, app, i, num_rands, 1+args_already_in_place);
if (num_unsafe_struct_refs > 1) {
/* Found a sequence of `(unsafed-struct-ref id 'number)` with
sequential `number`s, so extract the whole group at once */
v = (alt_rands
? alt_rands[i+1+args_already_in_place+num_unsafe_struct_refs-1]
: app->args[i+1+args_already_in_place+num_unsafe_struct_refs-1]);
mz_rs_sync();
generate_unsafe_struct_ref_sequence(jitter, arg, v, num_unsafe_struct_refs, i + offset);
CHECK_LIMIT();
i += (num_unsafe_struct_refs - 1);
#ifdef USE_FLONUM_UNBOXING
} else if (direct_lam
&& (SCHEME_LAMBDA_FLAGS(direct_lam) & LAMBDA_HAS_TYPED_ARGS)
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_lam, i+args_already_in_place)
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_lam, i+args_already_in_place))) {
int directly;
int extfl;
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_lam, i+args_already_in_place);
@ -2149,13 +2170,12 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
} else {
(void)jit_movi_p(JIT_R0, NULL);
}
} else
#endif
if (inline_direct_args) {
if (inline_direct_args[i].gen)
} else if (inline_direct_args) {
if (inline_direct_args[i].gen)
scheme_generate(arg, jitter, 0, 0, 0, inline_direct_args[i].reg, NULL, NULL);
} else
scheme_generate_non_tail(arg, jitter, 0, !need_non_tail, 0); /* sync'd below */
} else
scheme_generate_non_tail(arg, jitter, 0, !need_non_tail, 0); /* sync'd below */
RESUME_JIT_DATA();
CHECK_LIMIT();
@ -2397,4 +2417,91 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
return is_tail ? 2 : 1;
}
static int detect_unsafe_struct_refs(Scheme_Object *arg, Scheme_Object **alt_rands, Scheme_App_Rec *app,
int i, int num_rands, int shift)
/* Look for `(unsafe-struct-ref id 'num)` ... as a sequence of
arguments, which shows up as a result of `struct-copy`, and return
the length of the sequence. Instead of performing each
`unsafe-struct-ref` separately, which involves a chaperone test
each time, we'll test once and extract all. */
{
Scheme_App3_Rec *app3, *next_app3;
Scheme_Object *next_arg;
if (SAME_TYPE(SCHEME_TYPE(arg), scheme_application3_type)) {
app3 = (Scheme_App3_Rec *)arg;
if (SAME_OBJ(app3->rator, scheme_unsafe_struct_ref_proc)
&& SAME_TYPE(SCHEME_TYPE(app3->rand1), scheme_local_type)
&& SCHEME_INTP(app3->rand2)) {
int seq = 1, delta = SCHEME_INT_VAL(app3->rand2) - i;
i++;
while (i < num_rands) {
next_arg = (alt_rands ? alt_rands[i+shift] : app->args[i+shift]);
if (SAME_TYPE(SCHEME_TYPE(next_arg), scheme_application3_type)) {
next_app3 = (Scheme_App3_Rec *)next_arg;
if (SAME_OBJ(next_app3->rator, scheme_unsafe_struct_ref_proc)
&& SAME_TYPE(SCHEME_TYPE(next_app3->rand1), scheme_local_type)
&& SCHEME_INTP(next_app3->rand2)
&& (SCHEME_INT_VAL(next_app3->rand2) == i + delta)
&& (SCHEME_LOCAL_POS(next_app3->rand1) == SCHEME_LOCAL_POS(app3->rand1))) {
seq++;
i++;
} else
break;
} else
break;
}
return seq;
}
}
return 0;
}
static int generate_unsafe_struct_ref_sequence(mz_jit_state *jitter, Scheme_Object *arg, Scheme_Object *last_arg,
int count, int stack_pos)
/* Implement a sequence discovered by `detect_unsafe_struct_refs()`. */
{
Scheme_App3_Rec *app3 = (Scheme_App3_Rec *)arg;
int i, base = SCHEME_INT_VAL(app3->rand2);
GC_CAN_IGNORE jit_insn *ref, *refslow, *ref2;
/* Using `last_arg` ensures that we clear the local, if needed */
mz_runstack_skipped(jitter, 2);
scheme_generate(((Scheme_App3_Rec *)last_arg)->rand1, jitter, 0, 0, 0, JIT_R0, NULL, NULL);
CHECK_LIMIT();
mz_runstack_unskipped(jitter, 2);
/* Check for chaperones, and take slow path if found */
__START_SHORT_JUMPS__(1);
jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type);
ref = jit_bnei_i(jit_forward(), JIT_R2, scheme_chaperone_type);
refslow = jit_get_ip();
jit_addi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(stack_pos));
jit_str_p(JIT_R1, JIT_R0);
jit_movi_i(JIT_V1, base);
jit_movi_p(JIT_R0, count);
(void)jit_calli(sjc.struct_raw_refs_code);
ref2 = jit_jmpi(jit_forward());
mz_patch_branch(ref);
(void)jit_beqi_i(refslow, JIT_R2, scheme_proc_chaperone_type);
CHECK_LIMIT();
/* This is the fast path: */
for (i = 0; i < count; i++) {
jit_ldxi_p(JIT_R1, JIT_R0, (intptr_t)&(((Scheme_Structure *)0x0)->slots[i+base]));
if (i != count - 1)
mz_rs_stxi(stack_pos+i, JIT_R1);
else
jit_movr_p(JIT_R0, JIT_R1);
CHECK_LIMIT();
}
mz_patch_branch(ref2);
__END_SHORT_JUMPS__(1);
return 1;
}
#endif

View File

@ -182,6 +182,21 @@ static void chaperone_set_mark()
MZ_RUNSTACK[1] = SCHEME_CHAPERONE_VAL(MZ_RUNSTACK[1]);
}
static Scheme_Object *unsafe_struct_refs(Scheme_Object **rs, int offset, int count)
{
int i;
Scheme_Object *v, *s = rs[0];
for (i = 0; i < count; i++) {
v = scheme_struct_ref(s, offset + i);
if (i == count-1)
return v;
rs[i] = v;
}
return NULL;
}
#define JITCOMMON_TS_PROCS
#include "jit_ts.c"
@ -1824,6 +1839,29 @@ static int common4(mz_jit_state *jitter, void *_data)
scheme_jit_register_sub_func(jitter, code, scheme_false);
}
/* *** struct_raw_refs_code *** */
/* R1 points into the runstack, *R1 is struct, R0 is
count >= 2, and V1 is a starting slot in the structure */
{
void *code;
code = jit_get_ip();
sjc.struct_raw_refs_code = code;
mz_prolog(JIT_R2);
JIT_UPDATE_THREAD_RSPTR();
jit_prepare(3);
jit_pusharg_p(JIT_R0);
jit_pusharg_p(JIT_V1);
jit_pusharg_p(JIT_R1);
(void)mz_finish_lwe(ts_unsafe_struct_refs, ref);
jit_retval(JIT_R0);
mz_epilog(JIT_R2);
scheme_jit_register_sub_func(jitter, code, scheme_false);
}
/* *** syntax_e_code *** */
/* R0 is (potential) syntax object */
{