Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / runtime / gc / model.h
... / ...
CommitLineData
1/* Copyright (C) 2005-2007 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 */
7
8#if (defined (MLTON_GC_INTERNAL_TYPES))
9
10/*
11Consider the following schemes for representing object pointers and
12mapping them to 64-bit native pointers.
13
14A. 32 bits, with bottom two bits zero.
15B. 32 bits, with bottom bit zero, shift left by one.
16C. 32 bits, with bottom bit zero, shift left by two.
17D. 32 bits, shift left by two.
18E. 32 bits, shift left by three.
19F. 40 bits, with bottom two bits zero.
20G. 64 bits, with bottom two bits zero.
21
22These schemes vary in the number of bits to represent a pointer in an
23object, the time to load a pointer from memory into a register, the
24amount of addressable memory, and the object alignment.
25
26 bits time mem(G) align
27A 32 fast 4 4
28B 32 slow 8 4
29C 32 slow 16 8
30D 32 slow 16 4
31E 32 slow 32 8
32F 40 slow 256 4
33G 64 fast 4G 4
34
35Each of the (A-F) has a variant (AX-FX) in which pointers are added to
36some constant base address. This gives access to any region in the
37virtual address space instead of just the low addresses.
38
39The following diagram demonstrates what portion of the native pointer
40to which the object pointer corresponds.
41
4264 32 0
43| | |
44-----------------------------------------------------------------
45
46 ==============================00 A
47
48 ===============================0 B
49
50 ===============================0 C
51
52 ================================ D
53
54 ================================= E
55
56 ======================================00 F
57
58 ==============================================================00 G
59
60Algorithmically, we can compute the native pointer (P) from the object
61pointer (O) (with bitsize Z), given a shift (S) and a base (B):
62
63P = %add64(%shl64(%zxZ_64(O),S),B)
64
65Likewise, we can compute the object pointer (O) from the native
66pointer (P), given a shift (S) and a base (B):
67
68O = %lobits64_Z(%shr64(%sub64(P,B),S))
69
70Hence, each of the schemes may be characterized by the size Z of the
71object pointer, the shift S, and whether or not the base B is zero.
72Noting that
73 %zx64_64(x) = x
74 %shl64(x, 0) = x
75 %add64(x, 0) = x
76 %lobits64_64(x) = x
77 %shr64(x, 0) = x
78 %sub64(x, 0) = x
79it is easy to compute the number of ALU operations required by each
80scheme:
81
82A :: Z = 32, S == 0, B == 0 ops = 1
83AX :: Z = 32, S == 0, B != 0 ops = 2
84B :: Z = 32, S == 1, B == 0 ops = 2
85BX :: Z = 32, S == 1, B != 0 ops = 3
86C :: Z = 32, S == 2, B == 0 ops = 2
87CX :: Z = 32, S == 2, B != 0 ops = 3
88D :: Z = 32, S == 2, B == 0 ops = 2
89DX :: Z = 32, S == 2, B != 0 ops = 3
90E :: Z = 32, S == 3, B == 0 ops = 2
91EX :: Z = 32, S == 3, B != 0 ops = 3
92F :: Z = 40, S == 0, B == 0 ops = 1 (#)
93FX :: Z = 40, S == 0, B != 0 ops = 2 (#)
94G :: Z = 64, S == 0, B == 0 ops = 0
95
96#: In schemes F and FX, the conversion from object pointer to native
97pointer requires logical-shift-right, rather than zero-extend, since
98the object pointer would be fetched from memory as a 64-bit value.
99The cost may actually be higher, as storing an object pointer in
100memory requires some care so as not to overwrite neighboring data.
101
102It is not clear that any of the thirteen schemes dominates another.
103Here are some thoughts.
104
105(A) This is is what we have now, but is still useful on 64-bit
106machines where the bottom 4G may be less cluttered than on a 32-bit
107machine.
108
109(AX) seems like a nice cost/benefit tradeoff for a program that only
110needs 4G of memory, since the base can be used to find a contiguous 4G
111somewhere in the address space.
112
113(B) and (C) are similar, the tradeoff being to increase object
114alignment requirements in order to allow more memory. Importantly,
115pointers having a bottom zero bit means that we can still set the
116bottom bit to one to represent small values in sum types.
117
118(D) and (E) are problematic because they leave no room to represent
119small objects in sum types with pointers. I think that really rules
120them out.
121
122(F) costs some in object alignment because a sequence of pointers in
123an object may have to be padded to meet 4-byte alignment. Loading a
124pointer from memory into a register may be slightly faster than in
125(B) or (C) because we don't have to shift, but I wonder if that
126matters.
127
128(G) costs the most in space, but has the fastest load time for
129pointers of the schemes that allow access to 4G of memory.
130
131A reasonable tradeoff in implementation complexity vs allowing our
132users enough flexibility might be to provide:
133
134 A, AX, B, BX, C, CX, G
135
136After some experiments on those, we might be able to find a more
137manageable set for users.
138*/
139
140#if defined (GC_MODEL_NATIVE32)
141#define GC_MODEL_OBJPTR_SIZE 32
142#define GC_MODEL_OBJPTR_SHIFT 0
143#define GC_MODEL_OBJPTR_BASE 0
144#define GC_MODEL_HEADER_SIZE 32
145#define GC_MODEL_ARRLEN_SIZE 32
146#elif defined (GC_MODEL_NATIVE64)
147#define GC_MODEL_OBJPTR_SIZE 64
148#define GC_MODEL_OBJPTR_SHIFT 0
149#define GC_MODEL_OBJPTR_BASE 0
150#define GC_MODEL_HEADER_SIZE 64
151#define GC_MODEL_ARRLEN_SIZE 64
152#else
153#error GC_MODEL_* undefined
154#endif
155
156#define GC_MODEL_MINALIGN_SHIFT max(2, GC_MODEL_OBJPTR_SHIFT + 1)
157#define GC_MODEL_MINALIGN TWOPOWER(GC_MODEL_MINALIGN_SHIFT)
158
159#endif /* (defined (MLTON_GC_INTERNAL_TYPES)) */