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
Fix malloc and realloc for 64 bits platforms #4960
Changes from 4 commits
21528ef
2b39e3e
0f2b9a8
5234192
e8f2507
30d1e84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,39 @@ fun __crystal_realloc(ptr : Void*, size : UInt32) : Void* | |
LibGC.realloc(ptr, size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc64(size : UInt64) : Void* | ||
{% if flag?(:bits32) %} | ||
if size > UInt32::MAX | ||
raise ArgumentError.new("Negative size") | ||
end | ||
{% end %} | ||
|
||
LibGC.malloc(size) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since malloc64 is always used for allocation, and LibC / GC malloc use SizeT. The conversion from UInt64 to SizeT happens implicitly when calling a C method? How is the failure handle when request something over SizeT on 32bits arch? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a check and |
||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc_atomic64(size : UInt64) : Void* | ||
{% if flag?(:bits32) %} | ||
if size > UInt32::MAX | ||
raise ArgumentError.new("Negative size") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, right, it should be a different message |
||
end | ||
{% end %} | ||
|
||
LibGC.malloc_atomic(size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_realloc64(ptr : Void*, size : UInt64) : Void* | ||
{% if flag?(:bits32) %} | ||
if size > UInt32::MAX | ||
raise ArgumentError.new("Negative size") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
end | ||
{% end %} | ||
|
||
LibGC.realloc(ptr, size) | ||
end | ||
|
||
module GC | ||
def self.init | ||
LibGC.set_handle_fork(1) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,21 @@ fun __crystal_realloc(ptr : Void*, size : UInt32) : Void* | |
LibC.realloc(ptr, size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc64(size : UInt64) : Void* | ||
LibC.malloc(size) | ||
end | ||
|
||
# :nodoc: | ||
fun __crystal_malloc_atomic64(size : UInt64) : Void* | ||
LibC.malloc(size) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here should be LibGC.malloc_atomic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the null gc, which doesn't do any gc, it just forwards to the libc malloc. |
||
end | ||
|
||
# :nodoc: | ||
fun __crystal_realloc64(ptr : Void*, size : UInt64) : Void* | ||
LibC.realloc(ptr, size) | ||
end | ||
|
||
module GC | ||
def self.init | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,7 +242,7 @@ struct Pointer(T) | |
raise ArgumentError.new("Negative count") if count < 0 | ||
|
||
if self.class == source.class | ||
Intrinsics.memcpy(self.as(Void*), source.as(Void*), (count * sizeof(T)).to_u32, 0_u32, false) | ||
Intrinsics.memcpy(self.as(Void*), source.as(Void*), bytesize(count), 0_u32, false) | ||
else | ||
while (count -= 1) >= 0 | ||
self[count] = source[count] | ||
|
@@ -255,7 +255,7 @@ struct Pointer(T) | |
raise ArgumentError.new("Negative count") if count < 0 | ||
|
||
if self.class == source.class | ||
Intrinsics.memmove(self.as(Void*), source.as(Void*), (count * sizeof(T)).to_u32, 0_u32, false) | ||
Intrinsics.memmove(self.as(Void*), source.as(Void*), bytesize(count), 0_u32, false) | ||
else | ||
if source.address < address | ||
copy_from source, count | ||
|
@@ -495,10 +495,22 @@ struct Pointer(T) | |
# ptr.to_slice(6) # => Slice[0, 0, 0, 13, 14, 15] | ||
# ``` | ||
def clear(count = 1) | ||
Intrinsics.memset(self.as(Void*), 0_u8, (count * sizeof(T)).to_u32, 0_u32, false) | ||
Intrinsics.memset(self.as(Void*), 0_u8, bytesize(count), 0_u32, false) | ||
end | ||
|
||
def clone | ||
self | ||
end | ||
|
||
private def bytesize(count) | ||
{% if flag?(:bits64) %} | ||
count.to_u64 * sizeof(T) | ||
{% else %} | ||
if count > UInt32::MAX | ||
raise ArgumentError.new("Negative count") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One moar copy/pasted exception message to fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
end | ||
|
||
count.to_u32 * sizeof(T) | ||
{% end %} | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this more generally, is the automatic integer size conversion around
lib
a mistake in the language design, because it hides the situations where 64bit integers can be downcoverted to 32bits, and so hides where you should make a check for truncation?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it's a different issue and of much bigger scope: #3103
I don't think we can fix this in this same PR. For now we have to do manual checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, it's far out of scope for this PR.