0

I am making an interpreter in C, and I'm having a problem with my reference counting.

Each value (which is the interpreter's representation... of a value) is allocated with refcount 0. Once it gets added to the stack, it increments the refcount.

The only way to get a value off the stack is to pop it off it, but that leads to problems. My popping function returns the value that is popped, but if the refcount is 0 and I destroy the value I can no longer return it.

I get that I should probably put the refcount check somewhere else, but that just seems ugly as there are a lot of places that use the popping function.

What can I do to workaround this issue? Is implementing a real GC algorithm necessary in this case?

autistic
  • 1
  • 3
  • 35
  • 80
  • 1
    Sharing your research helps everyone. Tell us what you've tried and why it didn’t meet your needs. This demonstrates that you’ve taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer! Also see [how to ask](//stackoverflow.com/questions/how-to-ask) – Eregrith Jun 29 '15 at 09:55
  • I'm curious as to which problem you intend to solve. Any mimicry of garbage collection using reference counting without strong- and weak- referencing, rather than graph traversal is thoroughly broken. How would you prevent a cyclical structure such as a circular list, a patricia trie or various common graphs from leaking? You're better off implementing your GC algorithm to collect leaks from `malloc`s that have missing `free`s, where a stack-based implementation would be clumsy and performance-bogged; use a heap. – autistic Jun 29 '15 at 10:05
  • My language is stack-based. That means every value is on the stack anyway. I was reading about the mark-and-sweep algorithm. This would involve putting all `value`s on a "global" list and then destroying them when they are no references to it anymore, right? –  Jun 29 '15 at 10:10
  • I've misread your question (and deleted my answer)... and a new problem has arisen: **There's no reason to mention C here**. That tag ([c]) is borderline meta, certainly irrelevant, obnoxious for some people and should probably be removed. That aside, if you create a circular list and lose reference to it, since each node references another node in a circular fashion the refcount for each node will be 1... there'll still be a leak. – autistic Jun 29 '15 at 10:34

3 Answers3

1

I use my own data base system which also uses a kind of refcount.

When an object is stored into a data base, then its refcount is incremented. When I get an object from a data base, its refcount remains unchanged. It is decremented only if the object is deleted by any way (usually the deletion of a data base containing it or its replacement by another object in a data base containing it). The object is really destroyed only when its refcount is equal to zero AND its deletion is required.

Francois Jacq
  • 1,244
  • 10
  • 18
  • out of interest, what was the motivation to use your own database system – amdixon Jun 29 '15 at 10:06
  • Thanks for the response. So I should basically only destroy `value`s in the relevant cases? –  Jun 29 '15 at 10:12
  • @amdixon : an old reason (written in 1987 in Fortran :) ) and still working today, and still the fastest data base system I know... – Francois Jacq Jun 29 '15 at 10:37
  • @FrancoisJacq github link ? – amdixon Jun 29 '15 at 10:38
  • 1
    @amdixon no link sorry. It is not a free software. It belongs to IRSN (French institute of radioprotection and nuclear safety) and is used by severe accident simulation codes like ASTEC. – Francois Jacq Jun 29 '15 at 11:06
0

whenever you create object or value in your case, you should set the refcount to 1. On pushing to the stack, increment it. On poping, decrement. On pop each operation decrement and check th refcount, destroy value if refcount is zero. Which function destoy-value already be doing so you just need to call that function on pop.

Pointer
  • 627
  • 2
  • 8
  • 19
  • This wouldn't work as I'm not popping a value two times off the stack, but only when needed. This would leave all values existing with a refcount of 1. –  Jun 29 '15 at 10:28
  • so as per you design when does the value should get freed? – Pointer Jun 29 '15 at 10:32
  • 1
    You problem is that popping and deleting (or decrementing) are executed together. You could (should ?) add another action : copying from the stack (like getting an object for me) without modifying the stack itself. Popping becomes a final action to cleanup the stack, to decrement the object and to delete it if its count is equal to zero. – Francois Jacq Jun 29 '15 at 10:45
0

As a general rule, increment the count when creating a reference and decrement when deleting a reference. But there's also a third type of transaction (or an optimized composition of the two) where there's just a transfer and you don't change the count at all.

This is the case if you pop the value from the stack and them proceed to use the value (in a local variable, maybe). First the object was on the stack, and now its in a variable; but there's still only one object. The reference count doesn't change until you're done with it and ready to discard the reference.

luser droog
  • 18,988
  • 3
  • 53
  • 105