File: GcCode.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (111 lines) | stat: -rw-r--r-- 4,304 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma once

namespace storm {

	/**
	 * Describes a reference inside the generated code.
	 *
	 * The actual pointers for the references are stored inside the 'GcCodeRef' itself. These are
	 * the pointers that are actually scanned by the garbage collector, but the garbage collector
	 * will make sure to keep the described reference updated as well. Call
	 * 'runtime::codeUpdatePtrs' when all references have been filled in to update the references
	 * which 'offset' denotes.
	 *
	 * In the case of 'inside' references, the value stored in the 'pointer' member is a value to be
	 * interpreted as the offset within the current object, rather than an actual pointer.
	 *
	 * Note: If the LSB of the kind is set, the 'pointer' for that entry is scanned by the GC. To
	 * simplify, we use the entire least significant hex digit to indicate if the entry is scanned
	 * or not. The rest of the numbers are increasing as the enum would do normally.
	 */
	struct GcCodeRef {
		// Kind of reference. Ie. how do we read or write this reference to/from memory?
		enum Kind {
			// Disabled for now.
			disabled = 0x00,

			// Diabled, but scanned. I.e., we store some information inside 'pointer', but the value
			// of 'pointer' is not written anywhere in the code.
			ptrStorage = 0x01,

			// Raw pointer. Reads 4/8 bytes from 'offset' and treats those as a pointer.
			rawPtr = 0x11,

			// Offset pointer to a GC:d object. Reads 4/8 bytes from 'offset' and treats those as a
			// pointer relative (offset + sizeof(size_t)), ie. the address just after the pointer.
			relativePtr = 0x21,

			// A relative non-gc pointer to somewhere. This is updated as the object moves, but is
			// never scanned.
			relative = 0x30,

			// An absolute pointer to somewhere within this code section. This is updated whenever
			// the object moves, but is never scanned as it does not point to the start of an object.
			inside = 0x40,

			// Marker for a back-edge. The 'pointer' field contains an offset into this code listing
			// to indicate where the back edge leads to.
			backEdge = 0x50,

			// A relative (4-byte) pointer to one of the 'pointer' variables in the GcCodeRef
			// itself. The value stored inside 'pointer' must be an actual pointer, since it is
			// scanned by the GC. It can not be used to conveniently store large numbers etc.
			relativeHere = 0x61,

			// An architecture specific pointer that modifies the jump instruction as well, so that
			// we can properly support both long and short jump instructions (if wee need to
			// distinguish them) in an efficient manner by using short jumps where possible and
			// falling back to long jumps where necessary.
			jump = 0x71,

			// Update an entry in CodeTable, for unwinding information. 'pointer' is a pointer to
			// the location that shall be updated.
			codeInfo = 0x80,

			// Update an entry in DwarfTable, for unwinding information. 'pointer' is a pointer to
			// the location that shall be updated.
			dwarfInfo = 0x90,

			// ARM-specific version of "relativeHere". Writes an offset to the "pointer" member in
			// this struct at the offset indicated in 'offset'. This offset must be aligned to 4
			// bytes. This option assumes that it updates a 19-bit immediate located at bits 5..23.
			relativeHereImm19 = 0xA1,

			// ...
		};

		// Offset inside the code where this reference is located. Does not need to be aligned, that
		// depends entirely on the underlying machine we're working with.
		nat offset;

		// Reference type.
		Kind kind;

		// The pointer to be scanned. In the case where 'kind == inside', stores an offset into this
		// object instead.
		void *pointer;
	};


	/**
	 * Describes allocated code.
	 *
	 * NOTE: It is _not_ possible to store pointers to GcCode objects anywhere except for the stack,
	 * as these are really pointers into an object.
	 *
	 * TODO: Expose to Storm? This is only needed when writing the lowest parts of code-generating
	 * backends, which is only really neccessary when porting Storm to a new platform, so this has a
	 * very low priority.
	 */
	struct GcCode {
		// Number of entries. Only changed on allocation.
		const size_t refCount;

		// Reserved for internal use by the GC. Do not alter.
		void *reserved;

		// References in here.
		GcCodeRef refs[1];
	};

}