fix specialization over a nested lambda

This commit is contained in:
Matthew Flatt 2015-12-29 07:01:57 -06:00
parent 26560240f1
commit a516304f6b
6 changed files with 52 additions and 20 deletions

View File

@ -5064,6 +5064,27 @@
(dup rep))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check specialization with a capturing lambda:
(let ()
(define (f x)
(procedure-specialize
(lambda (y)
(lambda () (+ x y)))))
(set! f f)
(test 11 ((f 10) 1)))
(let ()
(define (f x)
(set! x (add1 x))
(procedure-specialize
(lambda (y)
(lambda () (+ x y)))))
(set! f f)
(test 12 ((f 10) 1)))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -1275,7 +1275,7 @@ static int generate_closure(Scheme_Closure_Data *data,
jit_movi_l(JIT_R1, init_word);
jit_str_l(JIT_R0, JIT_R1);
}
scheme_mz_load_retained(jitter, JIT_R1, code, 0);
scheme_mz_load_retained(jitter, JIT_R1, code);
jit_stxi_p((intptr_t)&((Scheme_Native_Closure *)0x0)->code, JIT_R0, JIT_R1);
return 1;
@ -1285,7 +1285,7 @@ static int generate_closure(Scheme_Closure_Data *data,
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(1);
scheme_mz_load_retained(jitter, JIT_R0, code, 0);
scheme_mz_load_retained(jitter, JIT_R0, code);
jit_pusharg_p(JIT_R0);
{
GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES;
@ -1302,13 +1302,25 @@ static int generate_closure_fill(Scheme_Closure_Data *data,
/* Fill in closure */
int j, size, pos;
mzshort *map;
Scheme_Object *v;
size = data->closure_size;
map = data->closure_map;
jit_addi_p(JIT_R2, JIT_R0, &((Scheme_Native_Closure *)0x0)->vals);
for (j = 0; j < size; j++) {
CHECK_LIMIT();
pos = mz_remap(map[j]);
jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos));
if (SCHEME_NATIVE_CLOSURE_DATA_FLAGS(jitter->nc->code) & NATIVE_SPECIALIZED)
v = extract_closure_local(map[j], jitter, 1);
else
v = NULL;
if (v) {
/* capture value directly within specialized */
scheme_mz_load_retained(jitter, JIT_R1, v);
} else {
pos = mz_remap(map[j]);
jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos));
}
jit_stxi_p(WORDS_TO_BYTES(j), JIT_R2, JIT_R1);
}
return 1;
@ -1435,7 +1447,7 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(1);
scheme_mz_load_retained(jitter, JIT_R0, ndata, 0);
scheme_mz_load_retained(jitter, JIT_R0, ndata);
jit_pusharg_p(JIT_R0);
{
GC_CAN_IGNORE jit_insn *refr USED_ONLY_FOR_FUTURES;
@ -2056,7 +2068,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
Scheme_Object *b;
mz_rs_sync_fail_branch();
b = scheme_extract_global(obj, jitter->nc, 0);
scheme_mz_load_retained(jitter, JIT_R2, b, 1);
scheme_mz_load_retained(jitter, JIT_R2, b);
} else {
/* Load global array: */
pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj));
@ -2175,7 +2187,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
pos = mz_remap(SCHEME_LOCAL_POS(obj));
if (!result_ignored) {
if (specialized)
scheme_mz_load_retained(jitter, JIT_R0, specialized, 1);
scheme_mz_load_retained(jitter, JIT_R0, specialized);
else
mz_rs_ldxi(JIT_R0, pos);
jit_ldr_p(target, JIT_R0);
@ -2879,7 +2891,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
if (ab) {
pos = mz_remap(lv->position);
if (specialized)
scheme_mz_load_retained(jitter, JIT_R2, specialized, 1);
scheme_mz_load_retained(jitter, JIT_R2, specialized);
else
mz_rs_ldxi(JIT_R2, pos);
jit_str_p(JIT_R2, JIT_R0);
@ -3357,7 +3369,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
}
}
scheme_mz_load_retained(jitter, target, obj, 0);
scheme_mz_load_retained(jitter, target, obj);
END_JIT_DATA(19);
return 1;

View File

@ -1366,7 +1366,7 @@ int scheme_stack_safety(mz_jit_state *jitter, int cnt, int offset);
#ifdef USE_FLONUM_UNBOXING
int scheme_mz_flostack_pos(mz_jit_state *jitter, int i);
#endif
void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o, int non_obj);
void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *o);
void scheme_mz_runstack_skipped(mz_jit_state *jitter, int n);
void scheme_mz_runstack_unskipped(mz_jit_state *jitter, int n);

View File

@ -479,7 +479,7 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
if (direct_native && direct_to_code) {
__END_SHORT_JUMPS__(num_rands < 100);
/* load closure pointer into R0: */
scheme_mz_load_retained(jitter, JIT_R0, direct_to_code, 0);
scheme_mz_load_retained(jitter, JIT_R0, direct_to_code);
/* jump directly: */
(void)jit_jmpi(direct_to_code->code->u.tail_code);
/* no slow path in this mode */

View File

@ -2561,7 +2561,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
&& !SCHEME_FALSEP(a1)
&& !SCHEME_VOIDP(a1)
&& !SAME_OBJ(a1, scheme_true)) {
scheme_mz_load_retained(jitter, JIT_R1, a1, 0);
scheme_mz_load_retained(jitter, JIT_R1, a1);
ref = jit_bner_p(jit_forward(), JIT_R0, JIT_R1);
/* In case true is a fall-through, note that the test
didn't disturb R0: */
@ -3848,7 +3848,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
ref = jit_bnei_p(jit_forward(), JIT_R0, scheme_undefined);
__END_TINY_JUMPS__(1);
scheme_mz_load_retained(jitter, JIT_R1, app->rand2, 0);
scheme_mz_load_retained(jitter, JIT_R1, app->rand2);
if (IS_NAMED_PRIM(rator, "check-not-unsafe-undefined"))
(void)jit_calli(sjc.call_check_not_defined_code);
else

View File

@ -70,15 +70,14 @@ int scheme_mz_retain_it(mz_jit_state *jitter, void *v)
return jitter->retained;
}
void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj, int non_obj)
void scheme_mz_load_retained(mz_jit_state *jitter, int rs, void *obj)
/* obj is a pointer, but not necesarily tagged (in CGC) */
{
if (non_obj
|| (!SCHEME_INTP((Scheme_Object *)obj)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_true)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_false)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_void)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_null))) {
if (!SCHEME_INTP((Scheme_Object *)obj)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_true)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_false)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_void)
&& !SAME_OBJ((Scheme_Object *)obj, scheme_null)) {
#ifdef JIT_PRECISE_GC
int retptr;
void *p;