Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions modules/Compiler/SSemanticVisitor.st
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,8 @@ SSemanticVisitor >> initialize [

{ #category : #visiting }
SSemanticVisitor >> visitAssignment: anAssignmentNode [
| c |
self analyzeAssignment: anAssignmentNode.
anAssignmentNode expression acceptVisitor: self.
c := anAssignmentNode compiler.

anAssignmentNode expression acceptVisitor: self
]

{ #category : #visiting }
Expand Down
136 changes: 64 additions & 72 deletions runtime/cpp/Allocator/G1GC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void G1GC::followClosure()
void G1GC::followGCedRefs()
{
_runtime->gcedRefsDo_([this](GCedRef *ref) {
this->queue_from_to_((HeapObject*)ref->getRaw(), 1, 1);
this->scanRoot_(ref->getRaw());
});
}

Expand Down Expand Up @@ -268,101 +268,93 @@ void G1GC::scan_from_to_(HeapObject *anObject, uintptr_t start, uintptr_t end)
_stack.push_back(end);
}

HeapObject* G1GC::resolveObject_(HeapObject *obj)
{
auto evacuate = this->hasToEvacuate_(obj);
if (obj->hasBeenSeen())
return evacuate ? this->copyOf_(obj) : obj;

obj->beSeen();

if (evacuate)
obj = this->evacuate_(obj);
else
this->updateRegionOccupancy_(obj);

if (obj->isSpecial())
this->rememberSpecial_(obj);

return obj;
}

void G1GC::scanBehavior()
{
auto slot = _scanned->behavior();
// printf("scanning behavior of %#" PRIxPTR " (%s)", (uintptr_t)_scanned, _scanned->printString().c_str());
// fflush(stdout);
// printf(", which is %#" PRIxPTR "( %s)\n", (uintptr_t)slot, slot->printString().c_str());
if (((Object*)slot)->isSmallInteger())
{
_index = _index + 1;
return;
}
auto evacuate = this->hasToEvacuate_(slot);
if (slot->hasBeenSeen())
{
if (evacuate)
{
slot = this->copyOf_(slot);
_scanned->behavior(slot);
}
auto slot = _scanned->behavior();
if (((Object*)slot)->isSmallInteger())
{
_index = _index + 1;
return;
}
slot->beSeen();
if (evacuate)
return;
}

bool wasSeen = slot->hasBeenSeen();
slot = this->resolveObject_(slot);
_scanned->behavior(slot);

if (wasSeen)
{
slot = this->evacuate_(slot);
_scanned->behavior(slot);
}
else
{
this->updateRegionOccupancy_(slot);
}
_index = _index + 1;
return;
}

if (slot->isSpecial())
this->rememberSpecial_(slot);

if (_index < _limit)
this->queueCurrent();
this->queueCurrent();

_index = 0;
_limit = slot->strongPointersSize();
_scanned = slot;
}

void G1GC::scanSlot()
void G1GC::scanRoot_(Object** root)
{
// scanned can be a heap object or a chunk of stack frame, we cannot use slotAt_
auto slot = ((Object**)_scanned)[_index-1];
auto stack = debugRuntime->_evaluator->context()->stack();
// if ((uintptr_t)_scanned < (uintptr_t)&stack[0] || (uintptr_t)_scanned > (uintptr_t)&stack[0xFFFF])
// printf("scanning slot %d of %#" PRIxPTR " (%s)", _index, (uintptr_t)_scanned, _scanned->printString().c_str());
// else
// printf("scanning stack slot of frame %#" PRIxPTR " at %d" , (uintptr_t)_scanned, _index);

// fflush(stdout);
// printf(" which is %#" PRIxPTR " (%s)\n", (uintptr_t)slot, slot->printString().c_str());
auto slot = *root;

if (slot->isSmallInteger())
{
_index = _index + 1;
return;
}
return;

auto hslot = slot->asHeapObject();
auto hslot = slot->asHeapObject();
bool wasSeen = hslot->hasBeenSeen();
hslot = this->resolveObject_(hslot);
*root = (Object*)hslot;

auto evacuate = this->hasToEvacuate_(hslot);
if (hslot->hasBeenSeen())
if (!wasSeen)
this->scan_from_to_(hslot, 0, hslot->strongPointersSize());
}

void G1GC::scanSlot()
{
auto &slotRef = _scanned->slotAt_(_index);
auto slot = slotRef;

if (slot == nullptr || slot->isSmallInteger())
{
if (evacuate)
{
hslot = this->copyOf_(hslot);
((Object**)_scanned)[_index-1] = (Object*)hslot;
}
_index = _index + 1;
return;
}
return;
}

hslot->beSeen();
auto hslot = slot->asHeapObject();
bool wasSeen = hslot->hasBeenSeen();
hslot = this->resolveObject_(hslot);
slotRef = (Object*)hslot;

if (evacuate)
if (wasSeen)
{
hslot = this->evacuate_(hslot);
((Object**)_scanned)[_index-1] = (Object*)hslot;
}
else
{
this->updateRegionOccupancy_(hslot);
}
_index = _index + 1;
return;
}

