Skip to content

Commit a56e453

Browse files
committed
Represent bytecode pointers (return address and traps) as ints on stack.
Removes most of the out-of-heap pointers the interpreter uses by replacing them with stack offsets.
1 parent 8437a0f commit a56e453

10 files changed

Lines changed: 68 additions & 66 deletions

File tree

byterun/backtrace.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,30 +110,33 @@ void caml_stash_backtrace(value exn, code_t pc, value * sp, int reraise)
110110
/* testing the code region is needed: PR#1554 */
111111
caml_backtrace_buffer[caml_backtrace_pos++] = pc;
112112
}
113-
for (/*nothing*/; sp < caml_trapsp; sp++) {
114-
code_t p = (code_t) *sp;
115-
if (p >= caml_start_code && p < end_code) {
113+
for (/*nothing*/; sp < caml_stack_high + caml_trap_sp_off; sp++) {
114+
if (Is_long(*sp) && Pc_val(*sp) >= caml_start_code && Pc_val(*sp) < end_code) {
116115
if (caml_backtrace_pos >= BACKTRACE_BUFFER_SIZE) break;
117-
caml_backtrace_buffer[caml_backtrace_pos++] = p;
116+
caml_backtrace_buffer[caml_backtrace_pos++] = Pc_val(*sp);
118117
}
119118
}
120119
}
121120

122121
/* returns the next frame pointer (or NULL if none is available);
123-
updates *sp to point to the following one, and *trapsp to the next
122+
updates *sp to point to the following one, and *trap_spoff to the next
124123
trap frame, which we will skip when we reach it */
125124

126-
code_t caml_next_frame_pointer(value ** sp, value ** trapsp)
125+
code_t caml_next_frame_pointer(value ** sp, intnat * trap_spoff)
127126
{
128127
code_t end_code = (code_t) ((char *) caml_start_code + caml_code_size);
129128

130129
while (*sp < caml_stack_high) {
131-
code_t *p = (code_t*) (*sp)++;
132-
if(&Trap_pc(*trapsp) == p) {
133-
*trapsp = Trap_link(*trapsp);
130+
value* p = (*sp)++;
131+
if(&Trap_pc(caml_stack_high + *trap_spoff) == p) {
132+
*trap_spoff = Trap_link(caml_stack_high + *trap_spoff);
134133
continue;
135134
}
136-
if (*p >= caml_start_code && *p < end_code) return *p;
135+
if (Is_long(*p) &&
136+
Pc_val(*p) >= caml_start_code &&
137+
Pc_val(*p) < end_code) {
138+
return Pc_val(*p);
139+
}
137140
}
138141
return NULL;
139142
}
@@ -157,10 +160,10 @@ CAMLprim value caml_get_current_callstack(value max_frames_value) {
157160
/* first compute the size of the trace */
158161
{
159162
value * sp = caml_extern_sp;
160-
value * trapsp = caml_trapsp;
163+
intnat trap_spoff = caml_trap_sp_off;
161164

162165
for (trace_size = 0; trace_size < max_frames; trace_size++) {
163-
code_t p = caml_next_frame_pointer(&sp, &trapsp);
166+
code_t p = caml_next_frame_pointer(&sp, &trap_spoff);
164167
if (p == NULL) break;
165168
}
166169
}
@@ -170,11 +173,11 @@ CAMLprim value caml_get_current_callstack(value max_frames_value) {
170173
/* then collect the trace */
171174
{
172175
value * sp = caml_extern_sp;
173-
value * trapsp = caml_trapsp;
176+
intnat trap_spoff = caml_trap_sp_off;
174177
uintnat trace_pos;
175178

176179
for (trace_pos = 0; trace_pos < trace_size; trace_pos++) {
177-
code_t p = caml_next_frame_pointer(&sp, &trapsp);
180+
code_t p = caml_next_frame_pointer(&sp, &trap_spoff);
178181
Assert(p != NULL);
179182
/* The assignment below is safe because we assign into an Abstract_tag block */
180183
Field(trace, trace_pos) = (value) p;

byterun/callback.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
7070
caml_extern_sp -= narg + 4;
7171
for (i = 0; i < narg; i++) caml_extern_sp[i] = args[i]; /* arguments */
7272
#ifndef LOCAL_CALLBACK_BYTECODE
73-
caml_extern_sp[narg] = (value) (callback_code + 4); /* return address */
73+
caml_extern_sp[narg] = Val_pc (callback_code + 4); /* return address */
7474
caml_extern_sp[narg + 1] = Val_unit; /* environment */
7575
caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
7676
caml_extern_sp[narg + 3] = closure;
@@ -79,7 +79,7 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
7979
callback_code[3] = narg;
8080
res = caml_interprete(callback_code, sizeof(callback_code));
8181
#else /*have LOCAL_CALLBACK_BYTECODE*/
82-
caml_extern_sp[narg] = (value) (local_callback_code + 4); /* return address */
82+
caml_extern_sp[narg] = Val_pc (local_callback_code + 4); /* return address */
8383
caml_extern_sp[narg + 1] = Val_unit; /* environment */
8484
caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
8585
caml_extern_sp[narg + 3] = closure;

byterun/compatibility.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,6 @@
271271
#define stack_high caml_stack_high
272272
#define stack_threshold caml_stack_threshold
273273
#define extern_sp caml_extern_sp
274-
#define trapsp caml_trapsp
275-
#define trap_barrier caml_trap_barrier
276274

277275
/* **** asmrun/startup.c */
278276
#define static_data_start caml_static_data_start

byterun/debugger.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void caml_debugger_init(void)
211211
}
212212
open_connection();
213213
caml_debugger_in_use = 1;
214-
caml_trap_barrier = caml_stack_high;
214+
caml_trap_barrier_off = 0;
215215
}
216216

217217
static value getval(struct channel *chan)
@@ -372,7 +372,7 @@ void caml_debugger(enum event_kind event)
372372
break;
373373
case REQ_SET_TRAP_BARRIER:
374374
i = caml_getword(dbg_in);
375-
caml_trap_barrier = caml_stack_high - i;
375+
caml_trap_barrier_off = -i;
376376
break;
377377
case REQ_GET_LOCAL:
378378
i = caml_getword(dbg_in);

byterun/interp.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ sp is a local copy of the global variable caml_extern_sp. */
7777
sp[0] = accu; /* accu */ \
7878
sp[1] = Val_unit; /* C_CALL frame: dummy environment */ \
7979
sp[2] = Val_unit; /* RETURN frame: dummy local 0 */ \
80-
sp[3] = (value) pc; /* RETURN frame: saved return address */ \
80+
sp[3] = Val_pc(pc); /* RETURN frame: saved return address */ \
8181
sp[4] = env; /* RETURN frame: saved environment */ \
8282
sp[5] = Val_long(extra_args); /* RETURN frame: saved extra args */ \
8383
caml_extern_sp = sp; }
8484
#define Restore_after_event \
8585
{ sp = caml_extern_sp; accu = sp[0]; \
86-
pc = (code_t) sp[3]; env = sp[4]; extra_args = Long_val(sp[5]); \
86+
pc = Pc_val(sp[3]); env = sp[4]; extra_args = Long_val(sp[5]); \
8787
sp += 6; }
8888

8989
/* Debugger interface */
@@ -379,7 +379,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
379379

380380
Instruct(PUSH_RETADDR): {
381381
sp -= 3;
382-
sp[0] = (value) (pc + *pc);
382+
sp[0] = Val_pc(pc + *pc);
383383
sp[1] = env;
384384
sp[2] = Val_long(extra_args);
385385
pc++;
@@ -395,7 +395,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
395395
value arg1 = sp[0];
396396
sp -= 3;
397397
sp[0] = arg1;
398-
sp[1] = (value)pc;
398+
sp[1] = Val_pc(pc);
399399
sp[2] = env;
400400
sp[3] = Val_long(extra_args);
401401
pc = Code_val(accu);
@@ -409,7 +409,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
409409
sp -= 3;
410410
sp[0] = arg1;
411411
sp[1] = arg2;
412-
sp[2] = (value)pc;
412+
sp[2] = Val_pc(pc);
413413
sp[3] = env;
414414
sp[4] = Val_long(extra_args);
415415
pc = Code_val(accu);
@@ -425,7 +425,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
425425
sp[0] = arg1;
426426
sp[1] = arg2;
427427
sp[2] = arg3;
428-
sp[3] = (value)pc;
428+
sp[3] = Val_pc(pc);
429429
sp[4] = env;
430430
sp[5] = Val_long(extra_args);
431431
pc = Code_val(accu);
@@ -489,7 +489,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
489489
pc = Code_val(accu);
490490
env = accu;
491491
} else {
492-
pc = (code_t)(sp[0]);
492+
pc = Pc_val(sp[0]);
493493
env = sp[1];
494494
extra_args = Long_val(sp[2]);
495495
sp += 3;
@@ -517,9 +517,9 @@ value caml_interprete(code_t prog, asize_t prog_size)
517517
Alloc_small(accu, num_args + 2, Closure_tag);
518518
Field(accu, 1) = env;
519519
for (i = 0; i < num_args; i++) Field(accu, i + 2) = sp[i];
520-
Code_val(accu) = pc - 3; /* Point to the preceding RESTART instr. */
520+
Field(accu, 0) = Val_bytecode(pc - 3); /* Point to the preceding RESTART instr. */
521521
sp += num_args;
522-
pc = (code_t)(sp[0]);
522+
pc = Pc_val(sp[0]);
523523
env = sp[1];
524524
extra_args = Long_val(sp[2]);
525525
sp += 3;
@@ -532,7 +532,7 @@ value caml_interprete(code_t prog, asize_t prog_size)
532532
int i;
533533
if (nvars > 0) *--sp = accu;
534534
Alloc_small(accu, 1 + nvars, Closure_tag);
535-
Code_val(accu) = pc + *pc;
535+
Field(accu, 0) = Val_bytecode(pc + *pc);
536536
pc++;
537537
for (i = 0; i < nvars; i++) Field(accu, i + 1) = sp[i];
538538
sp += nvars;
@@ -552,13 +552,13 @@ value caml_interprete(code_t prog, asize_t prog_size)
552552
}
553553
sp += nvars;
554554
p = &Field(accu, 0);
555-
*p = (value) (pc + pc[0]);
555+
*p = Val_bytecode(pc + pc[0]);
556556
*--sp = accu;
557557
p++;
558558
for (i = 1; i < nfuncs; i++) {
559559
*p = Make_header(i * 2, Infix_tag, Caml_white); /* color irrelevant. */
560560
p++;
561-
*p = (value) (pc + pc[i]);
561+
*p = Val_bytecode (pc + pc[i]);
562562
*--sp = (value) p;
563563
p++;
564564
}
@@ -800,11 +800,11 @@ value caml_interprete(code_t prog, asize_t prog_size)
800800

801801
Instruct(PUSHTRAP):
802802
sp -= 4;
803-
Trap_pc(sp) = pc + *pc;
804-
Trap_link(sp) = caml_trapsp;
803+
Trap_pc(sp) = Val_pc(pc + *pc);
804+
Trap_link(sp) = Val_long(caml_trap_sp_off);
805805
sp[2] = env;
806806
sp[3] = Val_long(extra_args);
807-
caml_trapsp = sp;
807+
caml_trap_sp_off = sp - caml_stack_high;
808808
pc++;
809809
Next;
810810

@@ -816,35 +816,34 @@ value caml_interprete(code_t prog, asize_t prog_size)
816816
pc--; /* restart the POPTRAP after processing the signal */
817817
goto process_signal;
818818
}
819-
caml_trapsp = Trap_link(sp);
819+
caml_trap_sp_off = Long_val(Trap_link(sp));
820820
sp += 4;
821821
Next;
822822

823823
Instruct(RAISE_NOTRACE):
824-
if (caml_trapsp >= caml_trap_barrier) caml_debugger(TRAP_BARRIER);
824+
if (caml_trap_sp_off >= caml_trap_barrier_off) caml_debugger(TRAP_BARRIER);
825825
goto raise_notrace;
826826

827827
Instruct(RERAISE):
828-
if (caml_trapsp >= caml_trap_barrier) caml_debugger(TRAP_BARRIER);
828+
if (caml_trap_sp_off >= caml_trap_barrier_off) caml_debugger(TRAP_BARRIER);
829829
if (caml_backtrace_active) caml_stash_backtrace(accu, pc, sp, 1);
830830
goto raise_notrace;
831831

832832
Instruct(RAISE):
833833
raise_exception:
834-
if (caml_trapsp >= caml_trap_barrier) caml_debugger(TRAP_BARRIER);
834+
if (caml_trap_sp_off >= caml_trap_barrier_off) caml_debugger(TRAP_BARRIER);
835835
if (caml_backtrace_active) caml_stash_backtrace(accu, pc, sp, 0);
836836
raise_notrace:
837-
if ((char *) caml_trapsp
838-
>= (char *) caml_stack_high - initial_sp_offset) {
837+
if (caml_trap_sp_off >= -initial_sp_offset) {
839838
caml_external_raise = initial_external_raise;
840839
caml_extern_sp = (value *) ((char *) caml_stack_high
841840
- initial_sp_offset);
842841
caml_callback_depth--;
843842
return Make_exception_result(accu);
844843
}
845-
sp = caml_trapsp;
846-
pc = Trap_pc(sp);
847-
caml_trapsp = Trap_link(sp);
844+
sp = caml_stack_high + caml_trap_sp_off;
845+
pc = Pc_val(Trap_pc(sp));
846+
caml_trap_sp_off = Long_val(Trap_link(sp));
848847
env = sp[2];
849848
extra_args = Long_val(sp[3]);
850849
sp += 4;

byterun/meta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ CAMLprim value caml_reify_bytecode(value prog, value len)
5656
#endif
5757
caml_prepare_bytecode((code_t) prog, (asize_t) Long_val(len));
5858
clos = caml_alloc_small (1, Closure_tag);
59-
Code_val(clos) = (code_t) prog;
59+
Field(clos, 0) = Val_bytecode(prog);
6060
return clos;
6161
}
6262

@@ -175,7 +175,7 @@ value * caml_stack_low;
175175
value * caml_stack_high;
176176
value * caml_stack_threshold;
177177
value * caml_extern_sp;
178-
value * caml_trapsp;
178+
intnat caml_trap_sp_off;
179179
int caml_callback_depth;
180180
int volatile caml_something_to_do;
181181
void (* volatile caml_async_action_hook)(void);

byterun/mlvalues.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,14 @@ CAMLextern value caml_get_public_method (value obj, value tag);
196196
Note however that tags being hashed, same tag does not necessarily mean
197197
same method name. */
198198

199+
#define Val_pc(pc) (Assert(((value)(pc) & 1) == 0), (value)(((char*)(pc)) + 1))
200+
#define Pc_val(val) (Assert(val & 1), (code_t)((char*)(val) - 1))
201+
199202
/* Special case of tuples of fields: closures */
200203
#define Closure_tag 247
201-
#define Code_val(val) (((code_t *) (val)) [0]) /* Also an l-value. */
204+
#define Bytecode_val(val) ((code_t)(val))
205+
#define Val_bytecode(code) ((value)(code))
206+
#define Code_val(val) Bytecode_val(Field((val), 0))
202207

203208
/* This tag is used (with Forward_tag) to implement lazy values.
204209
See major_gc.c and stdlib/lazy.ml. */

byterun/stacks.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ CAMLexport value * caml_stack_low;
2424
CAMLexport value * caml_stack_high;
2525
CAMLexport value * caml_stack_threshold;
2626
CAMLexport value * caml_extern_sp;
27-
CAMLexport value * caml_trapsp;
28-
CAMLexport value * caml_trap_barrier;
27+
CAMLexport intnat caml_trap_sp_off;
28+
CAMLexport intnat caml_trap_barrier_off;
2929
value caml_global_data = 0;
3030

3131
uintnat caml_max_stack_size; /* also used in gc_ctrl.c */
@@ -36,8 +36,8 @@ void caml_init_stack (uintnat initial_max_size)
3636
caml_stack_high = caml_stack_low + Stack_size / sizeof (value);
3737
caml_stack_threshold = caml_stack_low + Stack_threshold / sizeof (value);
3838
caml_extern_sp = caml_stack_high;
39-
caml_trapsp = caml_stack_high;
40-
caml_trap_barrier = caml_stack_high + 1;
39+
caml_trap_sp_off = 0;
40+
caml_trap_barrier_off = 1;
4141
caml_max_stack_size = initial_max_size;
4242
caml_gc_message (0x08, "Initial stack limit: %luk bytes\n",
4343
caml_max_stack_size / 1024 * sizeof (value));
@@ -47,7 +47,6 @@ void caml_realloc_stack(asize_t required_space)
4747
{
4848
asize_t size;
4949
value * new_low, * new_high, * new_sp;
50-
value * p;
5150

5251
Assert(caml_extern_sp >= caml_stack_low);
5352
size = caml_stack_high - caml_stack_low;
@@ -69,10 +68,6 @@ void caml_realloc_stack(asize_t required_space)
6968
(char *) caml_extern_sp,
7069
(caml_stack_high - caml_extern_sp) * sizeof(value));
7170
caml_stat_free(caml_stack_low);
72-
caml_trapsp = (value *) shift(caml_trapsp);
73-
caml_trap_barrier = (value *) shift(caml_trap_barrier);
74-
for (p = caml_trapsp; p < new_high; p = Trap_link(p))
75-
Trap_link(p) = (value *) shift(Trap_link(p));
7671
caml_stack_low = new_low;
7772
caml_stack_high = new_high;
7873
caml_stack_threshold = caml_stack_low + Stack_threshold / sizeof (value);

byterun/stacks.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ CAMLextern value * caml_stack_low;
2525
CAMLextern value * caml_stack_high;
2626
CAMLextern value * caml_stack_threshold;
2727
CAMLextern value * caml_extern_sp;
28-
CAMLextern value * caml_trapsp;
29-
CAMLextern value * caml_trap_barrier;
28+
CAMLextern intnat caml_trap_sp_off;
29+
CAMLextern intnat caml_trap_barrier_off;
3030

31-
#define Trap_pc(tp) (((code_t *)(tp))[0])
32-
#define Trap_link(tp) (((value **)(tp))[1])
31+
#define Val_off(off) (caml_stack_high + Long_val (off))
32+
#define Off_val(p) Val_long (caml_stack_high - Long_val (p))
33+
#define Trap_pc(tp) Field((tp), 0)
34+
#define Trap_link(tp) Field((tp), 1)
3335

3436
void caml_init_stack (uintnat init_max_size);
3537
void caml_realloc_stack (asize_t required_size);

0 commit comments

Comments
 (0)