Skip to content

Commit 1b2bcb4

Browse files
authored
flambda-backend: Put frametables in .text with relative offsets for return addresses. (#1227)
This makes their contents statically known at assemble time, reducing the number of relocations that the linker needs to perform.
1 parent 999d523 commit 1b2bcb4

File tree

15 files changed

+25
-19
lines changed

15 files changed

+25
-19
lines changed

asmcomp/amd64/emit.mlp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,7 @@ let end_assembly() =
14291429
emit_global_label "data_end";
14301430
D.qword (const 0);
14311431

1432+
D.text ();
14321433
D.align 8; (* PR#7591 *)
14331434
emit_global_label "frametable";
14341435

@@ -1465,6 +1466,7 @@ let end_assembly() =
14651466
D.size frametable (ConstSub (ConstThis, ConstLabel frametable))
14661467
end;
14671468

1469+
D.data ();
14681470
emit_probe_notes ();
14691471

14701472
if system = S_linux then

asmcomp/emitaux.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ let emit_frames a =
203203
not (Debuginfo.is_none d.Debuginfo.alloc_dbg)) dbgs
204204
then 3 else 2
205205
in
206-
a.efa_code_label fd.fd_lbl;
206+
a.efa_label_rel fd.fd_lbl 0l;
207207
efa_16_checked (fd.fd_frame_size + flags);
208208
efa_16_checked (List.length fd.fd_live_offset);
209209
List.iter efa_16_checked fd.fd_live_offset;

runtime/amd64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ G(caml_system__code_end):
764764
.align EIGHT_ALIGN
765765
G(caml_system__frametable):
766766
.quad 1 /* one descriptor */
767-
.quad LBL(107) /* return address into callback */
767+
.4byte LBL(107) - . /* return address into callback */
768768
.value -1 /* negative frame size => use callback link */
769769
.value 0 /* no roots here */
770770
.align EIGHT_ALIGN

runtime/amd64nt.asm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ caml_system__code_end:
430430
PUBLIC caml_system__frametable
431431
caml_system__frametable LABEL QWORD
432432
QWORD 1 ; one descriptor
433-
QWORD L107 ; return address into callback
433+
DWORD L107 - THIS BYTE ; return address into callback
434434
WORD -1 ; negative frame size => use callback link
435435
WORD 0 ; no roots here
436436
ALIGN 8

runtime/arm.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ caml_system__code_end:
436436
.globl caml_system__frametable
437437
caml_system__frametable:
438438
.word 1 /* one descriptor */
439-
.word .Lcaml_retaddr /* return address into callback */
439+
.word .Lcaml_retaddr - . /* return address into callback */
440440
.short -1 /* negative frame size => use callback link */
441441
.short 0 /* no roots */
442442
.align 2

runtime/arm64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ G(caml_system__code_end):
535535

536536
OBJECT(caml_system__frametable)
537537
.quad 1 /* one descriptor */
538-
.quad L(caml_retaddr) /* return address into callback */
538+
.4byte L(caml_retaddr) - . /* return address into callback */
539539
.short -1 /* negative frame size => use callback link */
540540
.short 0 /* no roots */
541541
.align 3

runtime/backtrace_nat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ frame_descr * caml_next_frame_descriptor(uintnat * pc, char ** sp)
4141
while (1) {
4242
d = caml_frame_descriptors[h];
4343
if (d == NULL) return NULL; /* happens if some code compiled without -g */
44-
if (d->retaddr == *pc) break;
44+
if (Retaddr_frame(d) == *pc) break;
4545
h = (h+1) & caml_frame_descriptors_mask;
4646
}
4747
/* Skip to next frame */

runtime/caml/stack.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ struct caml_context {
8787

8888
/* Structure of frame descriptors */
8989
typedef struct {
90-
uintnat retaddr;
90+
int32_t retaddr_rel;
9191
unsigned short frame_size;
9292
unsigned short num_live;
9393
unsigned short live_ofs[1 /* num_live */];
@@ -104,7 +104,7 @@ typedef struct {
104104
} frame_descr;
105105

106106
typedef struct {
107-
uintnat retaddr;
107+
int32_t retaddr_rel;
108108
unsigned short marker; /* LONG_FRAME_MARKER */
109109
unsigned short _pad; /* Ensure frame_size is 4-byte aligned */
110110
uint32_t frame_size;
@@ -143,6 +143,10 @@ extern uintnat caml_frame_descriptors_mask;
143143
#define Hash_retaddr(addr) \
144144
(((uintnat)(addr) >> 3) & caml_frame_descriptors_mask)
145145

146+
#define Retaddr_frame(d) \
147+
((uintnat)&(d)->retaddr_rel + \
148+
(uintnat)(intnat)((d)->retaddr_rel))
149+
146150
extern void caml_init_frame_descriptors(void);
147151
extern void caml_register_frametable(intnat *);
148152
extern void caml_unregister_frametable(intnat *);

runtime/i386.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ G(caml_system__code_end):
465465
.globl G(caml_system__frametable)
466466
G(caml_system__frametable):
467467
.long 1 /* one descriptor */
468-
.long LBL(107) /* return address into callback */
468+
.4byte LBL(107) - . /* return address into callback */
469469
#ifndef SYS_solaris
470470
.word -1 /* negative frame size => use callback link */
471471
.word 0 /* no roots here */

runtime/i386nt.asm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ _caml_system__code_end:
304304
PUBLIC _caml_system__frametable
305305
_caml_system__frametable LABEL DWORD
306306
DWORD 1 ; one descriptor
307-
DWORD L107 ; return address into callback
307+
DWORD L107 - THIS BYTE ; return address into callback
308308
WORD -1 ; negative frame size => use callback link
309309
WORD 0 ; no roots here
310310

runtime/power.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ caml_system__code_end:
649649
.type caml_system__frametable, @object
650650
caml_system__frametable:
651651
datag 1 /* one descriptor */
652-
datag .L105 + 4 /* return address into callback */
652+
.long .L105 + 4 - . /* return address into callback */
653653
.short -1 /* negative size count => use callback link */
654654
.short 0 /* no roots here */
655655

runtime/riscv.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ caml_system__code_end:
446446
.type caml_system__frametable, @object
447447
caml_system__frametable:
448448
.quad 1 /* one descriptor */
449-
.quad .Lcaml_retaddr /* return address into callback */
449+
.4byte .Lcaml_retaddr - . /* return address into callback */
450450
.short -1 /* negative frame size => use callback link */
451451
.short 0 /* no roots */
452452
.align 3

runtime/roots_nat.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ unsigned char * get_end_of_live_ofs (frame_descr *d) {
109109
static frame_descr * next_frame_descr(frame_descr * d) {
110110
unsigned char num_allocs = 0, *p;
111111
uint32_t frame_size;
112-
CAMLassert(d->retaddr >= 4096);
112+
CAMLassert(Retaddr_frame(d) >= 4096);
113113
if (d->frame_size != 0xFFFF) {
114114
frame_size = get_frame_size(d);
115115
p = get_end_of_live_ofs(d);
@@ -151,7 +151,7 @@ static void fill_hashtable(link *frametables) {
151151
len = *tbl;
152152
d = (frame_descr *)(tbl + 1);
153153
for (j = 0; j < len; j++) {
154-
h = Hash_retaddr(d->retaddr);
154+
h = Hash_retaddr(Retaddr_frame(d));
155155
while (caml_frame_descriptors[h] != NULL) {
156156
h = (h+1) & caml_frame_descriptors_mask;
157157
}
@@ -220,7 +220,7 @@ static void remove_entry(frame_descr * d) {
220220
uintnat r;
221221
uintnat j;
222222

223-
i = Hash_retaddr(d->retaddr);
223+
i = Hash_retaddr(Retaddr_frame(d));
224224
while (caml_frame_descriptors[i] != d) {
225225
i = (i+1) & caml_frame_descriptors_mask;
226226
}
@@ -232,7 +232,7 @@ static void remove_entry(frame_descr * d) {
232232
i = (i+1) & caml_frame_descriptors_mask;
233233
// r3
234234
if(caml_frame_descriptors[i] == NULL) return;
235-
r = Hash_retaddr(caml_frame_descriptors[i]->retaddr);
235+
r = Hash_retaddr(Retaddr_frame(caml_frame_descriptors[i]));
236236
/* If r is between i and j (cyclically), i.e. if
237237
caml_frame_descriptors[i]->retaddr don't need to be moved */
238238
if(( ( j < r ) && ( r <= i ) ) ||
@@ -657,7 +657,7 @@ void caml_do_local_roots_nat(scanning_action maj, scanning_action min,
657657
h = Hash_retaddr(retaddr);
658658
while(1) {
659659
d = caml_frame_descriptors[h];
660-
if (d->retaddr == retaddr) break;
660+
if (Retaddr_frame(d) == retaddr) break;
661661
h = (h+1) & caml_frame_descriptors_mask;
662662
}
663663
if (d->frame_size != 0xFFFF) {

runtime/s390x.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ caml_system__code_end:
346346
.type caml_system__frametable, @object
347347
caml_system__frametable:
348348
.quad 1 /* one descriptor */
349-
.quad .L105 /* return address into callback */
349+
.4byte .L105 - . /* return address into callback */
350350
.short -1 /* negative size count => use callback link */
351351
.short 0 /* no roots here */
352352
.align 8

runtime/signals_nat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void caml_garbage_collection(void)
6868
uintnat h = Hash_retaddr(Caml_state->last_return_address);
6969
while (1) {
7070
d = caml_frame_descriptors[h];
71-
if (d->retaddr == Caml_state->last_return_address) break;
71+
if (Retaddr_frame(d) == Caml_state->last_return_address) break;
7272
h = (h + 1) & caml_frame_descriptors_mask;
7373
}
7474
/* Must be an allocation frame */

0 commit comments

Comments
 (0)