Skip to content

Commit 385d1d0

Browse files
committed
compiler,runtime: implement a portable conservative GC
1 parent 00e91ec commit 385d1d0

File tree

12 files changed

+528
-17
lines changed

12 files changed

+528
-17
lines changed

compiler/compiler.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,10 @@ func (c *Compiler) TargetData() llvm.TargetData {
167167

168168
// selectGC picks an appropriate GC strategy if none was provided.
169169
func (c *Compiler) selectGC() string {
170-
gc := c.GC
171-
if gc == "" {
172-
gc = "leaking"
170+
if c.GC != "" {
171+
return c.GC
173172
}
174-
return gc
173+
return "conservative"
175174
}
176175

177176
// Compile the given package path or .go file path. Return an error when this
@@ -362,6 +361,15 @@ func (c *Compiler) Compile(mainPath string) []error {
362361
// See emitNilCheck in asserts.go.
363362
c.mod.NamedFunction("runtime.isnil").AddAttributeAtIndex(1, nocapture)
364363

364+
// This function is necessary for tracking pointers on the stack in a
365+
// portable way (see gc.go). Indicate to the optimizer that the only thing
366+
// we'll do is read the pointer.
367+
trackPointer := c.mod.NamedFunction("runtime.trackPointer")
368+
if !trackPointer.IsNil() {
369+
trackPointer.AddAttributeAtIndex(1, nocapture)
370+
trackPointer.AddAttributeAtIndex(1, readonly)
371+
}
372+
365373
// Memory copy operations do not capture pointers, even though some weird
366374
// pointer arithmetic is happening in the Go implementation.
367375
for _, fnName := range []string{"runtime.memcpy", "runtime.memmove"} {
@@ -1009,6 +1017,9 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) {
10091017
frame.locals[instr] = llvm.Undef(c.getLLVMType(instr.Type()))
10101018
} else {
10111019
frame.locals[instr] = value
1020+
if len(*instr.Referrers()) != 0 && c.needsStackObjects() {
1021+
c.trackExpr(frame, instr, value)
1022+
}
10121023
}
10131024
case *ssa.DebugRef:
10141025
// ignore

compiler/defer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ func (c *Compiler) emitDefer(frame *Frame, instr *ssa.Defer) {
130130
// Put this struct in an alloca.
131131
alloca := c.builder.CreateAlloca(deferFrameType, "defer.alloca")
132132
c.builder.CreateStore(deferFrame, alloca)
133+
if c.needsStackObjects() {
134+
c.trackPointer(alloca)
135+
}
133136

134137
// Push it on top of the linked list by replacing deferPtr.
135138
allocaCast := c.builder.CreateBitCast(alloca, next.Type(), "defer.alloca.cast")

0 commit comments

Comments
 (0)