summaryrefslogtreecommitdiffstats
path: root/byterun/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/interp.c')
-rw-r--r--byterun/interp.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/byterun/interp.c b/byterun/interp.c
index a0e54d166..9b682ba6e 100644
--- a/byterun/interp.c
+++ b/byterun/interp.c
@@ -523,10 +523,21 @@ value caml_interprete(code_t prog, asize_t prog_size)
int nvars = *pc++;
int i;
if (nvars > 0) *--sp = accu;
- Alloc_small(accu, 1 + nvars, Closure_tag);
+ if (nvars < Max_young_wosize) {
+ /* nvars + 1 <= Max_young_wosize, can allocate in minor heap */
+ Alloc_small(accu, 1 + nvars, Closure_tag);
+ for (i = 0; i < nvars; i++) Field(accu, i + 1) = sp[i];
+ } else {
+ /* PR#6385: must allocate in major heap */
+ /* caml_alloc_shr and caml_initialize never trigger a GC,
+ so no need to Setup_for_gc */
+ accu = caml_alloc_shr(1 + nvars, Closure_tag);
+ for (i = 0; i < nvars; i++) caml_initialize(&Field(accu, i + 1), sp[i]);
+ }
+ /* The code pointer is not in the heap, so no need to go through
+ caml_initialize. */
Code_val(accu) = pc + *pc;
pc++;
- for (i = 0; i < nvars; i++) Field(accu, i + 1) = sp[i];
sp += nvars;
Next;
}
@@ -534,15 +545,25 @@ value caml_interprete(code_t prog, asize_t prog_size)
Instruct(CLOSUREREC): {
int nfuncs = *pc++;
int nvars = *pc++;
+ mlsize_t blksize = nfuncs * 2 - 1 + nvars;
int i;
value * p;
if (nvars > 0) *--sp = accu;
- Alloc_small(accu, nfuncs * 2 - 1 + nvars, Closure_tag);
- p = &Field(accu, nfuncs * 2 - 1);
- for (i = 0; i < nvars; i++) {
- *p++ = sp[i];
+ if (blksize <= Max_young_wosize) {
+ Alloc_small(accu, blksize, Closure_tag);
+ p = &Field(accu, nfuncs * 2 - 1);
+ for (i = 0; i < nvars; i++, p++) *p = sp[i];
+ } else {
+ /* PR#6385: must allocate in major heap */
+ /* caml_alloc_shr and caml_initialize never trigger a GC,
+ so no need to Setup_for_gc */
+ accu = caml_alloc_shr(blksize, Closure_tag);
+ p = &Field(accu, nfuncs * 2 - 1);
+ for (i = 0; i < nvars; i++, p++) caml_initialize(p, sp[i]);
}
sp += nvars;
+ /* The code pointers and infix headers are not in the heap,
+ so no need to go through caml_initialize. */
p = &Field(accu, 0);
*p = (value) (pc + pc[0]);
*--sp = accu;