if (hslot->isSpecial())
this->rememberSpecial_(hslot);

if (_index < _limit)
this->queueCurrent();
this->queueCurrent();

_index = 0;
_limit = hslot->strongPointersSize();
_scanned = hslot;
Expand Down
2 changes: 2 additions & 0 deletions runtime/cpp/Allocator/G1GC.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ class G1GC : public GarbageCollector {
//void purgeRememberedSet(); // RE-ENABLE AFTER PLUGGING BACK GENGC
void queue_from_to_(HeapObject *anObject, uintptr_t start, uintptr_t end);
void queueCurrent();
HeapObject* resolveObject_(HeapObject *obj);
void scan_from_to_(HeapObject *anObject, uintptr_t start, uintptr_t end);
void scanRoot_(Object** root);
void scanBehavior();
void scanSlot();
void scanThreadLocalStorage_(HeapObject *thread);
Expand Down
7 changes: 3 additions & 4 deletions runtime/cpp/Allocator/GarbageCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,8 @@ void GarbageCollector::scanNativeStackFrame_sized_(uintptr_t *framePointer, uint
}

void GarbageCollector::scanStackFrameObjects_sized_(uintptr_t *framePointer, uintptr_t size) {
//for (uintptr_t i = 0; i < size; i++)
// printf("adding %s to queue\n", ((Object*)framePointer[i])->printString().c_str());
this->scan_from_to_((HeapObject*)framePointer, 1, size);
for (uintptr_t i = 0; i < size; i++)
this->scanRoot_((Object**)&framePointer[i]);
}

void GarbageCollector::scanSpecialSlots_(HeapObject *special)
Expand Down Expand Up @@ -219,7 +218,7 @@ void GarbageCollector::scanFirstStackChunk_(HeapObject *aProcessVMStack) {

void GarbageCollector::scanPointer_(Object** pointer)
{
this->scan_from_to_((HeapObject*)pointer, 1, 1);
this->scanRoot_(pointer);
}

/* only for use until we have context switches */
Expand Down
1 change: 1 addition & 0 deletions runtime/cpp/Allocator/GarbageCollector.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class GarbageCollector {
void rescueEphemeron_(HeapObject *ephemeron);
bool rescueUnreachableEphemerons();
virtual void scan_from_to_(HeapObject *current, uintptr_t start, uintptr_t limit) = 0;
virtual void scanRoot_(Object** root) = 0;
void scanNativeStackFrame_sized_(uintptr_t *framePointer, uintptr_t size);
void scanStackFrameObjects_sized_(uintptr_t *framePointer, uintptr_t size);
void scanSpecialSlots_(HeapObject *special);
Expand Down
22 changes: 22 additions & 0 deletions runtime/cpp/Bootstrap/BootstrappedKernel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright (c) 2025-2026, Javier Pimás.
See (MIT) license in root directory.
*/

#include "BootstrappedKernel.h"
#include <cstring>

namespace Egg {

BootstrappedKernel::BootstrappedKernel(uintptr_t base, uintptr_t size, uintptr_t objectsEnd)
{
// Bootstrap objects live directly in memory with no prefixed header,
// so we offset _currentBase so that spaceStart() returns 'base'.
_currentBase = base - sizeof(ImageSegmentHeader);
header.baseAddress = base;
header.size = objectsEnd - _currentBase;
header.reservedSize = size + sizeof(ImageSegmentHeader);
header.module = nullptr;
}

} // namespace Egg
29 changes: 29 additions & 0 deletions runtime/cpp/Bootstrap/BootstrappedKernel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright (c) 2025-2026, Javier Pimás.
See (MIT) license in root directory.
*/

#ifndef _BOOTSTRAPPED_KERNEL_H_
#define _BOOTSTRAPPED_KERNEL_H_

#include "../ImageSegment.h"
#include <string>

namespace Egg {

/**
* BootstrappedKernel wraps a GCSpace containing bootstrapped kernel objects
* and presents it as an ImageSegment for Runtime consumption.
*/
class BootstrappedKernel : public ImageSegment {
public:
BootstrappedKernel(uintptr_t base, uintptr_t size, uintptr_t objectsEnd);

void addExport(const std::string& name, HeapObject* obj) {
_exports[name] = obj;
}
};

} // namespace Egg

#endif // _BOOTSTRAPPED_KERNEL_H_
Loading
Loading