@@ -9,6 +9,7 @@ module Crystal
9
9
MAIN_NAME = " __crystal_main"
10
10
RAISE_NAME = " __crystal_raise"
11
11
MALLOC_NAME = " __crystal_malloc"
12
+ MALLOC_ATOMIC_NAME = " __crystal_malloc_atomic"
12
13
REALLOC_NAME = " __crystal_realloc"
13
14
PERSONALITY_NAME = " __crystal_personality"
14
15
GET_EXCEPTION_NAME = " __crystal_get_exception"
@@ -129,6 +130,7 @@ module Crystal
129
130
@empty_md_list : LLVM ::Value
130
131
@rescue_block : LLVM ::BasicBlock ?
131
132
@malloc_fun : LLVM ::Function ?
133
+ @malloc_atomic_fun : LLVM ::Function ?
132
134
@sret_value : LLVM ::Value ?
133
135
@cant_pass_closure_to_c_exception_call : Call ?
134
136
@realloc_fun : LLVM ::Function ?
@@ -1746,7 +1748,12 @@ module Crystal
1746
1748
if type .passed_by_value?
1747
1749
@last = alloca struct_type
1748
1750
else
1749
- @last = malloc struct_type
1751
+ if type .is_a?(InstanceVarContainer ) && ! type .struct? &&
1752
+ type .all_instance_vars.each_value.any? & .type.has_inner_pointers?
1753
+ @last = malloc struct_type
1754
+ else
1755
+ @last = malloc_atomic struct_type
1756
+ end
1750
1757
end
1751
1758
memset @last , int8(0 ), struct_type.size
1752
1759
type_ptr = @last
@@ -1806,9 +1813,15 @@ module Crystal
1806
1813
end
1807
1814
1808
1815
def malloc (type )
1809
- @malloc_fun ||= @main_mod .functions[MALLOC_NAME ]?
1810
- if malloc_fun = @malloc_fun
1811
- malloc_fun = check_main_fun MALLOC_NAME , malloc_fun
1816
+ generic_malloc(type ) { malloc_fun }
1817
+ end
1818
+
1819
+ def malloc_atomic (type )
1820
+ generic_malloc(type ) { malloc_atomic_fun }
1821
+ end
1822
+
1823
+ def generic_malloc (type )
1824
+ if malloc_fun = yield
1812
1825
size = trunc(type .size, llvm_context.int32)
1813
1826
pointer = call malloc_fun, size
1814
1827
bit_cast pointer, type .pointer
@@ -1818,12 +1831,18 @@ module Crystal
1818
1831
end
1819
1832
1820
1833
def array_malloc (type , count)
1821
- @malloc_fun ||= @main_mod .functions[MALLOC_NAME ]?
1834
+ generic_array_malloc(type , count) { malloc_fun }
1835
+ end
1836
+
1837
+ def array_malloc_atomic (type , count)
1838
+ generic_array_malloc(type , count) { malloc_atomic_fun }
1839
+ end
1840
+
1841
+ def generic_array_malloc (type , count)
1822
1842
size = trunc(type .size, llvm_context.int32)
1823
1843
count = trunc(count, llvm_context.int32)
1824
1844
size = builder.mul size, count
1825
- if malloc_fun = @malloc_fun
1826
- malloc_fun = check_main_fun MALLOC_NAME , malloc_fun
1845
+ if malloc_fun = yield
1827
1846
pointer = call malloc_fun, size
1828
1847
memset pointer, int8(0 ), size
1829
1848
bit_cast pointer, type .pointer
@@ -1835,6 +1854,24 @@ module Crystal
1835
1854
end
1836
1855
end
1837
1856
1857
+ def malloc_fun
1858
+ @malloc_fun ||= @main_mod .functions[MALLOC_NAME ]?
1859
+ if malloc_fun = @malloc_fun
1860
+ check_main_fun MALLOC_NAME , malloc_fun
1861
+ else
1862
+ nil
1863
+ end
1864
+ end
1865
+
1866
+ def malloc_atomic_fun
1867
+ @malloc_atomic_fun ||= @main_mod .functions[MALLOC_ATOMIC_NAME ]?
1868
+ if malloc_fun = @malloc_atomic_fun
1869
+ check_main_fun MALLOC_ATOMIC_NAME , malloc_fun
1870
+ else
1871
+ nil
1872
+ end
1873
+ end
1874
+
1838
1875
def memset (pointer, value, size)
1839
1876
pointer = cast_to_void_pointer pointer
1840
1877
call @program .memset(@llvm_mod , llvm_context), [pointer, value, trunc(size, llvm_context.int32), int32(4 ), int1(0 )]