%other-pointer-widetag derive-type: derive for simple-array.
[sbcl.git] / src / runtime / code.h
blob7b8dd3bb64bd69ab2438c7da60da5a229bdd7c0b
1 /*
2 * This software is part of the SBCL system. See the README file for
3 * more information.
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
12 #ifndef _CODE_H_
13 #define _CODE_H_
15 #include "genesis/closure.h"
16 #include "gc-assert.h"
18 static inline int code_total_nwords(struct code* c) {
19 #ifdef LISP_FEATURE_64_BIT
20 return c->header >> 32;
21 #else
22 /* Mask out bits reserved for GC */
23 return (c->header >> N_WIDETAG_BITS) & 0x3FFFFF;
24 #endif
27 // Return signed int in case something tries to compute the number of boxed
28 // words excluding the header word itself using "code_header_words(header) - 1",
29 // which, for a filler needs to come out as negative, not a huge positive.
30 static inline sword_t code_boxed_len(struct code* c)
32 return (c->boxed_size & 0xFFFFFFFF); // byte count
34 static inline sword_t code_header_words(struct code* c)
36 return code_boxed_len(c) >> WORD_SHIFT; // word count
39 /* Code component trailer words:
41 * fun table pointer v
42 * ... | offset | offset | .... | N-funs | datalen |
43 * (uint16) (uint16)
44 * | ----------- code trailer -------------|
46 * ^ end of instructions end of object ^
48 * The fun_table pointer is aligned at a 4-byte boundary.
49 * The final uint16 is the length of the code trailer, including the bytes
50 * comprising that length field itself, and the preceding count (n-funs) field.
51 * Thus the minimum trailer size should be 4 for any normal code object.
52 * Immobile trampolines are a special case - they indicate 0 trailer length,
53 * but the final 2 bytes are present since they have to be read.
55 static inline unsigned int* code_fun_table(struct code* code) {
56 return (unsigned int*)((char*)code + N_WORD_BYTES*code_total_nwords(code) - 4);
58 static inline unsigned short code_trailer_len(struct code* code) {
59 return *(unsigned short*)((char*)code + N_WORD_BYTES*code_total_nwords(code) - 2);
61 static inline unsigned short code_n_funs(struct code* code) {
62 // Do not attempt to read the fun table size from a code object with no trailer.
63 // If there is a nonzero trailer length, assume it is at least enough to store
64 // the length of the fun table.
65 return !code_trailer_len(code) ? 0 : *(unsigned short*)code_fun_table(code) >> 5;
68 static inline char* code_text_start(struct code* code) {
69 return (char*)code + code_boxed_len(code);
71 /// The length in bytes of the unboxed portion excluding the trailer.
72 static inline int code_text_size(struct code* c) {
73 return N_WORD_BYTES * code_total_nwords(c) - code_boxed_len(c) - code_trailer_len(c);
75 /// Return the text start, unless the boxed size has not yet been assigned.
76 /// In the latter case, the text start would seem to be the object address,
77 /// and reading a word there as if it were the jump table size would be wrong.
78 static inline lispobj* code_jumptable_start(struct code* code) {
79 return code->boxed_size ? (lispobj*)code_text_start(code) : 0;
81 static inline unsigned int jumptable_count(lispobj* table) {
82 // extract low 14 bits regardless of machine word size
83 return table ? *table & 0x3FFF : 0;
85 static inline unsigned int code_serialno(struct code* code) {
86 lispobj* table = code_jumptable_start(code);
87 #ifdef LISP_FEATURE_64_BIT
88 return table ? *table >> 32 : 0; // high 4 bits are the serialno
89 #else
90 return table ? *table >> 14 : 0; // else it only gets 18 (= 32 - 14) bits
91 #endif
94 static inline unsigned int code_n_named_calls(struct code* code) {
95 #ifdef LISP_FEATURE_64_BIT
96 return code->boxed_size >> 32;
97 #else
98 return 0;
99 #endif
102 // Iterate over the native pointers to each function in 'code_var'
103 // offsets are stored as the number of bytes into the instructions
104 // portion of the code object at which the simple-fun object resides.
105 // We use bytes, not words, because that's what the COMPUTE-FUN vop expects.
106 #define for_each_simple_fun(index_var,fun_var,code_var,assertp,guts) \
107 { int _nfuns_ = code_n_funs(code_var); \
108 if (_nfuns_ > 0) { \
109 char *_insts_ = code_text_start(code_var); \
110 int index_var = 0; \
111 unsigned int* _offsets_ = code_fun_table(code_var) - 1; \
112 do { \
113 struct simple_fun* fun_var \
114 = (struct simple_fun*)(_insts_ + _offsets_[-index_var]); \
115 if (assertp) \
116 gc_assert(widetag_of(&fun_var->header)==SIMPLE_FUN_WIDETAG); \
117 guts ; \
118 } while (++index_var < _nfuns_); \
121 /// Return true if 'pointer' is plausibly a pointer into the text of
122 /// the code object at 'start_addr'.
124 /// We don't pedantically check that it is within bounds, nor that it is not
125 /// pointing into either a simple-fun header or the trailing simple-fun table
126 /// or a piece of unboxed data preceding the first simple-fun.
127 /// Arguably we should at least check that it is below code_text_size though.
128 static inline int instruction_ptr_p(char *pointer, lispobj *start_addr)
130 return widetag_of(start_addr) == CODE_HEADER_WIDETAG &&
131 pointer >= code_text_start((struct code*)start_addr);
134 /// Maximum number of word backwards from a simple-fun
135 /// to its containing code component - corresponds to ~128MB.
136 /// The limit exists so that we can store the layout pointer
137 /// in the header of any callable object if N_WORD_BITS = 64.
138 /// This is not technically a restriction on the code size.
139 #define FUN_HEADER_NWORDS_MASK 0xFFFFFF
141 static inline lispobj fun_code_tagged(void* fun) {
142 return make_lispobj(fun_code_header(fun), OTHER_POINTER_LOWTAG);
145 #ifdef RETURN_PC_WIDETAG
146 #define embedded_obj_p(tag) (tag==RETURN_PC_WIDETAG || tag==SIMPLE_FUN_WIDETAG)
147 #else
148 #define embedded_obj_p(tag) (tag==SIMPLE_FUN_WIDETAG)
149 #endif
150 /* Convert from a lispobj with lowtag bits to the starting address
151 * of the heap object. */
152 static inline lispobj *
153 base_pointer(lispobj ptr)
155 lispobj *obj = native_pointer(ptr);
156 int widetag = widetag_of(obj);
157 return embedded_obj_p(widetag) ? (lispobj*)fun_code_header((struct simple_fun*)obj) : obj;
160 #if defined LISP_FEATURE_X86 || defined LISP_FEATURE_X86_64 || defined LISP_FEATURE_ARM64
161 # define FUN_SELF_FIXNUM_TAGGED 1
162 # define fun_self_from_baseptr(simple_fun) (lispobj)simple_fun->insts
163 # define fun_self_from_taggedptr(funptr) \
164 funptr - FUN_POINTER_LOWTAG + 2*N_WORD_BYTES
165 # define fun_taggedptr_from_self(self) \
166 self - 2*N_WORD_BYTES + FUN_POINTER_LOWTAG
167 #else
168 # define FUN_SELF_FIXNUM_TAGGED 0
169 # define fun_self_from_baseptr(simple_fun) \
170 make_lispobj(simple_fun,FUN_POINTER_LOWTAG)
171 # define fun_self_from_taggedptr(funptr) funptr
172 # define fun_taggedptr_from_self(self) self
173 #endif
175 #define simplefun_is_wrapped(fun) \
176 fun->self != fun_self_from_baseptr(fun) && fun->self != 0
177 #define CODE_IS_TRACED 0x01
179 extern int simple_fun_index(struct code*, struct simple_fun*);
181 // Offset from an fdefn raw address to the underlying simple-fun,
182 // if and only if it points to a simple-fun.
183 // For those of us who are too memory-impaired to know how to use the value:
184 // - it is the amount to ADD to a tagged simple-fun pointer to get its entry address
185 // - or the amount to SUBTRACT from an entry address to get a tagged fun pointer
186 #if defined(LISP_FEATURE_SPARC) || defined(LISP_FEATURE_ARM) || defined(LISP_FEATURE_RISCV)
187 #define FUN_RAW_ADDR_OFFSET 0
188 #else
189 #define FUN_RAW_ADDR_OFFSET (offsetof(struct simple_fun, insts) - FUN_POINTER_LOWTAG)
190 #endif
192 // for code ojects, this bit signifies that this object is in the remembered set.
193 // KLUDGE: this constant needs to be autogenerated. It is currently hardcoded into
194 // the CODE-HEADER-SET assembly routine
195 #define OBJ_WRITTEN_FLAG 0x40
196 #ifdef LISP_FEATURE_LITTLE_ENDIAN
197 #define CLEAR_WRITTEN_FLAG(obj) ((unsigned char*)obj)[3] &= ~OBJ_WRITTEN_FLAG
198 #define SET_WRITTEN_FLAG(obj) ((unsigned char*)obj)[3] |= OBJ_WRITTEN_FLAG
199 #else
200 #define CLEAR_WRITTEN_FLAG(obj) *obj &= ~(OBJ_WRITTEN_FLAG<<24)
201 #define SET_WRITTEN_FLAG(obj) *obj |= (OBJ_WRITTEN_FLAG<<24)
202 #endif
203 static inline int header_rememberedp(lispobj header) {
204 return (header & (OBJ_WRITTEN_FLAG << 24)) != 0;
207 #endif