Skip to content

Commit d7a1d62

Browse files
Ramsay Jonesgitster
Ramsay Jones
authored andcommitted
commit-slab.h: Fix memory allocation and addressing
The slab initialization code includes the calculation of the slab 'elem_size', which is in turn used to determine the size (capacity) of the slab. Each element of the slab represents an array, of length 'stride', of 'elemtype'. (Note that it may be clearer if the define_commit_slab macro parameter was called 'basetype' rather than 'elemtype'). However, the 'elem_size' calculation incorrectly uses 'sizeof(struct slabname)' in the expression, rather than 'sizeof(elemtype)'. Within the slab access routine, <slabname>_at(), the given commit 'index' is transformed into an (slab#, slot#) pair used to address the required element (a pointer to the first element of the array of 'elemtype' associated with that commit). The current code to calculate these address coordinates multiplies the commit index by the 'stride' which, at least for the slab#, produces the wrong result. Using the commit index directly, without scaling by the 'stride', produces the correct 'logical' address. Also, when allocating a new slab, the size of the allocation only allows for a slab containing elements of single element arrays of 'elemtype'. This should allow for elements of an array of length 'stride' of 'elemtype'. In order to fix this, we need to change the element size parameter to xcalloc() by multiplying the current element size (sizeof(**s->slab)) by the s->stride. Having changed the calculation of the slot#, we now need to convert the logical 'nth_slot', by scaling with s->stride, into the correct physical address. Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent a84b794 commit d7a1d62

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

commit-slab.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void init_ ##slabname## _with_stride(struct slabname *s, \
4848
if (!stride) \
4949
stride = 1; \
5050
s->stride = stride; \
51-
elem_size = sizeof(struct slabname) * stride; \
51+
elem_size = sizeof(elemtype) * stride; \
5252
s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
5353
s->slab_count = 0; \
5454
s->slab = NULL; \
@@ -72,11 +72,10 @@ static void clear_ ##slabname(struct slabname *s) \
7272
static elemtype *slabname## _at(struct slabname *s, \
7373
const struct commit *c) \
7474
{ \
75-
int nth_slab, nth_slot, ix; \
75+
int nth_slab, nth_slot; \
7676
\
77-
ix = c->index * s->stride; \
78-
nth_slab = ix / s->slab_size; \
79-
nth_slot = ix % s->slab_size; \
77+
nth_slab = c->index / s->slab_size; \
78+
nth_slot = c->index % s->slab_size; \
8079
\
8180
if (s->slab_count <= nth_slab) { \
8281
int i; \
@@ -89,8 +88,8 @@ static elemtype *slabname## _at(struct slabname *s, \
8988
} \
9089
if (!s->slab[nth_slab]) \
9190
s->slab[nth_slab] = xcalloc(s->slab_size, \
92-
sizeof(**s->slab)); \
93-
return &s->slab[nth_slab][nth_slot]; \
91+
sizeof(**s->slab) * s->stride); \
92+
return &s->slab[nth_slab][nth_slot * s->stride]; \
9493
} \
9594
\
9695
static int stat_ ##slabname## realloc

0 commit comments

Comments
 (0)