diff --git a/src/heap.cpp b/src/heap.cpp index b3f7eea200..4b7703aacc 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -509,6 +509,9 @@ class Context { lowMemoryThreshold(limit / 2), lock(0), + immortalHeapStart(0), + immortalHeapEnd(0), + ageMap(&gen1, max(1, log(TenureThreshold)), 1, 0, false), gen1(this, &ageMap, 0, 0), @@ -577,6 +580,9 @@ class Context { unsigned lowMemoryThreshold; System::Mutex* lock; + + void* immortalHeapStart; + void* immortalHeapEnd; Segment::Map ageMap; Segment gen1; @@ -948,7 +954,9 @@ update3(Context* c, void* o, bool* needsVisit) void* update2(Context* c, void* o, bool* needsVisit) { - if (c->mode == Heap::MinorCollection and c->gen2.contains(o)) { + if ((o < c->immortalHeapEnd and o > c->immortalHeapStart) + or (c->mode == Heap::MinorCollection and c->gen2.contains(o))) + { *needsVisit = false; return o; } @@ -1669,6 +1677,11 @@ class MyHeap: public Heap { c.client = client; } + virtual void setImmortalHeap(uintptr_t* start, unsigned sizeInWords) { + c.immortalHeapStart = start; + c.immortalHeapEnd = start + sizeInWords; + } + virtual void* tryAllocate(unsigned size) { return ::tryAllocate(&c, size); } @@ -1698,8 +1711,9 @@ class MyHeap: public Heap { Fixie(sizeInWords, objectMask, &(c.fixies), false))->body(); } - virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords, - bool objectMask, unsigned* totalInBytes) + virtual void* allocateImmortalFixed(Allocator* allocator, + unsigned sizeInWords, bool objectMask, + unsigned* totalInBytes) { *totalInBytes = Fixie::totalSize(sizeInWords, objectMask); return (new (allocator->allocate(*totalInBytes)) diff --git a/src/heap.h b/src/heap.h index bc8f9a5a1c..28f1533d8f 100644 --- a/src/heap.h +++ b/src/heap.h @@ -52,11 +52,13 @@ class Heap: public Allocator { }; virtual void setClient(Client* client) = 0; + virtual void setImmortalHeap(uintptr_t* start, unsigned sizeInWords) = 0; virtual void collect(CollectionType type, unsigned footprint) = 0; virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords, bool objectMask, unsigned* totalInBytes) = 0; - virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords, - bool objectMask, unsigned* totalInBytes) = 0; + virtual void* allocateImmortalFixed(Allocator* allocator, + unsigned sizeInWords, bool objectMask, + unsigned* totalInBytes) = 0; virtual bool needsMark(void* p) = 0; virtual bool needsMark(void* p, unsigned offset) = 0; virtual void mark(void* p, unsigned offset, unsigned count) = 0; diff --git a/src/machine.cpp b/src/machine.cpp index 78a0063995..4d0df1861f 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1512,6 +1512,8 @@ boot(Thread* t, BootImage* image) (heapMapSize(image->heapSize), BytesPerWord); uintptr_t* heap = heapMap + heapMapSizeInWords; + t->m->heap->setImmortalHeap(heap, image->heapSize); + for (unsigned word = 0; word < heapMapSizeInWords; ++word) { uintptr_t w = heapMap[word]; if (w) { @@ -2170,7 +2172,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type, case Machine::ImmortalAllocation: { unsigned total; object o = static_cast - (t->m->heap->allocateImmortal + (t->m->heap->allocateImmortalFixed (allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total)); cast(o, 0) = FixedMark;