Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / gc / object.c
1 /* Copyright (C) 2012,2016 Matthew Fluet.
2 * Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
4 * Copyright (C) 1997-2000 NEC Research Institute.
5 *
6 * MLton is released under a BSD-style license.
7 * See the file MLton-LICENSE for details.
8 */
9
10 const char* objectTypeTagToString (GC_objectTypeTag tag) {
11 switch (tag) {
12 case ARRAY_TAG:
13 return "ARRAY";
14 case NORMAL_TAG:
15 return "NORMAL";
16 case STACK_TAG:
17 return "STACK";
18 case WEAK_TAG:
19 return "WEAK";
20 default:
21 die ("bad GC_objectTypeTag %u", tag);
22 }
23 }
24
25 /* getHeaderp (p)
26 *
27 * Returns a pointer to the header for the object pointed to by p.
28 */
29 GC_header* getHeaderp (pointer p) {
30 return (GC_header*)(p
31 - GC_HEADER_SIZE);
32 }
33
34 /* getHeader (p)
35 *
36 * Returns the header for the object pointed to by p.
37 */
38 GC_header getHeader (pointer p) {
39 return *(getHeaderp(p));
40 }
41
42 /*
43 * Build the header for an object, given the index to its type info.
44 */
45 GC_header buildHeaderFromTypeIndex (uint32_t t) {
46 assert (t < TWOPOWER (TYPE_INDEX_BITS));
47 return 1 | (t << 1);
48 }
49
50 void splitHeader(GC_state s, GC_header header,
51 GC_objectTypeTag *tagRet, bool *hasIdentityRet,
52 uint16_t *bytesNonObjptrsRet, uint16_t *numObjptrsRet) {
53 unsigned int objectTypeIndex;
54 GC_objectType objectType;
55 GC_objectTypeTag tag;
56 bool hasIdentity;
57 uint16_t bytesNonObjptrs, numObjptrs;
58
59 assert (1 == (header & GC_VALID_HEADER_MASK));
60 objectTypeIndex = (header & TYPE_INDEX_MASK) >> TYPE_INDEX_SHIFT;
61 assert (objectTypeIndex < s->objectTypesLength);
62 objectType = &(s->objectTypes[objectTypeIndex]);
63 tag = objectType->tag;
64 hasIdentity = objectType->hasIdentity;
65 bytesNonObjptrs = objectType->bytesNonObjptrs;
66 numObjptrs = objectType->numObjptrs;
67
68 if (DEBUG_DETAILED)
69 fprintf (stderr,
70 "splitHeader ("FMTHDR")"
71 " objectTypeIndex = %u"
72 " tag = %s"
73 " hasIdentity = %s"
74 " bytesNonObjptrs = %"PRIu16
75 " numObjptrs = %"PRIu16"\n",
76 header,
77 objectTypeIndex,
78 objectTypeTagToString(tag),
79 boolToString(hasIdentity),
80 bytesNonObjptrs, numObjptrs);
81
82 if (tagRet != NULL)
83 *tagRet = tag;
84 if (hasIdentityRet != NULL)
85 *hasIdentityRet = hasIdentity;
86 if (bytesNonObjptrsRet != NULL)
87 *bytesNonObjptrsRet = bytesNonObjptrs;
88 if (numObjptrsRet != NULL)
89 *numObjptrsRet = numObjptrs;
90 }
91
92 /* advanceToObjectData (s, p)
93 *
94 * If p points at the beginning of an object, then advanceToObjectData
95 * returns a pointer to the start of the object data.
96 */
97 pointer advanceToObjectData (ARG_USED_FOR_ASSERT GC_state s, pointer p) {
98 GC_header header;
99 pointer res;
100
101 assert (isFrontierAligned (s, p));
102 header = *(GC_header*)p;
103 if (0 == header)
104 /* Looking at the counter word in an array. */
105 res = p + GC_ARRAY_METADATA_SIZE;
106 else
107 /* Looking at a header word. */
108 res = p + GC_NORMAL_METADATA_SIZE;
109 assert (isAligned ((uintptr_t)res, s->alignment));
110 if (DEBUG_DETAILED)
111 fprintf (stderr, FMTPTR" = advanceToObjectData ("FMTPTR")\n",
112 (uintptr_t)res, (uintptr_t)p);
113 return res;
114 }