PageRenderTime 150ms CodeModel.GetById 102ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/vm/layouts.hpp

http://github.com/abeaumont/factor
C++ Header | 382 lines | 266 code | 60 blank | 56 comment | 6 complexity | c8377804f65d3c86babb96673e689783 MD5 | raw file
  1namespace factor
  2{
  3
  4typedef unsigned char u8;
  5typedef unsigned short u16;
  6typedef unsigned int u32;
  7typedef unsigned long long u64;
  8typedef signed char s8;
  9typedef signed short s16;
 10typedef signed int s32;
 11typedef signed long long s64;
 12
 13#ifdef _WIN64
 14	typedef long long fixnum;
 15	typedef unsigned long long cell;
 16#else
 17	typedef long fixnum;
 18	typedef unsigned long cell;
 19#endif
 20
 21inline static cell align(cell a, cell b)
 22{
 23	return (a + (b-1)) & ~(b-1);
 24}
 25
 26inline static cell alignment_for(cell a, cell b)
 27{
 28	return align(a,b) - a;
 29}
 30
 31static const cell data_alignment = 16;
 32
 33#define WORD_SIZE (signed)(sizeof(cell)*8)
 34
 35#define TAG_MASK 15
 36#define TAG_BITS 4
 37#define TAG(x) ((cell)(x) & TAG_MASK)
 38#define UNTAG(x) ((cell)(x) & ~TAG_MASK)
 39#define RETAG(x,tag) (UNTAG(x) | (tag))
 40
 41/*** Tags ***/
 42#define FIXNUM_TYPE 0
 43#define F_TYPE 1
 44#define ARRAY_TYPE 2
 45#define FLOAT_TYPE 3
 46#define QUOTATION_TYPE 4
 47#define BIGNUM_TYPE 5
 48#define ALIEN_TYPE 6
 49#define TUPLE_TYPE 7
 50#define WRAPPER_TYPE 8
 51#define BYTE_ARRAY_TYPE 9
 52#define CALLSTACK_TYPE 10
 53#define STRING_TYPE 11
 54#define WORD_TYPE 12
 55#define DLL_TYPE 13
 56
 57#define TYPE_COUNT 14
 58
 59static inline const char *type_name(cell type)
 60{
 61	switch (type)
 62	{
 63	case FIXNUM_TYPE:
 64		return "fixnum";
 65	case F_TYPE:
 66		return "f";
 67	case ARRAY_TYPE:
 68		return "array";
 69	case FLOAT_TYPE:
 70		return "float";
 71	case QUOTATION_TYPE:
 72		return "quotation";
 73	case BIGNUM_TYPE:
 74		return "bignum";
 75	case ALIEN_TYPE:
 76		return "alien";
 77	case TUPLE_TYPE:
 78		return "tuple";
 79	case WRAPPER_TYPE:
 80		return "wrapper";
 81	case BYTE_ARRAY_TYPE:
 82		return "byte-array";
 83	case CALLSTACK_TYPE:
 84		return "callstack";
 85	case STRING_TYPE:
 86		return "string";
 87	case WORD_TYPE:
 88		return "word";
 89	case DLL_TYPE:
 90		return "dll";
 91	default:
 92		FACTOR_ASSERT(false);
 93		return "";
 94	}
 95}
 96
 97enum code_block_type
 98{
 99	code_block_unoptimized,
100	code_block_optimized,
101	code_block_pic
102};
103
104/* Constants used when floating-point trap exceptions are thrown */
105enum
106{
107	FP_TRAP_INVALID_OPERATION = 1 << 0,
108	FP_TRAP_OVERFLOW          = 1 << 1,
109	FP_TRAP_UNDERFLOW         = 1 << 2,
110	FP_TRAP_ZERO_DIVIDE       = 1 << 3,
111	FP_TRAP_INEXACT           = 1 << 4,
112};
113
114/* What Factor calls 'f' */
115static const cell false_object = F_TYPE;
116
117inline static bool immediate_p(cell obj)
118{
119	/* We assume that fixnums have tag 0 and false_object has tag 1 */
120	return TAG(obj) <= F_TYPE;
121}
122
123inline static fixnum untag_fixnum(cell tagged)
124{
125#ifdef FACTOR_DEBUG
126	FACTOR_ASSERT(TAG(tagged) == FIXNUM_TYPE);
127#endif
128	return ((fixnum)tagged) >> TAG_BITS;
129}
130
131inline static cell tag_fixnum(fixnum untagged)
132{
133	return RETAG(untagged << TAG_BITS,FIXNUM_TYPE);
134}
135
136#define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
137
138struct object {
139	NO_TYPE_CHECK;
140	cell header;
141
142	cell size() const;
143	template<typename Fixup> cell size(Fixup fixup) const;
144
145	cell binary_payload_start() const;
146	template<typename Fixup> cell binary_payload_start(Fixup fixup) const;
147
148	cell *slots() const { return (cell *)this; }
149
150	template<typename Iterator> void each_slot(Iterator &iter);
151
152	/* Only valid for objects in tenured space; must cast to free_heap_block
153	to do anything with it if its free */
154	bool free_p() const
155	{
156		return (header & 1) == 1;
157	}
158
159	cell type() const
160	{
161		return (header >> 2) & TAG_MASK;
162	}
163
164	void initialize(cell type)
165	{
166		header = type << 2;
167	}
168
169	cell hashcode() const
170	{
171		return (header >> 6);
172	}
173
174	void set_hashcode(cell hashcode)
175	{
176		header = (header & 0x3f) | (hashcode << 6);
177	}
178
179	bool forwarding_pointer_p() const
180	{
181		return (header & 2) == 2;
182	}
183
184	object *forwarding_pointer() const
185	{
186		return (object *)UNTAG(header);
187	}
188
189	void forward_to(object *pointer)
190	{
191		header = ((cell)pointer | 2);
192	}
193};
194
195/* Assembly code makes assumptions about the layout of this struct */
196struct array : public object {
197	static const cell type_number = ARRAY_TYPE;
198	static const cell element_size = sizeof(cell);
199	/* tagged */
200	cell capacity;
201
202	cell *data() const { return (cell *)(this + 1); }
203};
204
205/* These are really just arrays, but certain elements have special
206significance */
207struct tuple_layout : public array {
208	NO_TYPE_CHECK;
209	/* tagged */
210	cell klass;
211	/* tagged fixnum */
212	cell size;
213	/* tagged fixnum */
214	cell echelon;
215};
216
217struct bignum : public object {
218	static const cell type_number = BIGNUM_TYPE;
219	static const cell element_size = sizeof(cell);
220	/* tagged */
221	cell capacity;
222
223	cell *data() const { return (cell *)(this + 1); }
224};
225
226struct byte_array : public object {
227	static const cell type_number = BYTE_ARRAY_TYPE;
228	static const cell element_size = 1;
229	/* tagged */
230	cell capacity;
231
232#ifndef FACTOR_64
233	cell padding0;
234	cell padding1;
235#endif
236
237	template<typename Scalar> Scalar *data() const { return (Scalar *)(this + 1); }
238};
239
240/* Assembly code makes assumptions about the layout of this struct */
241struct string : public object {
242	static const cell type_number = STRING_TYPE;
243	/* tagged num of chars */
244	cell length;
245	/* tagged */
246	cell aux;
247	/* tagged */
248	cell hashcode;
249
250	u8 *data() const { return (u8 *)(this + 1); }
251};
252
253struct code_block;
254
255/* Assembly code makes assumptions about the layout of this struct:
256	basis/bootstrap/images/images.factor
257	basis/compiler/constants/constants.factor
258	core/bootstrap/primitives.factor
259*/
260struct word : public object {
261	static const cell type_number = WORD_TYPE;
262	/* TAGGED hashcode */
263	cell hashcode;
264	/* TAGGED word name */
265	cell name;
266	/* TAGGED word vocabulary */
267	cell vocabulary;
268	/* TAGGED definition */
269	cell def;
270	/* TAGGED property assoc for library code */
271	cell props;
272	/* TAGGED alternative entry point for direct non-tail calls. Used for inline caching */
273	cell pic_def;
274	/* TAGGED alternative entry point for direct tail calls. Used for inline caching */
275	cell pic_tail_def;
276	/* TAGGED machine code for sub-primitive */
277	cell subprimitive;
278	/* UNTAGGED entry point: jump here to execute word */
279	void *entry_point;
280	/* UNTAGGED compiled code block */
281
282	/* defined in code_blocks.hpp */
283	code_block *code() const;
284};
285
286/* Assembly code makes assumptions about the layout of this struct */
287struct wrapper : public object {
288	static const cell type_number = WRAPPER_TYPE;
289	cell object;
290};
291
292/* Assembly code makes assumptions about the layout of this struct */
293struct boxed_float : object {
294	static const cell type_number = FLOAT_TYPE;
295
296#ifndef FACTOR_64
297	cell padding;
298#endif
299
300	double n;
301};
302
303/* Assembly code makes assumptions about the layout of this struct:
304	basis/bootstrap/images/images.factor
305	basis/compiler/constants/constants.factor
306	core/bootstrap/primitives.factor
307*/
308struct quotation : public object {
309	static const cell type_number = QUOTATION_TYPE;
310	/* tagged */
311	cell array;
312	/* tagged */
313	cell cached_effect;
314	/* tagged */
315	cell cache_counter;
316	/* UNTAGGED entry point; jump here to call quotation */
317	void *entry_point;
318
319	/* defined in code_blocks.hpp */
320	code_block *code() const;
321};
322
323/* Assembly code makes assumptions about the layout of this struct */
324struct alien : public object {
325	static const cell type_number = ALIEN_TYPE;
326	/* tagged */
327	cell base;
328	/* tagged */
329	cell expired;
330	/* untagged */
331	cell displacement;
332	/* untagged */
333	cell address;
334
335	void update_address()
336	{
337		if(base == false_object)
338			address = displacement;
339		else
340			address = UNTAG(base) + sizeof(byte_array) + displacement;
341	}
342};
343
344struct dll : public object {
345	static const cell type_number = DLL_TYPE;
346	/* tagged byte array holding a C string */
347	cell path;
348	/* OS-specific handle */
349	void *handle;
350};
351
352struct callstack : public object {
353	static const cell type_number = CALLSTACK_TYPE;
354	/* tagged */
355	cell length;
356	
357	void *frame_top_at(cell offset) const
358	{
359		return (void *)((char *)(this + 1) + offset);
360	}
361
362	void *top() const { return (void *)(this + 1); }
363	void *bottom() const { return (void *)((cell)(this + 1) + untag_fixnum(length)); }
364};
365
366struct tuple : public object {
367	static const cell type_number = TUPLE_TYPE;
368	/* tagged layout */
369	cell layout;
370
371	cell *data() const { return (cell *)(this + 1); }
372};
373
374struct data_root_range {
375	cell *start;
376	cell len;
377
378	explicit data_root_range(cell *start_, cell len_) :
379		start(start_), len(len_) {}
380};
381
382}