unbreak JIT and check limits
Repairs a problem with ce9894c8bf
, where a large "inlined" vector
allocation is not actually inlined, but other parts of the JIT
assume that it will behave as inlined --- which implies that the
runstack will be left unchanged after the call.
Closes #1868
This commit is contained in:
parent
55c1685526
commit
dfa5d48092
|
@ -934,12 +934,17 @@
|
|||
;; a vector allocation that is too large
|
||||
|
||||
(parameterize ([current-namespace (make-base-namespace)])
|
||||
(let loop ([i 10])
|
||||
((eval `(lambda (x) (vector x ,@(for/list ([j (in-range i)])
|
||||
j))))
|
||||
i)
|
||||
(when (i . < . 100000)
|
||||
(loop (floor (* i #e1.25))))))
|
||||
(for ([tail? '(#t #f)])
|
||||
(let loop ([i 10])
|
||||
((eval `(lambda (f x)
|
||||
,(let ([e `(vector x ,@(for/list ([j (in-range i)])
|
||||
j))])
|
||||
(if tail?
|
||||
e
|
||||
`(f ,e)))))
|
||||
values i)
|
||||
(when (i . < . 10000)
|
||||
(loop (floor (* i #e1.25)))))))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
|
|
@ -298,6 +298,11 @@ GC2_EXTERN int GC_allocate_phantom_bytes(void *pb, intptr_t);
|
|||
Returns 0 if allocation should fail due to a memory limit,
|
||||
1 otherwise. The representative `pb` determines who is charged. */
|
||||
|
||||
GC2_EXTERN intptr_t GC_max_nursery_object_size();
|
||||
/*
|
||||
Returns a lower bound on the maximum size allowed for allocation
|
||||
in the nursery. */
|
||||
|
||||
/***************************************************************************/
|
||||
/* Memory tracing */
|
||||
/***************************************************************************/
|
||||
|
@ -581,7 +586,7 @@ GC2_EXTERN intptr_t GC_is_place();
|
|||
Otherwise returns 0;
|
||||
*/
|
||||
|
||||
GC2_EXTERN int GC_message_small_objects_size(void *msg_memory, intptr_t up_to);
|
||||
GC2_EXTERN int GC_message_small_objects_size(void *msg_memory, intptr_t up_to);
|
||||
/*
|
||||
Determines whether the message qualifies as short and whether the
|
||||
total size of all objects allocated by the message allocator is less
|
||||
|
|
|
@ -1774,6 +1774,8 @@ intptr_t GC_alloc_alignment()
|
|||
|
||||
intptr_t GC_malloc_stays_put_threshold() { return MAX_OBJECT_SIZE; }
|
||||
|
||||
intptr_t GC_max_nursery_object_size() { return MAX_OBJECT_SIZE - OBJHEAD_SIZE; }
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Nursery (a.k.a. generation 0) and generation 1/2 */
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -256,6 +256,9 @@ Scheme_Env *scheme_engine_instance_init()
|
|||
scheme_init_resolve();
|
||||
scheme_init_sfs();
|
||||
scheme_init_validate();
|
||||
#ifdef MZ_USE_JIT
|
||||
scheme_init_jit();
|
||||
#endif
|
||||
|
||||
scheme_init_process_globals();
|
||||
|
||||
|
@ -492,7 +495,7 @@ static Scheme_Env *place_instance_init(void *stack_base, int initial_main_os_thr
|
|||
|
||||
scheme_init_stack_check();
|
||||
scheme_init_overflow();
|
||||
|
||||
|
||||
scheme_init_thread_lwc();
|
||||
|
||||
scheme_init_compenv_places();
|
||||
|
|
|
@ -266,6 +266,9 @@ typedef struct Apply_LWC_Args {
|
|||
typedef Scheme_Object *(*Continuation_Apply_Indirect)(Apply_LWC_Args *, intptr_t);
|
||||
typedef Scheme_Object *(*Continuation_Apply_Finish)(Apply_LWC_Args *args, void *stack, void *frame);
|
||||
|
||||
#define JIT_MAX_VECTOR_INLINE_SIZE 256
|
||||
#define JIT_MAX_STRUCT_FIELD_INLINE_COUNT 256
|
||||
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
# define JIT_NUM_FL_KINDS 2
|
||||
#else
|
||||
|
|
|
@ -150,7 +150,7 @@ static int check_val_struct_prim(Scheme_Object *p, int arity)
|
|||
Scheme_Struct_Type *t;
|
||||
t = (Scheme_Struct_Type *)SCHEME_PRIM_CLOSURE_ELS(p)[0];
|
||||
if ((arity == t->num_islots)
|
||||
&& (arity < 100)) {
|
||||
&& (arity < JIT_MAX_STRUCT_FIELD_INLINE_COUNT)) {
|
||||
return INLINE_STRUCT_PROC_CONSTR;
|
||||
}
|
||||
return 0;
|
||||
|
@ -5288,9 +5288,18 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
c = 2;
|
||||
} else {
|
||||
c = app->num_args;
|
||||
if (c > 256) {
|
||||
if (c > JIT_MAX_VECTOR_INLINE_SIZE) {
|
||||
/* Too big for inline alloc */
|
||||
return scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 0);
|
||||
i = scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 0);
|
||||
CHECK_LIMIT();
|
||||
if (dest != JIT_R0)
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
|
||||
/* since we're called in inline mode, need to manually pop: */
|
||||
jit_addi_l(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c));
|
||||
mz_runstack_popped(jitter, c);
|
||||
|
||||
return i;
|
||||
} else if (c)
|
||||
scheme_generate_app(app, NULL, c, c, jitter, 0, 0, 0, 2); /* sync'd below */
|
||||
}
|
||||
|
|
|
@ -29,6 +29,22 @@
|
|||
/* Used by vector-set-performance-stats!: */
|
||||
int scheme_jit_malloced;
|
||||
|
||||
void scheme_init_jit()
|
||||
{
|
||||
#ifdef CAN_INLINE_ALLOC
|
||||
intptr_t max_alloc;
|
||||
max_alloc = GC_max_nursery_object_size();
|
||||
if ((sizeof(Scheme_Vector) + (JIT_MAX_VECTOR_INLINE_SIZE - mzFLEX_DELTA) * sizeof(Scheme_Object *)) > max_alloc) {
|
||||
scheme_log_abort("Misconfigured: inlined vector size is greater than maximum allowed by GC");
|
||||
abort();
|
||||
}
|
||||
if ((sizeof(Scheme_Structure) + ((JIT_MAX_STRUCT_FIELD_INLINE_COUNT - mzFLEX_DELTA) * sizeof(Scheme_Object *))) > max_alloc) {
|
||||
scheme_log_abort("Misconfigured: inlined struct size is greater than maximum allowed by GC");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* JIT buffer */
|
||||
/*========================================================================*/
|
||||
|
|
|
@ -304,6 +304,9 @@ void scheme_init_finalization(void);
|
|||
void scheme_init_portable_case(void);
|
||||
void scheme_init_stack_check(void);
|
||||
void scheme_init_overflow(void);
|
||||
#ifdef MZ_USE_JIT
|
||||
void scheme_init_jit(void);
|
||||
#endif
|
||||
#ifdef MZ_PRECISE_GC
|
||||
void scheme_register_traversers(void);
|
||||
void scheme_init_hash_key_procs(void);
|
||||
|
@ -532,7 +535,6 @@ extern Scheme_Object *scheme_make_vector_proc;
|
|||
extern Scheme_Object *scheme_vector_immutable_proc;
|
||||
extern Scheme_Object *scheme_vector_ref_proc;
|
||||
extern Scheme_Object *scheme_vector_set_proc;
|
||||
extern Scheme_Object *scheme_vector_cas_proc;
|
||||
extern Scheme_Object *scheme_list_to_vector_proc;
|
||||
extern Scheme_Object *scheme_unsafe_vector_length_proc;
|
||||
extern Scheme_Object *scheme_unsafe_struct_ref_proc;
|
||||
|
@ -1075,6 +1077,9 @@ typedef struct Scheme_Structure
|
|||
Scheme_Object *slots[mzFLEX_ARRAY_DECL];
|
||||
} Scheme_Structure;
|
||||
|
||||
#define MAX_STRUCT_FIELD_COUNT 32768
|
||||
#define MAX_STRUCT_FIELD_COUNT_STR "32768"
|
||||
|
||||
#ifdef MZ_USE_PLACES
|
||||
typedef struct Scheme_Serialized_Structure
|
||||
{
|
||||
|
|
|
@ -2839,7 +2839,7 @@ static int parse_pos(const char *who, Scheme_Object *prim, Scheme_Object **args,
|
|||
|
||||
if (!SCHEME_INTP(args[1]) || (SCHEME_INT_VAL(args[1]) < 0)) {
|
||||
if (SCHEME_BIGNUMP(args[1]) && SCHEME_BIGPOS(args[1])) {
|
||||
pos = 32769; /* greater than max field count */
|
||||
pos = (MAX_STRUCT_FIELD_COUNT + 1);
|
||||
} else {
|
||||
if (!who)
|
||||
who = extract_field_proc_name(prim);
|
||||
|
@ -3482,9 +3482,6 @@ static Scheme_Object *make_prefab_struct(int argc, Scheme_Object *argv[])
|
|||
return scheme_make_prefab_struct_instance(stype, vec);
|
||||
}
|
||||
|
||||
#define MAX_STRUCT_FIELD_COUNT 32768
|
||||
#define MAX_STRUCT_FIELD_COUNT_STR "32768"
|
||||
|
||||
static Scheme_Object *prefab_key_struct_type(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Struct_Type *stype;
|
||||
|
|
Loading…
Reference in New Issue
Block a user