File: pl-data.h

package info (click to toggle)
swi-prolog 3.1.0-2
  • links: PTS
  • area: main
  • in suites: slink
  • size: 8,772 kB
  • ctags: 12,869
  • sloc: ansic: 43,657; perl: 12,577; lisp: 4,359; sh: 1,534; makefile: 798; awk: 14
file content (241 lines) | stat: -rw-r--r-- 7,537 bytes parent folder | download | duplicates (2)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proposal for new Prolog data-structures.

Aim
===

Flexibel adaption to different memory model.   Possible  to make `clean'
programs, i.e. programs that donot make assumptions on the memory model.
The latter appears necessary on some systems to put Prolog into a DLL.

Fast comparison and checking. The hope  is   that  the  result will have
comparable or better speed.

Approach
========

	* No direct pointers in Prolog machine words anymore

	* Tags in the low bits to exploit SPARC and possible other
	  machines fixed-width instruction, so masks can be loaded
	  in one instead of two instructions.

	* Explicit encoding of the `user' data-types in the word,
	  so PL_term_type() can be much faster.

	* Explicit encoding of the storage regime used, so more code
	  can be generic.

Types:
======

Sorted to standard order of terms:

Storage places:

	S	Static (global variable)
	H	Heap
	L	Local
	G	Global
	T	Trail
	-	`In the variable'

	      INDEX  STORAGE  L  G  H  T  S  -  I
----------------------------------------------------------------
Var		0      -                    00
Integer		1      HG-      10 01       00
Float		2      HG       10 01
Atom		3      HS          01    00
String		4      HG       10 01
List		5      HG       10 01
Term		6      HG       10 01
Reference	7      HLG   11 10 01
----------------------------------------------------------------

Adding 2 bits for the garbage collector, this adds up to 7-bits tag info,
leaving us with 32-7 is 25 bits data, or:

	* Tagged ints from -16M to +16M
	* 128 MB per memory area, assuming all data is 4-byte aligned.

Giving this, stacks can be freely shifted!

Bit layout
==========

	* Value are the top-bits, so extracting the value is just a
	  shift.

	* GC masks follow, so, as they are normally both 0, shifting
	  suffices for this too.

	* Type is the low 3-bits, so a simple mask yields the type.

	* Storage in bits 4 and 5

Indirect data
=============

	* Using normal tag, but the storage-specifier is 0x3 (11).  Tag
	  is only INTEGER, STRING or FLOAT

	* Using value: size in words of the object * 4
	
	* String uses the low-order 2 bits for specifying the amount of
	  padding bytes (0-3, 0 means 4).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include "pl-buffer.h"

#define LMASK_BITS	7		/* total # mask bits */

#define TAG_MASK	0x00000007L	/* mask for tag */
#define TAG_VAR		0x00000000L	/* tag for variable (= 0L) */
#define TAG_INTEGER	0x00000001L	/* Tagged or indirect integer */
#define TAG_FLOAT	0x00000002L	/* Floating point number */
#define TAG_ATOM	0x00000003L	/* an atom */
#define TAG_STRING	0x00000004L	/* String */
#define TAG_LIST	0x00000005L	/* List */
#define TAG_COMPOUND	0x00000006L	/* Compound term */
#define TAG_REFERENCE	0x00000007L	/* Reference pointer */

					/* Trail tag-bits */
#define TAG_TRAILMASK	0x00000001L	/* mask for tag */
#define TAG_TRAILADDR	0x00000000L	/* Trail-only: address */
#define TAG_TRAILVAL	0x00000001L	/* Trail-only: value */
#define tagTrailPtr(p)	((Word)((ulong)(p)|TAG_TRAILVAL))
#define isTrailVal(p)	((ulong)(p)&TAG_TRAILVAL)
#define trailValP(p)	((Word)((ulong)(p)&~TAG_TRAILMASK))
#define trailVal(p)	(*trailValP(p))

#define STG_MASK	(0x3<<3)
#define STG_STATIC	(0x0<<3)	/* storage masks */
#define STG_GLOBAL	(0x1<<3)
#define STG_LOCAL	(0x2<<3)
#define STG_RESERVED	(0x3<<3)

#define STG_INLINE	STG_STATIC
#define STG_TRAIL	STG_STATIC

#define MARK_MASK	(0x1<<5)	/* GC mark */
#define FIRST_MASK	(0x2<<5)	/* GC first mark */

#define tag(w)		((w) & TAG_MASK)
#define storage(w)	((w) & STG_MASK)
#define valPtr2(w, s)	((Word)(((w) >> 5) + base_addresses[s]))
#define valPtr(w)	valPtr2(w, storage(w))
#define valInt(w)	((long)(w) >> 7)

		 /*******************************
		 *	  EXTENDED TAG		*
		 *******************************/

extern const unsigned int tagtypeex[];

#define tagex(w)	((w) & (TAG_MASK|STG_MASK))

#define TAGEX_INDIRECT	0x1
#define isIndirect(w)	(tagtypeex[tagex(w)] & TAGEX_INDIRECT)

		 /*******************************
		 *	 BASIC TYPE TESTS	*
		 *******************************/

#define isVar(w)	((w) == 0L)	/* variable */
#define isAtom(w)	(tag(w) == TAG_ATOM)
#define isInteger(w)	(tag(w) == TAG_INTEGER)
#define isReal(w)	(tag(w) == TAG_FLOAT)
#define isString(w)	(tag(w) == TAG_STRING)
#define isTerm(w)	(tag(w) == TAG_COMPOUND)


		 /*******************************
		 *	    REFERENCES		*
		 *******************************/

#define isRef(w)	(tag(w) == TAG_REFERENCE)
#define unRef(w)	((Word)valPtr(w))
#define deRef(p)	{ while(isRef(*(p))) (p) = unRef(*(p)); }
#define deRef2(p, d)	{ (d) = (p); deRef(d); }


		 /*******************************
		 *	COMPOUNDS AND LISTS	*
		 *******************************/

#define functorTerm(w)	valueTerm(w)->definition
#define arityTerm(w)	arityFunctor(valueTerm(w)->definition)
#define valueTerm(w)	((Functor)valPtr2(w, STG_GLOBAL))
#define hasFunctor(w,f) (isTerm(w) && valueTerm(w)->definition == (f))
#define argTerm(w, n)	(((Functor)valPtr(w))->arguments[n])
#define argTermP(w, n)	(&argTerm(w, n))

#define isList(w)	hasFunctor(w, FUNCTOR_dot2)
#define isNil(w)	((w) == ATOM_nil)


		 /*******************************
		 *	      INDIRECTS		*
		 *******************************/

#define mkIndHdr(n, t)	(((n)<<9) | (t) | STG_LOCAL)
#define wsizeofInd(iw)	((iw)>>9)
#define addressIndirect(w) valPtr(w)
#define valIndirectP(w)	(((Word)valPtr(w))+1)

#define padHdr(iw)	(((iw)>>7 & 0x3) ? ((iw)>>7 & 0x3) : 4)
#define mkPadHdr(n)	(((n)&(sizeof(word)-1)) << 7)
#define mkStrHdr(n,p)	(mkIndHdr(n, TAG_STRING)|mkPadHdr(pad))

#define valString(w)	((char *)valIndirectP(w))
#define valBignum(w)	(*(long *)valIndirectP(w))
#define isBignum(w)	(isInteger(w) && storage(w) != STG_INLINE)
#define isTaggedInt(w)	(tagex(w) == (TAG_INTEGER|STG_INLINE))
			/* == (isInteger(w) && storage(w) == STG_INLINE) */

		 /*******************************
		 *	       VALUES		*
		 *******************************/

#define indexAtom(w)	((w)>>LMASK_BITS)
#define atomValue(w)	fetchBuffer(&atom_array, indexAtom(w), Atom)
#define stringAtom(w)	(atomValue(w)->name)
#define valInteger(w)	(storage(w) == STG_INLINE ? valInt(w) : valBignum(w))

		 /*******************************
		 *	      FUNCTORS		*
		 *******************************/

#define F_ARITY_BITS	5		/* upto 32 inlined arity */
#define F_ARITY_MASK	((1<<F_ARITY_BITS)-1)
#define MK_FUNCTOR(n, a) (((((n)<<F_ARITY_BITS)|(a))<<LMASK_BITS) | \
			  TAG_ATOM|STG_GLOBAL)
#define functorHashValue(f, n)	((f)>>(LMASK_BITS) & ((n)-1))
#define indexFunctor(w)	((w)>>(LMASK_BITS+F_ARITY_BITS))
#define valueFunctor(w) fetchBuffer(&functor_array,indexFunctor(w),FunctorDef)
#define _arityFunc_(w)	(((w) >> LMASK_BITS) & F_ARITY_MASK)
#define arityFunctor(w) (_arityFunc_(w)!=F_ARITY_MASK ? _arityFunc_(w) \
						      : valueFunctor(w)->arity)
#define isAtomFunctor(w) (arityFunctor(w) == 0)
#define nameFunctor(w)	(valueFunctor(w)->name)

		 /*******************************
		 *	  DERIVED TESTS		*
		 *******************************/

#define nonvar(w)	(!isVar(w))
#define isNumber(w)	(isInteger(w) || isReal(w))
#define isAtomic(w)	(!isVar(w) && !isTerm(w))


		 /*******************************
		 *	   CREATING WORDS	*
		 *******************************/

#define MAXTAGGEDPTR	((1L<<((8*sizeof(word))-5-1)) - 1)

#define consInt(n)	(((word)(n)<<7) | TAG_INTEGER)
#if !O_DEBUG
#define consPtr(p,ts)	((word)((((word)(p)-base_addresses[(ts)&STG_MASK])<<5)|(ts)))
#endif