Skip to content

Commit

Permalink
Modernize heap initialization
Browse files Browse the repository at this point in the history
This also makes the vectors of the generational heap part of the heap object.

Signed-off-by: Stefan Marr <[email protected]>
  • Loading branch information
smarr committed Aug 20, 2024
1 parent 17fce38 commit f0ac4d2
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---
Checks: '*include*,
bugprone-branch-clone,
cppcoreguidelines-prefer-member-initializer,
bugprone-implicit-widening-of-multiplication-result,
modernize-use-nodiscard,
cppcoreguidelines-init-variables,
misc-const-correctness,
Expand Down
26 changes: 10 additions & 16 deletions src/memory/CopyingHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,16 @@
#include "Heap.h"

CopyingHeap::CopyingHeap(size_t objectSpaceSize)
: Heap<CopyingHeap>(new CopyingCollector(this)) {
size_t const bufSize = objectSpaceSize;

currentBuffer = malloc(bufSize);
oldBuffer = malloc(bufSize);

memset(currentBuffer, 0x0, bufSize);
memset(oldBuffer, 0x0, bufSize);

currentBufferEnd = (void*)((size_t)currentBuffer + bufSize);
collectionLimit =
(void*)((size_t)currentBuffer + ((size_t)((double)bufSize * 0.9)));
nextFreePosition = currentBuffer;

oldBufferEnd = (void*)((size_t)oldBuffer + bufSize);
oldBufferIsValid = false;
: Heap<CopyingHeap>(new CopyingCollector(this)),
currentBuffer(malloc(objectSpaceSize)),
oldBuffer(malloc(objectSpaceSize)),
currentBufferEnd((void*)((size_t)currentBuffer + objectSpaceSize)),
collectionLimit((void*)((size_t)currentBuffer +
((size_t)((double)objectSpaceSize * 0.9)))),
oldBufferEnd((void*)((size_t)oldBuffer + objectSpaceSize)),
nextFreePosition(currentBuffer) {
memset(currentBuffer, 0x0, objectSpaceSize);
memset(oldBuffer, 0x0, objectSpaceSize);
}

void CopyingHeap::switchBuffers(bool increaseMemory) {
Expand Down
2 changes: 1 addition & 1 deletion src/memory/CopyingHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ class CopyingHeap : public Heap<CopyingHeap> {
void* oldBufferEnd;

void* nextFreePosition;
bool oldBufferIsValid;
bool oldBufferIsValid{false};
};
27 changes: 13 additions & 14 deletions src/memory/GenerationalCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <vector>

#include "../misc/debug.h"
Expand All @@ -14,13 +15,12 @@
#include "../vmobjects/VMObjectBase.h"
#include "GarbageCollector.h"

#define INITIAL_MAJOR_COLLECTION_THRESHOLD (5 * 1024 * 1024) // 5 MB
#define INITIAL_MAJOR_COLLECTION_THRESHOLD \
((uintptr_t)5 * 1024U * 1024U) // 5 MB

GenerationalCollector::GenerationalCollector(GenerationalHeap* heap)
: GarbageCollector(heap) {
majorCollectionThreshold = INITIAL_MAJOR_COLLECTION_THRESHOLD;
matureObjectsSize = 0;
}
: GarbageCollector(heap),
majorCollectionThreshold(INITIAL_MAJOR_COLLECTION_THRESHOLD) {}

static gc_oop_t mark_object(gc_oop_t oop) {
// don't process tagged objects
Expand Down Expand Up @@ -89,8 +89,8 @@ void GenerationalCollector::MinorCollection() {
Universe::WalkGlobals(&copy_if_necessary);

// and also all objects that have been detected by the write barriers
for (auto objIter = heap->oldObjsWithRefToYoungObjs->begin();
objIter != heap->oldObjsWithRefToYoungObjs->end();
for (auto objIter = heap->oldObjsWithRefToYoungObjs.begin();
objIter != heap->oldObjsWithRefToYoungObjs.end();
objIter++) {
// content of oldObjsWithRefToYoungObjs is not altered while iteration,
// because copy_if_necessary returns old objs only -> ignored by
Expand All @@ -99,7 +99,7 @@ void GenerationalCollector::MinorCollection() {
obj->SetGCField(MASK_OBJECT_IS_OLD);
obj->WalkObjects(&copy_if_necessary);
}
heap->oldObjsWithRefToYoungObjs->clear();
heap->oldObjsWithRefToYoungObjs.clear();
heap->nextFreePosition = heap->nursery;
}

Expand All @@ -111,22 +111,21 @@ void GenerationalCollector::MajorCollection() {

// now that all objects are marked we can safely delete all allocated
// objects that are not marked
auto* survivors = new vector<AbstractVMObject*>();
for (auto objIter = heap->allocatedObjects->begin();
objIter != heap->allocatedObjects->end();
vector<AbstractVMObject*> survivors;
for (auto objIter = heap->allocatedObjects.begin();
objIter != heap->allocatedObjects.end();
objIter++) {
AbstractVMObject* obj = *objIter;
assert(IsValidObject(obj));

if ((obj->GetGCField() & MASK_OBJECT_IS_MARKED) != 0) {
survivors->push_back(obj);
survivors.push_back(obj);
obj->SetGCField(MASK_OBJECT_IS_OLD);
} else {
heap->FreeObject(obj);
}
}
delete heap->allocatedObjects;
heap->allocatedObjects = survivors;
heap->allocatedObjects.swap(survivors);
}

void GenerationalCollector::Collect() {
Expand Down
2 changes: 1 addition & 1 deletion src/memory/GenerationalCollector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class GenerationalCollector : public GarbageCollector<GenerationalHeap> {

private:
uintptr_t majorCollectionThreshold;
size_t matureObjectsSize;
size_t matureObjectsSize{0};
void MajorCollection();
void MinorCollection();
};
27 changes: 11 additions & 16 deletions src/memory/GenerationalHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,16 @@
using namespace std;

GenerationalHeap::GenerationalHeap(size_t objectSpaceSize)
: Heap<GenerationalHeap>(new GenerationalCollector(this)) {
// our initial collection limit is 90% of objectSpaceSize
// collectionLimit = objectSpaceSize * 0.9;

nursery = malloc(objectSpaceSize);
nurserySize = objectSpaceSize;
maxNurseryObjSize = objectSpaceSize / 2;
nursery_end = (size_t)nursery + nurserySize;
matureObjectsSize = 0;
: Heap<GenerationalHeap>(new GenerationalCollector(this)),
nursery(malloc(objectSpaceSize)),
nursery_end((size_t)nursery + objectSpaceSize),
nurserySize(objectSpaceSize), maxNurseryObjSize(objectSpaceSize / 2),
nextFreePosition(nursery),

// our initial collection limit is 90% of objectSpaceSize
collectionLimit((void*)((size_t)nursery +
((size_t)((double)objectSpaceSize * 0.9)))) {
memset(nursery, 0x0, objectSpaceSize);
collectionLimit =
(void*)((size_t)nursery + ((size_t)((double)objectSpaceSize * 0.9)));
nextFreePosition = nursery;
allocatedObjects = new vector<AbstractVMObject*>();
oldObjsWithRefToYoungObjs = new vector<size_t>();
}

AbstractVMObject* GenerationalHeap::AllocateNurseryObject(size_t size) {
Expand All @@ -53,15 +48,15 @@ AbstractVMObject* GenerationalHeap::AllocateMatureObject(size_t size) {
ErrorPrint("\nFailed to allocate " + to_string(size) + " Bytes.\n");
Quit(-1);
}
allocatedObjects->push_back(newObject);
allocatedObjects.push_back(newObject);
matureObjectsSize += size;
return newObject;
}

void GenerationalHeap::writeBarrier_OldHolder(VMObjectBase* holder,
const vm_oop_t referencedObject) {
if (isObjectInNursery(referencedObject)) {
oldObjsWithRefToYoungObjs->push_back((size_t)holder);
oldObjsWithRefToYoungObjs.push_back((size_t)holder);
holder->SetGCField(holder->GetGCField() | MASK_SEEN_BY_WRITE_BARRIER);
}
}
6 changes: 3 additions & 3 deletions src/memory/GenerationalHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class GenerationalHeap : public Heap<GenerationalHeap> {
size_t nursery_end;
size_t nurserySize;
size_t maxNurseryObjSize;
size_t matureObjectsSize;
size_t matureObjectsSize{0};
void* nextFreePosition;
void writeBarrier_OldHolder(VMObjectBase* holder,
vm_oop_t referencedObject);
void* collectionLimit;
vector<size_t>* oldObjsWithRefToYoungObjs;
vector<AbstractVMObject*>* allocatedObjects;
vector<size_t> oldObjsWithRefToYoungObjs;
vector<AbstractVMObject*> allocatedObjects;
};

inline bool GenerationalHeap::isObjectInNursery(vm_oop_t obj) {
Expand Down
1 change: 0 additions & 1 deletion src/vmobjects/VMSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ VMSymbol::VMSymbol(const size_t length, const char* const str)
length),
numberOfArgumentsOfSignature(
Signature::DetermineNumberOfArguments(str, length)) {
nextCachePos = 0;
size_t i = 0;
for (; i < length; ++i) {
chars[i] = str[i];
Expand Down
2 changes: 1 addition & 1 deletion src/vmobjects/VMSymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class VMSymbol : public VMString {
private:
const uint8_t numberOfArgumentsOfSignature;
GCClass* cachedClass_invokable[3]{};
size_t nextCachePos;
size_t nextCachePos{0};
GCInvokable* cachedInvokable[3]{};

inline VMInvokable* GetCachedInvokable(const VMClass* cls) const {
Expand Down

0 comments on commit f0ac4d2

Please sign in to comment.