summaryrefslogtreecommitdiffstats
path: root/byterun/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/interp.c')
-rw-r--r--byterun/interp.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/byterun/interp.c b/byterun/interp.c
index 591b51778..e22b28b8b 100644
--- a/byterun/interp.c
+++ b/byterun/interp.c
@@ -181,14 +181,6 @@ sp is a local copy of the global variable caml_extern_sp. */
#endif
#endif
-/* Division and modulus madness */
-
-#ifdef NONSTANDARD_DIV_MOD
-extern intnat caml_safe_div(intnat p, intnat q);
-extern intnat caml_safe_mod(intnat p, intnat q);
-#endif
-
-
#ifdef DEBUG
static intnat caml_bcodcount;
#endif
@@ -531,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;
}
@@ -542,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;
@@ -780,7 +793,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
if (accu == Val_false) pc += *pc; else pc++;
Next;
Instruct(SWITCH): {
- uint32 sizes = *pc++;
+ uint32_t sizes = *pc++;
if (Is_block(accu)) {
intnat index = Tag_val(accu);
Assert ((uintnat) index < (sizes >> 16));
@@ -962,21 +975,13 @@ value caml_interprete(code_t prog, asize_t prog_size)
Instruct(DIVINT): {
intnat divisor = Long_val(*sp++);
if (divisor == 0) { Setup_for_c_call; caml_raise_zero_divide(); }
-#ifdef NONSTANDARD_DIV_MOD
- accu = Val_long(caml_safe_div(Long_val(accu), divisor));
-#else
accu = Val_long(Long_val(accu) / divisor);
-#endif
Next;
}
Instruct(MODINT): {
intnat divisor = Long_val(*sp++);
if (divisor == 0) { Setup_for_c_call; caml_raise_zero_divide(); }
-#ifdef NONSTANDARD_DIV_MOD
- accu = Val_long(caml_safe_mod(Long_val(accu), divisor));
-#else
accu = Val_long(Long_val(accu) % divisor);
-#endif
Next;
}
Instruct(ANDINT):