diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 47b50ee1d5..c27e1aa46b 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -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)]) diff --git a/racket/src/racket/src/gen-jit-ts.rkt b/racket/src/racket/src/gen-jit-ts.rkt index 36bd02ef25..4de54e7a79 100644 --- a/racket/src/racket/src/gen-jit-ts.rkt +++ b/racket/src/racket/src/gen-jit-ts.rkt @@ -191,6 +191,7 @@ s_v iSi_s siS_v + Sii_s z_p si_s sis_v diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 0905a52760..6487e0ae72 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -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; diff --git a/racket/src/racket/src/jit_ts.c b/racket/src/racket/src/jit_ts.c index 733d3cfac1..10faf239fb 100644 --- a/racket/src/racket/src/jit_ts.c +++ b/racket/src/racket/src/jit_ts.c @@ -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 diff --git a/racket/src/racket/src/jit_ts_def.c b/racket/src/racket/src/jit_ts_def.c index 1ea6b65b66..ffe04270f1 100644 --- a/racket/src/racket/src/jit_ts_def.c +++ b/racket/src/racket/src/jit_ts_def.c @@ -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); \ } diff --git a/racket/src/racket/src/jit_ts_future_glue.c b/racket/src/racket/src/jit_ts_future_glue.c index 29998b59d7..f95e4778d1 100644 --- a/racket/src/racket/src/jit_ts_future_glue.c +++ b/racket/src/racket/src/jit_ts_future_glue.c @@ -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; diff --git a/racket/src/racket/src/jit_ts_protos.h b/racket/src/racket/src/jit_ts_protos.h index 1078efb1f0..bb96f2c95e 100644 --- a/racket/src/racket/src/jit_ts_protos.h +++ b/racket/src/racket/src/jit_ts_protos.h @@ -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); diff --git a/racket/src/racket/src/jit_ts_runtime_glue.c b/racket/src/racket/src/jit_ts_runtime_glue.c index 3f826b8039..5b7ceff16d 100644 --- a/racket/src/racket/src/jit_ts_runtime_glue.c +++ b/racket/src/racket/src/jit_ts_runtime_glue.c @@ -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: diff --git a/racket/src/racket/src/jitcall.c b/racket/src/racket/src/jitcall.c index 7d01aa6f63..c8b6413d26 100644 --- a/racket/src/racket/src/jitcall.c +++ b/racket/src/racket/src/jitcall.c @@ -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 diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 11ca5ba8e8..ff88696c91 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -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 */ {