Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | /* Copyright (C) 2012,2016 Matthew Fluet. |
2 | * Copyright (C) 1999-2008 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 | /* newObject (s, header, bytesRequested, allocInOldGen) | |
11 | * | |
12 | * Allocate a new object in the heap. | |
13 | * bytesRequested includes the size of the header. | |
14 | */ | |
15 | pointer newObject (GC_state s, | |
16 | GC_header header, | |
17 | size_t bytesRequested, | |
18 | bool allocInOldGen) { | |
19 | pointer frontier; | |
20 | pointer result; | |
21 | ||
22 | assert (isAligned (bytesRequested, s->alignment)); | |
23 | assert (allocInOldGen | |
24 | ? hasHeapBytesFree (s, bytesRequested, 0) | |
25 | : hasHeapBytesFree (s, 0, bytesRequested)); | |
26 | if (allocInOldGen) { | |
27 | frontier = s->heap.start + s->heap.oldGenSize; | |
28 | s->heap.oldGenSize += bytesRequested; | |
29 | s->cumulativeStatistics.bytesAllocated += bytesRequested; | |
30 | } else { | |
31 | if (DEBUG_DETAILED) | |
32 | fprintf (stderr, "frontier changed from "FMTPTR" to "FMTPTR"\n", | |
33 | (uintptr_t)s->frontier, | |
34 | (uintptr_t)(s->frontier + bytesRequested)); | |
35 | frontier = s->frontier; | |
36 | s->frontier += bytesRequested; | |
37 | } | |
38 | GC_profileAllocInc (s, bytesRequested); | |
39 | *((GC_header*)frontier) = header; | |
40 | result = frontier + GC_HEADER_SIZE; | |
41 | assert (isAligned ((size_t)result, s->alignment)); | |
42 | if (DEBUG) | |
43 | fprintf (stderr, FMTPTR " = newObject ("FMTHDR", %"PRIuMAX", %s)\n", | |
44 | (uintptr_t)result, | |
45 | header, | |
46 | (uintmax_t)bytesRequested, | |
47 | boolToString (allocInOldGen)); | |
48 | return result; | |
49 | } | |
50 | ||
51 | GC_stack newStack (GC_state s, | |
52 | size_t reserved, | |
53 | bool allocInOldGen) { | |
54 | GC_stack stack; | |
55 | ||
56 | assert (isStackReservedAligned (s, reserved)); | |
57 | if (reserved > s->cumulativeStatistics.maxStackSize) | |
58 | s->cumulativeStatistics.maxStackSize = reserved; | |
59 | stack = (GC_stack)(newObject (s, GC_STACK_HEADER, | |
60 | sizeofStackWithMetaData (s, reserved), | |
61 | allocInOldGen)); | |
62 | stack->reserved = reserved; | |
63 | stack->used = 0; | |
64 | if (DEBUG_STACKS) | |
65 | fprintf (stderr, FMTPTR " = newStack (%"PRIuMAX")\n", | |
66 | (uintptr_t)stack, | |
67 | (uintmax_t)reserved); | |
68 | return stack; | |
69 | } | |
70 | ||
71 | GC_thread newThread (GC_state s, size_t reserved) { | |
72 | GC_stack stack; | |
73 | GC_thread thread; | |
74 | pointer res; | |
75 | ||
76 | assert (isStackReservedAligned (s, reserved)); | |
77 | ensureHasHeapBytesFree (s, 0, sizeofStackWithMetaData (s, reserved) + sizeofThread (s)); | |
78 | stack = newStack (s, reserved, FALSE); | |
79 | res = newObject (s, GC_THREAD_HEADER, | |
80 | sizeofThread (s), | |
81 | FALSE); | |
82 | thread = (GC_thread)(res + offsetofThread (s)); | |
83 | thread->bytesNeeded = 0; | |
84 | thread->exnStack = BOGUS_EXN_STACK; | |
85 | thread->stack = pointerToObjptr((pointer)stack, s->heap.start); | |
86 | if (DEBUG_THREADS) | |
87 | fprintf (stderr, FMTPTR" = newThreadOfSize (%"PRIuMAX")\n", | |
88 | (uintptr_t)thread, (uintmax_t)reserved);; | |
89 | return thread; | |
90 | } | |
91 | ||
92 | static inline void setFrontier (GC_state s, pointer p, | |
93 | ARG_USED_FOR_ASSERT size_t bytes) { | |
94 | p = alignFrontier (s, p); | |
95 | assert ((size_t)(p - s->frontier) <= bytes); | |
96 | GC_profileAllocInc (s, (size_t)(p - s->frontier)); | |
97 | s->cumulativeStatistics.bytesAllocated += (size_t)(p - s->frontier); | |
98 | s->frontier = p; | |
99 | assert (s->frontier <= s->limitPlusSlop); | |
100 | } |