summaryrefslogtreecommitdiff
path: root/src/runtime/mheap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/mheap.c')
-rw-r--r--src/runtime/mheap.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/runtime/mheap.c b/src/runtime/mheap.c
index 9c6de16af..427d11082 100644
--- a/src/runtime/mheap.c
+++ b/src/runtime/mheap.c
@@ -98,9 +98,20 @@ HaveSpan:
// No matter what, cache span info, because gc needs to be
// able to map interior pointer to containing span.
s->sizeclass = sizeclass;
- for(n=0; n<npage; n++) {
+ for(n=0; n<npage; n++)
MHeapMap_Set(&h->map, s->start+n, s);
- if(sizeclass != 0)
+ if(sizeclass == 0) {
+ uintptr tmp;
+
+ // If there are entries for this span, invalidate them,
+ // but don't blow out cache entries about other spans.
+ for(n=0; n<npage; n++)
+ if(MHeapMapCache_GET(&h->mapcache, s->start+n, tmp) != 0)
+ MHeapMapCache_SET(&h->mapcache, s->start+n, 0);
+ } else {
+ // Save cache entries for this span.
+ // If there's a size class, there aren't that many pages.
+ for(n=0; n<npage; n++)
MHeapMapCache_SET(&h->mapcache, s->start+n, sizeclass);
}
@@ -168,6 +179,8 @@ MHeap_Grow(MHeap *h, uintptr npage)
return false;
}
+ // Create a fake "in use" span and free it, so that the
+ // right coalescing happens.
s = FixAlloc_Alloc(&h->spanalloc);
MSpan_Init(s, (uintptr)v>>PageShift, ask>>PageShift);
MHeapMap_Set(&h->map, s->start, s);
@@ -198,8 +211,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
{
MSpan *t;
- if(s->state != MSpanInUse || s->ref != 0)
+ if(s->state != MSpanInUse || s->ref != 0) {
+ printf("MHeap_FreeLocked - span %p ptr %p state %d ref %d\n", s, s->start<<PageShift, s->state, s->ref);
throw("MHeap_FreeLocked - invalid free");
+ }
s->state = MSpanFree;
MSpanList_Remove(s);