From b946d4639eae894fec120569a9d32ba061fcc749 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 1 Oct 2014 13:04:50 -0600 Subject: [PATCH] JIT: fix allocation of `letrec`-bound closure over unboxed flonums The closure could be allocated as uninitialized memory with the expectation that it would be filled right away, but boxing values to put in the closure could expose the uninitialized memory to the GC. Fix the problem by boxing before allocating closures. --- racket/src/racket/src/jit.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/racket/src/racket/src/jit.c b/racket/src/racket/src/jit.c index 43ecff8070..5c94a8a860 100644 --- a/racket/src/racket/src/jit.c +++ b/racket/src/racket/src/jit.c @@ -2846,6 +2846,13 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w mz_rs_sync(); + /* Box any unboxed values that will go into a closure */ + for (i = 0; i < l->count; i++) { + if (generate_closure_prep((Scheme_Closure_Data *)l->procs[i], jitter)) + prepped = 1; + CHECK_LIMIT(); + } + /* Create unfinished closures */ for (i = 0; i < l->count; i++) { ((Scheme_Closure_Data *)l->procs[i])->context = (Scheme_Object *)l; @@ -2853,12 +2860,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w CHECK_LIMIT(); jit_stxi_p(WORDS_TO_BYTES(i), JIT_RUNSTACK, JIT_R0); } - - for (i = 0; i < l->count; i++) { - if (generate_closure_prep((Scheme_Closure_Data *)l->procs[i], jitter)) - prepped = 1; - CHECK_LIMIT(); - } + /* We assume no allocation between last generated closure and + filling all closures, since the last one may be allocated as + "dirty". */ /* Close them: */ for (i = l->count; i--; ) {