| 1 | /* Copyright (C) 2016 Matthew Fluet. |
| 2 | * Copyright (C) 1999-2007 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 | size_t sizeofWeak (GC_state s) { |
| 11 | size_t res; |
| 12 | |
| 13 | res = GC_NORMAL_METADATA_SIZE + sizeof (struct GC_weak); |
| 14 | res = align (res, s->alignment); |
| 15 | if (DEBUG) { |
| 16 | size_t check; |
| 17 | uint16_t bytesNonObjptrs, numObjptrs; |
| 18 | |
| 19 | splitHeader (s, GC_WEAK_GONE_HEADER, NULL, NULL, &bytesNonObjptrs, &numObjptrs); |
| 20 | check = GC_NORMAL_METADATA_SIZE + (bytesNonObjptrs + (numObjptrs * OBJPTR_SIZE)); |
| 21 | if (DEBUG_DETAILED) |
| 22 | fprintf (stderr, |
| 23 | "sizeofWeak: res = %"PRIuMAX" check = %"PRIuMAX"\n", |
| 24 | (uintmax_t)res, (uintmax_t)check); |
| 25 | assert (check == res); |
| 26 | } |
| 27 | assert (isAligned (res, s->alignment)); |
| 28 | return res; |
| 29 | } |
| 30 | |
| 31 | size_t offsetofWeak (GC_state s) { |
| 32 | return (sizeofWeak (s)) - (GC_NORMAL_METADATA_SIZE + sizeof (struct GC_weak)); |
| 33 | } |
| 34 | |
| 35 | uint32_t GC_weakCanGet (__attribute__ ((unused)) GC_state s, pointer p) { |
| 36 | uint32_t res; |
| 37 | |
| 38 | res = GC_WEAK_GONE_HEADER != getHeader (p); |
| 39 | if (DEBUG_WEAK) |
| 40 | fprintf (stderr, "%s = GC_weakCanGet ("FMTPTR")\n", |
| 41 | boolToString (res), (uintptr_t)p); |
| 42 | return res; |
| 43 | } |
| 44 | |
| 45 | pointer GC_weakGet (GC_state s, pointer p) { |
| 46 | GC_weak weak; |
| 47 | pointer res; |
| 48 | |
| 49 | weak = (GC_weak)(p + offsetofWeak (s)); |
| 50 | res = objptrToPointer(weak->objptr, s->heap.start); |
| 51 | if (DEBUG_WEAK) |
| 52 | fprintf (stderr, FMTPTR" = GC_weakGet ("FMTPTR")\n", |
| 53 | (uintptr_t)res, (uintptr_t)p); |
| 54 | return res; |
| 55 | } |
| 56 | |
| 57 | pointer GC_weakNew (GC_state s, GC_header header, pointer p) { |
| 58 | GC_weak weak; |
| 59 | pointer res; |
| 60 | |
| 61 | res = newObject (s, header, |
| 62 | sizeofWeak (s), |
| 63 | FALSE); |
| 64 | weak = (GC_weak)(res + offsetofWeak (s)); |
| 65 | weak->objptr = pointerToObjptr(p, s->heap.start); |
| 66 | if (DEBUG_WEAK) |
| 67 | fprintf (stderr, FMTPTR" = GC_weakNew ("FMTHDR", "FMTPTR")\n", |
| 68 | (uintptr_t)res, header, (uintptr_t)p); |
| 69 | return (pointer)res; |
| 70 | } |