Commit | Line | Data |
---|---|---|
7f918cf1 CE |
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 | } |