GC.calloc(), then what?
safety0ff via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Jun 27 01:49:07 PDT 2014
On Friday, 27 June 2014 at 08:17:07 UTC, Ali Çehreli wrote:
> Thank you for your responses. I am partly enlightened. :p
I know you're a knowledgeable person in the D community, I may
have stated many things you already knew, but I tried to answer
the questions as-is.
> On 06/27/2014 12:34 AM, safety0ff wrote:
>
> > Add range is usually for cases when you use
> stdc.stdlib.malloc/calloc
> > and place pointers to GC managed memory within that memory.
> This allows
> > the GC to scan that memory for pointers during collection,
> otherwise it
> > may reclaim memory which is pointed to my malloc'd memory.
>
> One part that I don't understand in the documentation is "if p
> points into a GC-managed memory block, addRange does not mark
> this block as live".
>
> [SNIP]
>
> See, that's confusing: What does that mean? I still hold the
> memory block anyway; what does the GC achieve by scanning my
> memory if it's not going to follow references anyway?
The GC _will_ follow references (i.e. scan deeply,) that's the
whole point of addRange.
What that documentation is saying is that:
If you pass a range R through addRange, and R lies in the GC
heap, then once there are no pointers (roots) to R, the GC will
collect it anyway regardless that you called addRange on it.
In other words, prefer using addRoot for GC memory and addRange
for non-GC memory.
> >> 4) Are the random bit patterns in a malloc()'ed memory
> always a
> >> concern for false pointers? Does that become a concern after
> calling
> >> addRoot() or addRange()?
> >
> > If by malloc you're talking about stdc.stdlib.malloc then:
> > It only becomes a concern after you call addRange,
>
> But addRange doesn't seem to make sense for stdlib.malloc'ed
> memory, right? The reason is, that memory is not managed by the
> GC so there is no danger of losing that memory due to a
> collection anyway. It will go away only when I call stdlib.free.
addRange almost exclusively makes sense with stdlib.malloc'ed
memory.
As you've stated: If you pass it GC memory it does not mark the
block as live.
I believe the answer above clears things up: the GC does scan the
range, and scanning is always "deep" (i.e. when it finds pointers
to unmarked GC memory, it marks them.)
Conversely, addRoot exclusively makes sense with GC memory.
> > If you're talking about GC.malloc():
> > Currently the GC zeros the memory unless you allocate NO_SCAN
> memory, so
> > it only differs in the NO_SCAN case.
>
> So, the GC's default behavior is to scan the memory,
> necessitating clearing the contents? That seems to make
> GC.malloc() behave the same as GC.calloc() by default, doesn't
> it?
I don't believe it's necessary to clear it, it's just a measure
against false pointers (AFAIK.)
> So, is this guideline right?
>
> "GC.malloc() makes sense only with NO_SCAN."
I wouldn't make a guideline like that, just say that: if you want
the memory to be guaranteed to be zero'd use GC.calloc.
However, due to GC internals (for preventing false pointers,)
GC.malloc'd memory will often be zero'd anyway.
> >> If so, why would anyone ever malloc() instead of always
> calloc()'ing?
> >
> > To save on redundant zero'ing.
>
> And again, redundant zero'ing is saved only when used with
> NO_SCAN.
Yup.
> I think I finally understand the main difference between
> stdlib.malloc and GC.malloc: The latter gets collected by the
> GC.
Yup.
> Another question: Do GC.malloc'ed and GC.calloc'ed memory
> scanned deep?
Yes, only NO_SCAN memory doesn't get scanned, everything else
does.
More information about the Digitalmars-d-learn
mailing list