Skip to content

Commit e9c48dc

Browse files
committed
[Heavy] Fix garbage collector... mostly
1 parent 3641fd2 commit e9c48dc

File tree

6 files changed

+58
-19
lines changed

6 files changed

+58
-19
lines changed

heavy/include/heavy/Context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class Context : public ContinuationStack<Context>,
146146
RaiseError(CreateString(Msg), IrrArgs);
147147
}
148148

149+
using Heap<Context>::MaybeCollectGarbage;
149150
void CollectGarbage();
150151

151152
// WithEnv - Call a thunk with an environment and the ability to clean up

heavy/include/heavy/ContinuationStack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ class ContinuationStack {
276276
// This means a C++ function was not written correctly.
277277
assert((DidCallContinuation || getDerived().CheckError()) &&
278278
"function failed to call continuation");
279+
getDerived().MaybeCollectGarbage();
279280
}
280281
DidCallContinuation = false;
281282
}

heavy/include/heavy/Heap.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,23 @@ class Heap : public llvm::AllocatorBase<Heap<Derived>> {
9292
}
9393

9494
void* Allocate(size_t Size, size_t Alignment) {
95-
size_t WorstCase = Size + Alignment;
96-
size_t BytesUsed = getBytesAllocated();
97-
98-
if (BytesUsed + WorstCase > MaxHint) {
99-
getDerived().CollectGarbage();
100-
}
101-
102-
// Allocate on the possibly new heap.
10395
return TrashHeap.Allocate(Size, Alignment);
10496
}
10597

10698
void Deallocate(void const*, size_t, size_t) {
10799
// Do nothing.
108100
}
101+
102+
void MaybeCollectGarbage() {
103+
size_t BytesUsed = getBytesAllocated();
104+
105+
if (BytesUsed > MaxHint)
106+
getDerived().CollectGarbage();
107+
}
108+
109+
void ReplaceHeap(AllocatorTy&& Alloc) {
110+
TrashHeap = std::move(Alloc);
111+
}
109112
};
110113

