From 8430daa628dbfd23d10227d4a84ae0f80a6e0b0b Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 24 Jul 2015 22:41:08 -0300 Subject: [PATCH] Jitinline string-length and bytes-length Previously only the unsafe versions were inlined in the jit compiler. --- racket/src/racket/src/jit.h | 2 ++ racket/src/racket/src/jit_ts.c | 4 +++ racket/src/racket/src/jitcommon.c | 22 +++++++++++++++++ racket/src/racket/src/jitinline.c | 41 +++++++++++++++++++++++++++++-- racket/src/racket/src/string.c | 6 +++-- 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 5ec13dbe61..c569fd218f 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -313,6 +313,8 @@ struct scheme_jit_common_record { void *bad_vector_length_code; void *bad_flvector_length_code; void *bad_fxvector_length_code; + void *bad_string_length_code; + void *bad_bytes_length_code; void *vector_ref_code, *vector_ref_check_index_code, *vector_set_code, *vector_set_check_index_code; void *chap_vector_ref_code, *chap_vector_ref_check_index_code, *chap_vector_set_code, *chap_vector_set_check_index_code; void *string_ref_code, *string_ref_check_index_code, *string_set_code, *string_set_check_index_code; diff --git a/racket/src/racket/src/jit_ts.c b/racket/src/racket/src/jit_ts.c index 6cb0ad1399..755fc8a38d 100644 --- a/racket/src/racket/src/jit_ts.c +++ b/racket/src/racket/src/jit_ts.c @@ -89,6 +89,8 @@ define_ts_s_s(scheme_flvector_length, FSRC_MARKS) define_ts_s_s(scheme_extflvector_length, FSRC_MARKS) #endif define_ts_s_s(scheme_fxvector_length, FSRC_MARKS) +define_ts_s_s(scheme_string_length, FSRC_MARKS) +define_ts_s_s(scheme_byte_string_length, 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) @@ -207,6 +209,8 @@ define_ts_s_s(scheme_box, FSRC_OTHER) # define ts_scheme_extflvector_length scheme_extflvector_length #endif # define ts_scheme_fxvector_length scheme_fxvector_length +# define ts_scheme_string_length scheme_string_length +# 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_scheme_equal scheme_equal diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 3c95dde179..26fcaa9a32 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -603,6 +603,28 @@ static int common1b(mz_jit_state *jitter, void *_data) CHECK_LIMIT(); scheme_jit_register_sub_func(jitter, sjc.bad_fxvector_length_code, scheme_false); + /* *** bad_string_length_code *** */ + /* R0 is argument */ + sjc.bad_string_length_code = jit_get_ip(); + mz_prolog(JIT_R1); + JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); + jit_prepare(1); + jit_pusharg_p(JIT_R0); + (void)mz_finish_lwe(ts_scheme_string_length, ref); + CHECK_LIMIT(); + scheme_jit_register_sub_func(jitter, sjc.bad_string_length_code, scheme_false); + + /* *** bad_bytes_length_code *** */ + /* R0 is argument */ + sjc.bad_bytes_length_code = jit_get_ip(); + mz_prolog(JIT_R1); + JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); + jit_prepare(1); + jit_pusharg_p(JIT_R0); + (void)mz_finish_lwe(ts_scheme_byte_string_length, ref); + CHECK_LIMIT(); + scheme_jit_register_sub_func(jitter, sjc.bad_bytes_length_code, scheme_false); + return 1; } diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 6623927105..40d969cd72 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -1454,8 +1454,22 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in jit_fixnum_l(dest, JIT_R0); return 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-string-length") + } else if (IS_NAMED_PRIM(rator, "string-length") + || IS_NAMED_PRIM(rator, "bytes-length") + || IS_NAMED_PRIM(rator, "unsafe-string-length") || IS_NAMED_PRIM(rator, "unsafe-bytes-length")) { + GC_CAN_IGNORE jit_insn *reffail, *ref; + int unsafe = 0, for_string = 0; + + if (IS_NAMED_PRIM(rator, "unsafe-string-length") + || IS_NAMED_PRIM(rator, "unsafe-bytes-length")) { + unsafe = 1; + } + if (IS_NAMED_PRIM(rator, "string-length") + || IS_NAMED_PRIM(rator, "unsafe-string-length")) { + for_string = 1; + } + LOG_IT(("inlined string-length\n")); mz_runstack_skipped(jitter, 1); @@ -1465,7 +1479,30 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); - if (IS_NAMED_PRIM(rator, "unsafe-string-length")) + if (!unsafe) { + mz_rs_sync_fail_branch(); + + __START_TINY_JUMPS__(1); + ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); + __END_TINY_JUMPS__(1); + + reffail = jit_get_ip(); + if (for_string) + (void)jit_calli(sjc.bad_string_length_code); + else + (void)jit_calli(sjc.bad_bytes_length_code); + + __START_TINY_JUMPS__(1); + mz_patch_branch(ref); + if (for_string) + (void)mz_bnei_t(reffail, JIT_R0, scheme_char_string_type, JIT_R1); + else + (void)mz_bnei_t(reffail, JIT_R0, scheme_byte_string_type, JIT_R1); + __END_TINY_JUMPS__(1); + } + CHECK_LIMIT(); + + if (for_string) (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_CHAR_STRLEN_VAL(0x0)); else (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_BYTE_STRLEN_VAL(0x0)); diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index ca7e45ecc3..abb3544a5a 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -496,7 +496,8 @@ scheme_init_string (Scheme_Env *env) env); p = scheme_make_folding_prim(string_length, "string-length", 1, 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_PRODUCES_FIXNUM); + SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED + |SCHEME_PRIM_PRODUCES_FIXNUM); scheme_add_global_constant("string-length", p, env); @@ -774,7 +775,8 @@ scheme_init_string (Scheme_Env *env) GLOBAL_PRIM_W_ARITY("shared-bytes", shared_byte_string, 0, -1, env); p = scheme_make_folding_prim(byte_string_length, "bytes-length", 1, 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_PRODUCES_FIXNUM); + SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(SCHEME_PRIM_IS_UNARY_INLINED + |SCHEME_PRIM_PRODUCES_FIXNUM); scheme_add_global_constant("bytes-length", p, env); p = scheme_make_immed_prim(scheme_checked_byte_string_ref, "bytes-ref", 2, 2);