
Baby's First Garbage Collector - daw___
http://journal.stuffwithstuff.com/2013/12/08/babys-first-garbage-collector/
======
recuter
So every once in a while I come across old timey C optimizations in the spirit
of Duff's device or bit twiddling to swap variables, 'etc 'etc...

While they have a certain kind of charm to them they seem to be almost
universally bested by increasingly mature compilers and complex (or
virtualized) hardware.

So I'm kind of coming to the conclusion that clever pointer arithmetic games
and even manual malloc/free are _increasingly_ futile unless you're targeting
embedded devices. If a young language like Go gets you at least in the same
ballpark as C with a relatively immature GC and even toy implementations like
the OP take you rather far these days... when is coding without a garbage
collector even really defensible anymore?

I'm not trolling. I think pointer arithmetic is neat and the aforementioned
"optimizations" are magical and possibly my generation has missed out on
something wonderful. Seems it just isn't often practical to do that sort of
thing anymore.

Edit: I'd like to stress that I wasn't talking in absolutes, and asking rather
than telling. I'm not sure how to phrase my post better, made some edits
nonetheless.

~~~
ANTSANTS
Let me link to a (very longwinded, sorry) post I made a while back explaining
how a particular type of memory pool allocator works:
[https://news.ycombinator.com/item?id=6176091](https://news.ycombinator.com/item?id=6176091)

tl;dr if you think "manual memory management" means "malloc thing, use thing,
free thing" you're kind of missing the point.

Also, tricks like Duff's device and XOR swap have long since become
pessimizations, not optimizations, on desktop and mobile-class hardware.
Duff's device, for instance, wastes instruction cache when any decent CPU's
branch predictor can eliminate most of a simple loop's overhead anyway. With
the exception of manually vectorizing tight loops to take advantage of SIMD
hardware (which is more of assembly's domain anyway), I think the "optimized
C" of today looks pretty straightforward and unobfuscated, just with more
attention paid to the details that higher level languages mostly gloss over
for you.

> ...and possibly my generation has missed out on something wonderful...

I'm pretty certain I'm younger than you, I just grew up really wanting to make
games and know how computers work. Maybe _you_ don't need or even want to
think about this kind of stuff, but it's not like the problems just magically
disappeared one day. Or, more bluntly, "if C and C++ are so dumb then why
isn't your browser written in Python?"

~~~
asveikau
I think the HN crowd honestly believes that the only reason the next browser
hasn't been written in a GC language is momentum and time. That the next one
will very obviously be written in Ruby or Python. I've seen discussions here
to that effect.

I find it hard to read HN discussions about C. One faction is totally amazed
by the C equivalent of being able to tie their shoes. The other faction
believes shoelaces are obsolete and everyone should wear velcro.

This "my generation has missed out" thing is really odd... If you are honestly
interested in it, go learn how it works! The commenter you're replying to
should quit making excuses.

~~~
recuter
Sorry for the poor phrasing, maybe you've misunderstood: I've mentioned that
I'm interested, am fond of it, and have learned how it works. Not sure what
excuses you're talking about.

OTOH, for when I'm not writing a browser, a HFTs, or the next-gen video game
engine, the trade offs are increasingly not worth it. On top of that we don't
have Amigas to have fun with anymore and stay close to the hardware on (I
guess maybe Raspberry Pi qualifies as some sort of substitute) and so that
particular brand of hacker, a small group to begin with, keeps on shrinking.
That's what I meant by missing out.

------
phamilton
Not having studied the topic in depth, my first thought is whether true
pointers and a garbage collector can coexist (without artificially removing
parts of the language). The big condition for knowing if something is still in
use is whether any references exist to it. But in a language like C , you
could cast a pointer to something else (like a void pointer for some quasi
generic linked list), store it somewhere, and then cast it back later after
garbage collection has run. That seems like a problematic situation. So is
completely giving up on pointers (or just never doing tricky things like
casting or pointer arithmetic) a requirement to having a garbage collector?

~~~
city41
I don't know of any language that has pointers and a GC. Are there any? C#
lets you use pointers but only if you tell the GC to not move your object and
promise to behave.

~~~
wsc981
> "I don't know of any language that has pointers and a GC. Are there any?"

Objective-C used to have a garbage collector, though (at least with regards to
iOS) Apple removed this capability with the introduction or ARC. On the
following URL is some discussion on the Objective-C garbage collector:
[http://cocoasamurai.blogspot.nl/2010/12/objective-c-
memory-m...](http://cocoasamurai.blogspot.nl/2010/12/objective-c-memory-
management-garbage.html)

~~~
masklinn
iOS never got the GC, only the desktop version got it, and afaik it was
deprecated rather than removed entirely.

~~~
pornel
It's been removed entirely in Xcode 5.1.

------
dysoco
Now THIS is the kind of articles I want to see in HN.

Saved for later reading, seems very interesting and well explained.

~~~
kerkeslager
Did you see this a few weeks ago?
[http://patshaughnessy.net/2013/10/24/visualizing-garbage-
col...](http://patshaughnessy.net/2013/10/24/visualizing-garbage-collection-
in-ruby-and-python/)

~~~
dysoco
Nope, thanks for the link!

------
robertk
I don't understand. When sweep frees an object, it invalidates the "next"
object of the previous object in the linked list, breaking the traversal next
time a gc() is called. Doesn't the linked list have to be patched? (e.g., keep
track of "prev_object" and set its next to unreached->next before freeing
unreached)

~~~
bla2
I think `*object = unreached->next;` does that, since it's using a pointer to
a pointer.

~~~
munificent
That's correct. It patches the "next" pointer of the previous object to point
_past_ the freed object.

It's a pointer to a pointer to handle the case where you're freeing the first
object in the list. In that case, it's "firstObject" that needs to be
modified, not some Object's "next" pointer.

Using a pointer to a pointer (while admittedly harder to read at first) lets
you handle both of those cases with the same code.

~~~
unwind
This technique is talked about in this Stack Overflow answer:
[http://stackoverflow.com/questions/12914917/using-
pointers-t...](http://stackoverflow.com/questions/12914917/using-pointers-to-
remove-item-from-singly-linked-list), which also references this Slashdot
interview ([http://meta.slashdot.org/story/12/10/11/0030249/linus-
torval...](http://meta.slashdot.org/story/12/10/11/0030249/linus-torvalds-
answers-your-questions)) with Linus Torvalds where he gives this as his
"favorite hack".

~~~
munificent
Yup, I got the idea for this from Linus. Before then, I've always done the
uglier "if this is the first node then ..." special case branch instead.

------
mamcx
That was actually very easy to understand!.

Thanks for that. I'm thinking in build a toy language and this make on magic
thing die..

------
signa11
storing the 'mark' bit with the objects themselves is not so good for COW
semantics, but should be _just_ fine for this toy example i think...

------
kimonos
Nice post! It's very precise. I didn't have a hard time understanding it.
Thanks for sharing!