111114
class IdTable {

heavy/include/heavy/Value.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,8 @@ class ForwardRef : public ValueBase {
15811581
Value Val;
15821582

15831583
ForwardRef(Value V)
1584-
: ValueBase(ValueKind::ForwardRef)
1584+
: ValueBase(ValueKind::ForwardRef),
1585+
Val(V)
15851586
{ }
15861587

15871588
static bool classof(Value V) {

heavy/lib/Context.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ void Context::verifyModule() {
322322
namespace {
323323
class Writer : public ValueVisitor<Writer> {
324324
friend class ValueVisitor<Writer>;
325+
using Base = ValueVisitor<Writer>;
325326
unsigned IndentationLevel = 0;
326327
llvm::raw_ostream &OS;
327328

@@ -339,6 +340,13 @@ class Writer : public ValueVisitor<Writer> {
339340
: OS(OS)
340341
{ }
341342

343+
void Visit(Value V) {
344+
if (!V)
345+
OS << "#<NULLPTR>";
346+
else
347+
Base::Visit(V);
348+
}
349+
342350
private:
343351
void PrintFormattedWhitespace() {
344352
// We could handle indentation and new lines
@@ -367,6 +375,12 @@ class Writer : public ValueVisitor<Writer> {
367375
OS << ">";
368376
}
369377

378+
void VisitForwardRef(ForwardRef* F) {
379+
OS << "#<ForwardRef {";
380+
Visit(F->Val);
381+
OS << "}>";
382+
}
383+
370384
void VisitBool(Bool V) {
371385
if (V)
372386
OS << "#t";

heavy/lib/Heap.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
7070
heavy::EnvEntry VisitEnvEntry(heavy::EnvEntry const& EnvEntry) {
7171
heavy::Value Value = Visit(EnvEntry.Value);
7272
heavy::String* MangledName
73-
= VisitString(EnvEntry.MangledName);
73+
= cast<String>(Visit(EnvEntry.MangledName));
7474
return heavy::EnvEntry{Value, MangledName};
7575
}
7676

@@ -96,7 +96,7 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
9696

9797
// ByteVector
9898
heavy::Value VisitByteVector(heavy::ByteVector* ByteVector) {
99-
heavy::String* NewString = VisitString(ByteVector->getString());
99+
heavy::String* NewString = cast<String>(Visit(ByteVector->getString()));
100100
return new (NewHeap) heavy::ByteVector(NewString);
101101
}
102102

@@ -146,7 +146,6 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
146146
// ForwardRef
147147
heavy::Value VisitForwardRef(heavy::ForwardRef* ForwardRef) {
148148
// This is a wrapper for an already copied value.
149-
// Unwrap it on the new heap.
150149
return ForwardRef->Val;
151150
}
152151

@@ -246,6 +245,10 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
246245

247246
template <typename ...Args>
248247
heavy::Value Visit(heavy::Value OldVal) {
248+
// Handle the ValueSumTypes that alias ValueBase
249+
if (isa<Undefined>(OldVal))
250+
return VisitUndefined(cast<Undefined>(OldVal));
251+
249252
void* ValueBase = OldVal.get<ValueSumType::ValueBase>();
250253
if (ValueBase == nullptr)
251254
return OldVal;
@@ -260,6 +263,7 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
260263

261264
heavy::Value NewVal = Base::Visit(OldVal);
262265
// Overwrite the OldVal with a ForwardRef.
266+
assert(NewVal && "expecting valid value");
263267
new (ValueBase) ForwardRef(NewVal);
264268

265269
return NewVal;
@@ -283,10 +287,11 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
283287

284288
// The module itself is not garbage collected,
285289
// but it has contained objects that are.
286-
Module->Cleanup = cast_or_null<Lambda>(Visit(Module->Cleanup));
290+
if (Module->Cleanup)
291+
Module->Cleanup = cast_or_null<Lambda>(Visit(Module->Cleanup));
287292
for (auto& DensePair : Module->Map) {
288-
DensePair.getFirst() = VisitString(DensePair.getFirst());
289-
DensePair.getSecond() = VisitString(DensePair.getSecond());
293+
DensePair.getFirst() = cast<String>(Visit(DensePair.getFirst()));
294+
DensePair.getSecond() = cast<String>(Visit(DensePair.getSecond()));
290295
}
291296
return Module;
292297
}
@@ -303,14 +308,14 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
303308
if (OpGen->TopLevelHandler)
304309
OpGen->TopLevelHandler = Visit(OpGen->TopLevelHandler);
305310
if (OpGen->LibraryEnvProc)
306-
OpGen->LibraryEnvProc = VisitBinding(OpGen->LibraryEnvProc);
311+
OpGen->LibraryEnvProc = cast<Binding>(Visit(OpGen->LibraryEnvProc));
307312
// Note that the BindingTable has no unique ownership of the Bindings
308313
// as they are all pushed to the Environment.
309314
}
310315

311316
for (auto& DensePair : Env->EnvMap) {
312-
DensePair.getFirst() = VisitString(DensePair.getFirst());
313-
DensePair.getSecond() = VisitString(DensePair.getSecond());
317+
DensePair.getFirst() = cast<String>(Visit(DensePair.getFirst()));
318+
DensePair.getSecond() = cast<String>(Visit(DensePair.getSecond()));
314319
}
315320

316321
VisitedSpecials.push_back(Env);
@@ -319,6 +324,14 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
319324
};
320325

321326
void Context::CollectGarbage() {
327+
// FIXME The continuation stack and escape procedures
328+
// are saved as opaque string objects.
329+
// Wrap these in some kind of "ContStack" value
330+
// and make a visitor for their captures.
331+
llvm::errs() << "NOT COLLECTING GARBAGE: " << getBytesAllocated() << "\n";
332+
MaxHint *= 2;
333+
return;
334+
322335
// Create NewHeap
323336
Heap::AllocatorTy NewHeap;
324337
CopyCollector GC(NewHeap, this->TrashHeap);
@@ -352,10 +365,16 @@ void Context::CollectGarbage() {
352365
ValAttr = LiteralOp.getInputAttr();
353366
else if (auto MatchOp = dyn_cast<heavy::MatchOp>(Op))
354367
ValAttr = MatchOp.getValAttr();
355-
GC.VisitRootNode(ValAttr.getCachedValue());
368+
369+
// Just clear the value and the attr will rebuild it
370+
// from its expression when and if it is requested.
371+
if (ValAttr)
372+
ValAttr.getCachedValue() = Value();
356373
};
357374
ModuleOp->walk(WalkerFn);
375+
358376
}
377+
ReplaceHeap(std::move(NewHeap));
359378
}
360379

361380
String* IdTable::CreateIdTableEntry(llvm::StringRef Str) {

0 commit comments

Comments
 (0)