Skip to content

Commit

Permalink
Reduce size of heap block per-granule maps twice for 4KB heap blocks
Browse files Browse the repository at this point in the history
If MAXOBJGRANULES-1 fits into a byte, we could use unsigned char
(instead of short) type for hb_map elements.

* docs/tree.md (A picture): Specify that element of GC_obj_map is of
either 8 or 16 bits (instead of 16 bits strictly); specify that hb_map
field of hblkhdr could be of uchar* type.
* include/private/gc_priv.h [!MARK_BIT_PER_OBJ] (hb_map_entry_t): New
type (defined depending on values of CPP_LOG_HBLKSIZE and
GC_GRANULE_BYTES); add comment.
* include/private/gc_priv.h [!MARK_BIT_PER_OBJ] (hblkhdr.hb_map,
_GC_arrays._obj_map[]): Change type from unsigned short* to
hb_map_entry_t*.
* obj_map.c [!MARK_BIT_PER_OBJ] (GC_add_map_entry): Change type of
new_map local variable from unsigned short* to hb_map_entry_t*; update
relevant casts and GC_scratch_alloc() argument accordingly; replace
0xffff to ~(hb_map_entry_t)0 in static assertion; expect GC_obj_map[lg]
is already non-NULL on entrance.
  • Loading branch information
ivmai committed Sep 3, 2024
1 parent 282d4fc commit 57ccbcc
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
4 changes: 2 additions & 2 deletions docs/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ contributed originally by Dave Barrett.
| | |<--OBJ_MAP_LEN-->|
| | =HBLKSIZE/GC_GRANULE_BYTES
HDR(p)| GC_find_header(p) | (1024 elements on Alpha)
| \ from | (16 bits each)
| \ from | (8/16 bits each)
| (hdr) (struct hblkhdr) / alloc_hdr() |
+--->+----------------------+ |
GET_HDR(p)| struct hblk *hb_next | |
Expand All @@ -141,7 +141,7 @@ contributed originally by Dave Barrett.
+----------------------+ |
| word hb_descr | |
+----------------------+ |
| ushort *hb_map |>------------+
| uchar/ushort *hb_map |>------------+
+----------------------+
| AO_t hb_n_marks |
--- +----------------------+
Expand Down
15 changes: 13 additions & 2 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,17 @@ typedef word page_hash_table[PHT_SIZE];
/* initial group of mark bits, and it is safe to */
/* allocate smaller header for large objects. */

#ifndef MARK_BIT_PER_OBJ
/* We maintain layout maps for heap blocks containing objects of */
/* a given size. Each entry in this map describes a byte offset */
/* (displacement) and has the following type. */
# if (1 << (CPP_LOG_HBLKSIZE - 1)) / GC_GRANULE_BYTES <= 0x100
typedef unsigned char hb_map_entry_t;
# else
typedef unsigned short hb_map_entry_t;
# endif
#endif /* !MARK_BIT_PER_OBJ */

struct hblkhdr {
struct hblk * hb_next; /* Link field for hblk free list */
/* and for lists of chunks waiting to be */
Expand Down Expand Up @@ -1143,7 +1154,7 @@ struct hblkhdr {
word hb_descr; /* Object descriptor for marking. */
/* See gc_mark.h. */
# ifndef MARK_BIT_PER_OBJ
unsigned short * hb_map; /* Essentially a table of remainders */
hb_map_entry_t *hb_map; /* Essentially a table of remainders */
/* mod BYTES_TO_GRANULES(hb_sz), except */
/* for large blocks. See GC_obj_map. */
# endif
Expand Down Expand Up @@ -1619,7 +1630,7 @@ struct _GC_arrays {
/* the allocator lock held. */
# ifndef MARK_BIT_PER_OBJ
# define GC_obj_map GC_arrays._obj_map
unsigned short * _obj_map[MAXOBJGRANULES+1];
hb_map_entry_t *_obj_map[MAXOBJGRANULES+1];
/* If not NULL, then a pointer to a map of valid */
/* object addresses. GC_obj_map[lg][i] is */
/* i % lg. This is now used purely to replace */
Expand Down
11 changes: 6 additions & 5 deletions obj_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ GC_INNER void GC_register_displacement_inner(size_t offset)
GC_INNER GC_bool GC_add_map_entry(size_t lg)
{
size_t displ;
unsigned short * new_map;
hb_map_entry_t *new_map;

GC_ASSERT(I_HOLD_LOCK());
GC_STATIC_ASSERT(MAXOBJGRANULES - 1U <= 0xffffU /* max ushort */);
GC_STATIC_ASSERT(MAXOBJGRANULES - 1 <= (size_t)(~(hb_map_entry_t)0));
if (lg > MAXOBJGRANULES) lg = 0;
if (GC_obj_map[lg] != 0) return TRUE;
if (EXPECT(GC_obj_map[lg] != NULL, TRUE)) return TRUE;

new_map = (unsigned short *)GC_scratch_alloc(OBJ_MAP_LEN * sizeof(short));
new_map = (hb_map_entry_t *)GC_scratch_alloc(OBJ_MAP_LEN
* sizeof(hb_map_entry_t));
if (EXPECT(NULL == new_map, FALSE)) return FALSE;

GC_COND_LOG_PRINTF(
Expand All @@ -66,7 +67,7 @@ GC_INNER void GC_register_displacement_inner(size_t offset)
}
} else {
for (displ = 0; displ < OBJ_MAP_LEN; displ++) {
new_map[displ] = (unsigned short)(displ % lg);
new_map[displ] = (hb_map_entry_t)(displ % lg);
}
}
GC_obj_map[lg] = new_map;
Expand Down

0 comments on commit 57ccbcc

Please sign in to comment.