-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
The standard library sometimes uses GC.malloc
and GC.malloc_atomic
to allocate raw bytes, when Slice
isn't appropriate. Some examples are:
Line 35 in 0e82118
data = GC.malloc(data_size).as(self) |
Line 18 in 0e82118
@buffer = GC.malloc_atomic(capacity.to_u32).as(UInt8*) |
At other times it uses Pointer.malloc
:
crystal/src/string/formatter.cr
Line 435 in 0e82118
@temp_buf = Pointer(UInt8).malloc(len) |
Line 37 in 0e82118
@emitter = Pointer(Void).malloc(LibYAML::EMITTER_SIZE).as(LibYAML::Emitter*) |
The two may correspond to different allocators; an explanation is available in #12391. However, I believe this distinction is not that important because the two "different" allocators in this case are simply separate instances of the GC allocator. We should settle with one of those alternatives as a matter of consistency.
Personally I am in favor of the Pointer
form, because IMO GC
is an implementation detail and should be hidden away.
Note that Pointer(UInt8)#malloc
is guaranteed to be atomic and Pointer(Void)#malloc
is guaranteed to be non-atomic.