Jean Abou Samra <j...@abou-samra.fr> writes: > Hi, > > Once again, the more I try to understand how GC works at > the C++ level, the more I get lost. Of course, not being > too good at low-level programming doesn't help. Take this > random exported function: > > > LY_DEFINE (ly_duration_less_p, "ly:duration<?", > 2, 0, 0, (SCM p1, SCM p2), > R"( > Is @var{p1} shorter than @var{p2}? > )") > { > auto *const a = LY_ASSERT_SMOB (Duration, p1, 1); > auto *const b = LY_ASSERT_SMOB (Duration, p2, 2); > > if (Duration::compare (*a, *b) < 0) > return SCM_BOOL_T; > else > return SCM_BOOL_F; > } > > > > This is my understanding: > > Duration is a Simple_smob type. > > That means a Duration object can be allocated either on the stack > or on the BDWGC heap. > > Since p1 and p2 are SCM, they are BDWGC-heap-allocated in this case.
Nope. They are on the stack. They may either be immediate SCM values with nothing on the heap (like SCM_EOL or small integers), or they may point to a heap cell. In that case, scanning the stack during GC will pick up the SCM values and mark the associated cells in the heap. > The unsmobbed a and b are thus pointers to data on the BDWGC heap. Correct. > > Since they are pointers to the part of the SCM that stores the C++ > object, and not to the start of the SCM value, they won't cause the > SCM to be marked by their mere existence on the stack. Correct. > p1 and p2 are not used after the LY_ASSERT_SMOB calls. The compiler > could drop them before the end of the function. Unlikely since that would mess up the stack frame, but let's assume so. > In that case, nothing protects p1 and p2 between the two LY_ASSERT_SMOB > lines and the Duration::compare. If the ly:duration<? call is a tail > call, Guile itself might not hold references to the duration objects. > If that happens, a crash would ensue. Why? There is no allocation happening anywhere, so there is no reason to do garbage collection. At least I think that is the rationale also covering a lot of Guile-internal code. > This pattern looks somewhat frequent, so I hope I am wrong. If so, > where is my mistake? Hopefully above. -- David Kastrup