-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use GC.malloc_atomic
with GC.realloc
, not Pointer#realloc
#12391
Use GC.malloc_atomic
with GC.realloc
, not Pointer#realloc
#12391
Conversation
I'm wondering if we should also take steps to reduce the error probability through the API. An idea might be to make |
There's another one in I think the main issue is that there's no We could even hide |
struct Pointer(T)
def self.malloc_atomic(size : UInt64)
Pointer(UInt8).malloc(size * sizeof(T)).as(T*)
end
end |
It would be odd if Lines 33 to 38 in f160040
This raises another question actually. If the interpreter calls |
crystal/src/compiler/crystal/codegen/types.cr Lines 48 to 61 in f160040
So it's definitely fine as it's safe. But it might miss some performance possibilities. |
This PR ensures that pointers allocated using
GC.malloc
andGC.malloc_atomic
are only reallocated usingGC.realloc
. This is necessary for the interpreter to run on Windows properly, and may also be relevant on other systems if eventually the interpreter's GC is distinct from the compiler's own GC.Pointer.malloc
andPointer#realloc
are defined as primitives. For compiled code, these internally call the top-level funs__crystal_malloc64
,__crystal_malloc_atomic64
, and__crystal_realloc64
, which in turn forward to the class methods onGC
, soPointer
andGC
's methods happen to be exactly the same:crystal/src/gc.cr
Lines 16 to 47 in a5054ce
For interpreted code, the same primitives call
Pointer.malloc
andPointer#realloc
from the compiler itself:crystal/src/compiler/crystal/interpreter/instructions.cr
Lines 1004 to 1015 in a5054ce
Currently, the compiler on Windows is statically linked, whereas
LibGC
inside interpreted code would be dynamically loaded (using #11573 and #12140); there would be two copies of the garbage collector which do not conflict like on Unix-like systems. Consequently, allocating memory from one allocator and then reallocating it in another is undefined behavior.All instances of
GC.malloc
in the repository are already paired toGC.realloc
. Note also that adding@[Primitive]
toGC
's class methods doesn't work because these have different signatures than the methods inPointer
.