summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-08-20 11:25:50 +0100
committerNicholas Clark <nick@ccl4.org>2010-08-20 17:34:39 +0100
commit29657bb6c05aaef4172308097542f56a92e02a08 (patch)
tree7bb1617504da0ddc2506d9a4bbc9a1b28b4f6c0c /sv.c
parenteaeb1e7f3008ef8680fd7726bb124dac46e2f98c (diff)
downloadperl-29657bb6c05aaef4172308097542f56a92e02a08.tar.gz
Refactor the loop of S_more_bodies() to be (hopefully) clearer.
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/sv.c b/sv.c
index 77bb1b504a..bf1adc0574 100644
--- a/sv.c
+++ b/sv.c
@@ -1053,7 +1053,9 @@ S_more_bodies (pTHX_ const svtype sv_type)
start = (char*) Perl_get_arena(aTHX_ arena_size, sv_type);
- end = start + arena_size - 2 * body_size;
+ /* Get the address of the byte after the end of the last body we can fit.
+ Remember, this is integer division: */
+ end = start + arena_size / body_size * body_size;
/* computed count doesnt reflect the 1st slot reservation */
#if defined(MYMALLOC) || defined(HAS_MALLOC_GOOD_SIZE)
@@ -1072,14 +1074,21 @@ S_more_bodies (pTHX_ const svtype sv_type)
#endif
*root = (void *)start;
- while (start <= end) {
+ while (1) {
+ /* Where the next body would start: */
char * const next = start + body_size;
+
+ if (next >= end) {
+ /* This is the last body: */
+ assert(next == end);
+
+ *(void **)start = 0;
+ return *root;
+ }
+
*(void**) start = (void *)next;
start = next;
}
- *(void **)start = 0;
-
- return *root;
}
/* grab a new thing from the free list, allocating more if necessary.