Skip to content

Commit 9a5deda

Browse files
committed
feat: presice mark
1 parent 481a544 commit 9a5deda

File tree

11 files changed

+156
-156
lines changed

11 files changed

+156
-156
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"cwd": "${workspaceFolder}",
8888
"env": {
8989
// "GC_LOG": "info"
90-
// "PL_IMMIX_HEAP_SIZE": "80000000"
90+
"PL_IMMIX_HEAP_SIZE": "70000000"
9191
}
9292
// "stopOnEntry": true
9393
},

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ members = ["internal_macro", "vm", "pl_linker", "immix", "kagari"]
101101
lto = "fat"
102102
opt-level = 3
103103
debug = "line-tables-only"
104+
overflow-checks = false
105+
debug-assertions = false
104106

105107
[profile.bench]
106108
opt-level = 3

alloc-aarch64.ll

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ define void @gc_thread_init() {
3232
ret void
3333
}
3434

35-
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
35+
declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture, i8, i64, i1) nounwind
3636

3737

3838

@@ -46,9 +46,9 @@ define double @sqrt_64(double %Val) {
4646
; define new DioGC__malloc
4747
define ptr addrspace(1) @DioGC__malloc(i64 %size, i8 %obj_type, i64 %rsp) noinline optnone allockind("alloc") {
4848
entry:
49-
; if size > 128, call slowpath
49+
; if size > 7936, call slowpath
5050
; call void @printi64ln(i64 2222)
51-
%size_gt_128 = icmp ugt i64 %size, 128
51+
%size_gt_128 = icmp ugt i64 %size, 7936
5252
br i1 %size_gt_128, label %call_slowpath, label %check_collector
5353
check_collector:
5454
; Load collector from gc_handle
@@ -63,6 +63,7 @@ call_slowpath:
6363
%innerrsp = tail call ptr asm alignstack "mov $0, sp", "=r"() #0
6464
%rspi = ptrtoint ptr %innerrsp to i64
6565
%slowpath_result = call ptr addrspace(1) @DioGC__malloc_slowpath(i64 %size, i8 %obj_type, i64 %rspi, ptr @gc_handle)
66+
call void @llvm.memset.p1.i64(ptr addrspace(1) %slowpath_result, i8 0, i64 %size, i1 false)
6667
; call void @printi64ln(i64 999)
6768
; %slowpath_result_i = ptrtoint ptr addrspace(1) %slowpath_result to i64
6869
; call void @printi64ln(i64 %slowpath_result_i)
@@ -94,11 +95,12 @@ fastpath_start:
9495

9596

9697

97-
; Calculate alloc size = (size + 7) / 8 * 8
98+
; Calculate alloc size = (size + 7) / 8 * 8 + 8
9899
; LINE_SIZE is 128
99100
%size_plus_7 = add i64 %size, 7
100101
%size_div_8 = lshr i64 %size_plus_7, 3
101-
%alloc_size = shl i64 %size_div_8, 3
102+
%alloc_size_body = shl i64 %size_div_8, 3
103+
%alloc_size = add i64 %alloc_size_body, 8
102104

103105

104106

@@ -107,44 +109,44 @@ fastpath_start:
107109
%hole_end_minus_cursor = sub i64 %hole_end_i64, %cursor_i64
108110
; check if hole_end - cursor >= alloc_size
109111
%hole_end_minus_cursor_ge_alloc_size = icmp sge i64 %hole_end_minus_cursor, %alloc_size
110-
br i1 %hole_end_minus_cursor_ge_alloc_size, label %check_current_line, label %call_slowpath
112+
br i1 %hole_end_minus_cursor_ge_alloc_size, label %fast_path, label %call_slowpath
111113

112-
check_current_line:
113-
; Check if alloc in current line is possible
114-
; let current_line_remains = self.cursor.align_offset(LINE_SIZE);
115-
%current_line_occupied = and i64 %cursor_i64, 127
116-
%current_line_remains = sub i64 128, %current_line_occupied
117-
118-
119-
; call void @printi64ln(i64 %current_line_remains)
120-
; call void @printi64ln(i64 %alloc_size)
121-
; check if alloc_size <= current_line_remains && current_line_remains != 0
122-
%alloc_size_le_remains = icmp ule i64 %alloc_size, %current_line_remains
123-
%current_line_remains_ne_0 = icmp ne i64 %current_line_remains, 0
124-
%alloc_size_le_remains_and_ne_0 = and i1 %alloc_size_le_remains, %current_line_remains_ne_0
125-
br i1 %alloc_size_le_remains_and_ne_0, label %fast_path, label %check_remaining
126-
127-
check_remaining:
128-
; Check if 128 <= hole_end - cursor
129-
%hole_end_minus_cursor_ge_128 = icmp uge i64 %hole_end_minus_cursor, 128
130-
131-
; self.cursor = self.cursor.add(current_line_remains);
132-
%new_cursor_i = add i64 %cursor_i64, %current_line_remains
133-
%new_cursor = inttoptr i64 %new_cursor_i to ptr addrspace(1)
134-
br i1 %hole_end_minus_cursor_ge_128, label %fast_path, label %call_slowpath
135-
136114

137115
fast_path:
138-
; phi get cursor
139-
%cursor_phi = phi ptr addrspace(1) [ %cursor, %check_current_line ], [ %new_cursor, %check_remaining ]
140116

141-
%cursor_phi_i = ptrtoint ptr addrspace(1) %cursor_phi to i64
117+
; set header
118+
; 1. store zero to first bytt of %cursor
119+
store i8 0, ptr addrspace(1) %cursor
120+
; 2. store obj_type to second byte of %cursor
121+
%cursor_obj_type_ptr = getelementptr i8, ptr addrspace(1) %cursor, i64 1
122+
store i8 %obj_type, ptr addrspace(1) %cursor_obj_type_ptr
123+
; 3. store size (trunc to i16) to third and fourth byte of %cursor
124+
%cursor_size_ptr = getelementptr i16, ptr addrspace(1) %cursor, i64 1
125+
%size_cast = trunc i64 %alloc_size to i16
126+
store i16 %size_cast, ptr addrspace(1) %cursor_size_ptr
127+
; 4. store %cursor's lower 32 bits to fifth to eighth byte of %cursor
128+
%cursor_i32 = trunc i64 %cursor_i64 to i32
129+
%cursor_i32_ptr = getelementptr i32, ptr addrspace(1) %cursor, i64 1
130+
store i32 %cursor_i32, ptr addrspace(1) %cursor_i32_ptr
131+
132+
133+
134+
%cursor_phi_i = add i64 %cursor_i64, 8
135+
%cursor_phi = inttoptr i64 %cursor_phi_i to ptr addrspace(1)
142136
; Update cursor
143-
%new_cursor_after_alloc_i = add i64 %cursor_phi_i, %alloc_size
137+
%new_cursor_after_alloc_i = add i64 %cursor_i64, %alloc_size
138+
; checi if new_cursor_after_alloc_i is zero
139+
%new_cursor_after_alloc_is_zero = icmp eq i64 %new_cursor_after_alloc_i, 0
140+
br i1 %new_cursor_after_alloc_is_zero, label %unreachable_path, label %update_cursor
141+
unreachable_path:
142+
unreachable
143+
144+
update_cursor:
144145
%new_cursor_after_alloc = inttoptr i64 %new_cursor_after_alloc_i to ptr addrspace(1)
145146
store ptr addrspace(1) %new_cursor_after_alloc, ptr addrspace(1) %cursor_ptr, align 8
146147
; call void @printi64ln(i64 4)
147148
; call void @printi64ln(i64 %cursor_phi_i)
149+
call void @llvm.memset.p1.i64(ptr addrspace(1) %cursor_phi, i8 0, i64 %size, i1 false)
148150
ret ptr addrspace(1) %cursor_phi
149151
}
150152

alloc-jit-aarch64.ll

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ define double @sqrt_64(double %Val) {
4545
; define new DioGC__malloc
4646
define ptr addrspace(1) @DioGC__malloc(i64 %size, i8 %obj_type, i64 %rsp) noinline optnone allockind("alloc") {
4747
entry:
48-
; if size > 128, call slowpath
48+
; if size > 7936, call slowpath
4949
; call void @printi64ln(i64 2222)
50-
%size_gt_128 = icmp ugt i64 %size, 128
50+
%size_gt_128 = icmp ugt i64 %size, 7936
5151
br i1 %size_gt_128, label %call_slowpath, label %check_collector
5252
check_collector:
5353
; Load collector from gc_handle
@@ -62,6 +62,7 @@ call_slowpath:
6262
%innerrsp = tail call ptr asm alignstack "mov $0, sp", "=r"() #0
6363
%rspi = ptrtoint ptr %innerrsp to i64
6464
%slowpath_result = call ptr addrspace(1) @DioGC__malloc_slowpath_jit(i64 %size, i8 %obj_type, i64 %rspi)
65+
call void @llvm.memset.p1.i64(ptr addrspace(1) %slowpath_result, i8 0, i64 %size, i1 false)
6566
; call void @printi64ln(i64 999)
6667
; %slowpath_result_i = ptrtoint ptr addrspace(1) %slowpath_result to i64
6768
; call void @printi64ln(i64 %slowpath_result_i)
@@ -75,7 +76,7 @@ fastpath_start:
7576

7677
; Get thread_local_allocator (first field)
7778
%block = load ptr addrspace(1), ptr %thread_local_allocator_ptr, align 8
78-
79+
7980
; check block is null
8081
%block_is_null = icmp eq ptr addrspace(1) %block, null
8182
br i1 %block_is_null, label %call_slowpath, label %load_block_fields
@@ -98,11 +99,12 @@ load_block_fields:
9899

99100

100101

101-
; Calculate alloc size = (size + 7) / 8 * 8
102+
; Calculate alloc size = (size + 7) / 8 * 8 + 8
102103
; LINE_SIZE is 128
103104
%size_plus_7 = add i64 %size, 7
104105
%size_div_8 = lshr i64 %size_plus_7, 3
105-
%alloc_size = shl i64 %size_div_8, 3
106+
%alloc_size_body = shl i64 %size_div_8, 3
107+
%alloc_size = add i64 %alloc_size_body, 8
106108

107109

108110

@@ -111,44 +113,44 @@ load_block_fields:
111113
%hole_end_minus_cursor = sub i64 %hole_end_i64, %cursor_i64
112114
; check if hole_end - cursor >= alloc_size
113115
%hole_end_minus_cursor_ge_alloc_size = icmp sge i64 %hole_end_minus_cursor, %alloc_size
114-
br i1 %hole_end_minus_cursor_ge_alloc_size, label %check_current_line, label %call_slowpath
115-
116-
check_current_line:
117-
; Check if alloc in current line is possible
118-
; let current_line_remains = self.cursor.align_offset(LINE_SIZE);
119-
%current_line_occupied = and i64 %cursor_i64, 127
120-
%current_line_remains = sub i64 128, %current_line_occupied
121-
116+
br i1 %hole_end_minus_cursor_ge_alloc_size, label %fast_path, label %call_slowpath
122117

123-
; call void @printi64ln(i64 %current_line_remains)
124-
; call void @printi64ln(i64 %alloc_size)
125-
; check if alloc_size <= current_line_remains && current_line_remains != 0
126-
%alloc_size_le_remains = icmp ule i64 %alloc_size, %current_line_remains
127-
%current_line_remains_ne_0 = icmp ne i64 %current_line_remains, 0
128-
%alloc_size_le_remains_and_ne_0 = and i1 %alloc_size_le_remains, %current_line_remains_ne_0
129-
br i1 %alloc_size_le_remains_and_ne_0, label %fast_path, label %check_remaining
130-
131-
check_remaining:
132-
; Check if 128 <= hole_end - cursor
133-
%hole_end_minus_cursor_ge_128 = icmp uge i64 %hole_end_minus_cursor, 128
134-
135-
; self.cursor = self.cursor.add(current_line_remains);
136-
%new_cursor_i = add i64 %cursor_i64, %current_line_remains
137-
%new_cursor = inttoptr i64 %new_cursor_i to ptr addrspace(1)
138-
br i1 %hole_end_minus_cursor_ge_128, label %fast_path, label %call_slowpath
139-
140118

141119
fast_path:
142-
; phi get cursor
143-
%cursor_phi = phi ptr addrspace(1) [ %cursor, %check_current_line ], [ %new_cursor, %check_remaining ]
144120

145-
%cursor_phi_i = ptrtoint ptr addrspace(1) %cursor_phi to i64
121+
; set header
122+
; 1. store zero to first bytt of %cursor
123+
store i8 0, ptr addrspace(1) %cursor
124+
; 2. store obj_type to second byte of %cursor
125+
%cursor_obj_type_ptr = getelementptr i8, ptr addrspace(1) %cursor, i64 1
126+
store i8 %obj_type, ptr addrspace(1) %cursor_obj_type_ptr
127+
; 3. store size (trunc to i16) to third and fourth byte of %cursor
128+
%cursor_size_ptr = getelementptr i16, ptr addrspace(1) %cursor, i64 1
129+
%size_cast = trunc i64 %alloc_size to i16
130+
store i16 %size_cast, ptr addrspace(1) %cursor_size_ptr
131+
; 4. store %cursor's lower 32 bits to fifth to eighth byte of %cursor
132+
%cursor_i32 = trunc i64 %cursor_i64 to i32
133+
%cursor_i32_ptr = getelementptr i32, ptr addrspace(1) %cursor, i64 1
134+
store i32 %cursor_i32, ptr addrspace(1) %cursor_i32_ptr
135+
136+
137+
138+
%cursor_phi_i = add i64 %cursor_i64, 8
139+
%cursor_phi = inttoptr i64 %cursor_phi_i to ptr addrspace(1)
146140
; Update cursor
147-
%new_cursor_after_alloc_i = add i64 %cursor_phi_i, %alloc_size
141+
%new_cursor_after_alloc_i = add i64 %cursor_i64, %alloc_size
142+
; checi if new_cursor_after_alloc_i is zero
143+
%new_cursor_after_alloc_is_zero = icmp eq i64 %new_cursor_after_alloc_i, 0
144+
br i1 %new_cursor_after_alloc_is_zero, label %unreachable_path, label %update_cursor
145+
unreachable_path:
146+
unreachable
147+
148+
update_cursor:
148149
%new_cursor_after_alloc = inttoptr i64 %new_cursor_after_alloc_i to ptr addrspace(1)
149150
store ptr addrspace(1) %new_cursor_after_alloc, ptr addrspace(1) %cursor_ptr, align 8
150151
; call void @printi64ln(i64 4)
151152
; call void @printi64ln(i64 %cursor_phi_i)
153+
call void @llvm.memset.p1.i64(ptr addrspace(1) %cursor_phi, i8 0, i64 %size, i1 false)
152154
ret ptr addrspace(1) %cursor_phi
153155
}
154156

alloc-jit-x64.ll

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ define double @sqrt_64(double %Val) {
4545
; define new DioGC__malloc
4646
define ptr addrspace(1) @DioGC__malloc(i64 %size, i8 %obj_type, i64 %rsp) noinline optnone allockind("alloc") {
4747
entry:
48-
; if size > 128, call slowpath
48+
; if size > 7936, call slowpath
4949
; call void @printi64ln(i64 2222)
50-
%size_gt_128 = icmp ugt i64 %size, 128
50+
%size_gt_128 = icmp ugt i64 %size, 7936
5151
br i1 %size_gt_128, label %call_slowpath, label %check_collector
5252
check_collector:
5353
; Load collector from gc_handle
@@ -62,6 +62,7 @@ call_slowpath:
6262
%innerrsp = tail call ptr asm alignstack "mov %rsp, $0", "=r"() #0
6363
%rspi = ptrtoint ptr %innerrsp to i64
6464
%slowpath_result = call ptr addrspace(1) @DioGC__malloc_slowpath_jit(i64 %size, i8 %obj_type, i64 %rspi)
65+
call void @llvm.memset.p1.i64(ptr addrspace(1) %slowpath_result, i8 0, i64 %size, i1 false)
6566
; call void @printi64ln(i64 999)
6667
; %slowpath_result_i = ptrtoint ptr addrspace(1) %slowpath_result to i64
6768
; call void @printi64ln(i64 %slowpath_result_i)
@@ -75,7 +76,7 @@ fastpath_start:
7576

7677
; Get thread_local_allocator (first field)
7778
%block = load ptr addrspace(1), ptr %thread_local_allocator_ptr, align 8
78-
79+
7980
; check block is null
8081
%block_is_null = icmp eq ptr addrspace(1) %block, null
8182
br i1 %block_is_null, label %call_slowpath, label %load_block_fields
@@ -98,11 +99,12 @@ load_block_fields:
9899

99100

100101

101-
; Calculate alloc size = (size + 7) / 8 * 8
102+
; Calculate alloc size = (size + 7) / 8 * 8 + 8
102103
; LINE_SIZE is 128
103104
%size_plus_7 = add i64 %size, 7
104105
%size_div_8 = lshr i64 %size_plus_7, 3
105-
%alloc_size = shl i64 %size_div_8, 3
106+
%alloc_size_body = shl i64 %size_div_8, 3
107+
%alloc_size = add i64 %alloc_size_body, 8
106108

107109

108110

@@ -111,44 +113,44 @@ load_block_fields:
111113
%hole_end_minus_cursor = sub i64 %hole_end_i64, %cursor_i64
112114
; check if hole_end - cursor >= alloc_size
113115
%hole_end_minus_cursor_ge_alloc_size = icmp sge i64 %hole_end_minus_cursor, %alloc_size
114-
br i1 %hole_end_minus_cursor_ge_alloc_size, label %check_current_line, label %call_slowpath
115-
116-
check_current_line:
117-
; Check if alloc in current line is possible
118-
; let current_line_remains = self.cursor.align_offset(LINE_SIZE);
119-
%current_line_occupied = and i64 %cursor_i64, 127
120-
%current_line_remains = sub i64 128, %current_line_occupied
121-
116+
br i1 %hole_end_minus_cursor_ge_alloc_size, label %fast_path, label %call_slowpath
122117

123-
; call void @printi64ln(i64 %current_line_remains)
124-
; call void @printi64ln(i64 %alloc_size)
125-
; check if alloc_size <= current_line_remains && current_line_remains != 0
126-
%alloc_size_le_remains = icmp ule i64 %alloc_size, %current_line_remains
127-
%current_line_remains_ne_0 = icmp ne i64 %current_line_remains, 0
128-
%alloc_size_le_remains_and_ne_0 = and i1 %alloc_size_le_remains, %current_line_remains_ne_0
129-
br i1 %alloc_size_le_remains_and_ne_0, label %fast_path, label %check_remaining
130-
131-
check_remaining:
132-
; Check if 128 <= hole_end - cursor
133-
%hole_end_minus_cursor_ge_128 = icmp uge i64 %hole_end_minus_cursor, 128
134-
135-
; self.cursor = self.cursor.add(current_line_remains);
136-
%new_cursor_i = add i64 %cursor_i64, %current_line_remains
137-
%new_cursor = inttoptr i64 %new_cursor_i to ptr addrspace(1)
138-
br i1 %hole_end_minus_cursor_ge_128, label %fast_path, label %call_slowpath
139-
140118

141119
fast_path:
142-
; phi get cursor
143-
%cursor_phi = phi ptr addrspace(1) [ %cursor, %check_current_line ], [ %new_cursor, %check_remaining ]
144120

145-
%cursor_phi_i = ptrtoint ptr addrspace(1) %cursor_phi to i64
121+
; set header
122+
; 1. store zero to first bytt of %cursor
123+
store i8 0, ptr addrspace(1) %cursor
124+
; 2. store obj_type to second byte of %cursor
125+
%cursor_obj_type_ptr = getelementptr i8, ptr addrspace(1) %cursor, i64 1
126+
store i8 %obj_type, ptr addrspace(1) %cursor_obj_type_ptr
127+
; 3. store size (trunc to i16) to third and fourth byte of %cursor
128+
%cursor_size_ptr = getelementptr i16, ptr addrspace(1) %cursor, i64 1
129+
%size_cast = trunc i64 %alloc_size to i16
130+
store i16 %size_cast, ptr addrspace(1) %cursor_size_ptr
131+
; 4. store %cursor's lower 32 bits to fifth to eighth byte of %cursor
132+
%cursor_i32 = trunc i64 %cursor_i64 to i32
133+
%cursor_i32_ptr = getelementptr i32, ptr addrspace(1) %cursor, i64 1
134+
store i32 %cursor_i32, ptr addrspace(1) %cursor_i32_ptr
135+
136+
137+
138+
%cursor_phi_i = add i64 %cursor_i64, 8
139+
%cursor_phi = inttoptr i64 %cursor_phi_i to ptr addrspace(1)
146140
; Update cursor
147-
%new_cursor_after_alloc_i = add i64 %cursor_phi_i, %alloc_size
141+
%new_cursor_after_alloc_i = add i64 %cursor_i64, %alloc_size
142+
; checi if new_cursor_after_alloc_i is zero
143+
%new_cursor_after_alloc_is_zero = icmp eq i64 %new_cursor_after_alloc_i, 0
144+
br i1 %new_cursor_after_alloc_is_zero, label %unreachable_path, label %update_cursor
145+
unreachable_path:
146+
unreachable
147+
148+
update_cursor:
148149
%new_cursor_after_alloc = inttoptr i64 %new_cursor_after_alloc_i to ptr addrspace(1)
149150
store ptr addrspace(1) %new_cursor_after_alloc, ptr addrspace(1) %cursor_ptr, align 8
150151
; call void @printi64ln(i64 4)
151152
; call void @printi64ln(i64 %cursor_phi_i)
153+
call void @llvm.memset.p1.i64(ptr addrspace(1) %cursor_phi, i8 0, i64 %size, i1 false)
152154
ret ptr addrspace(1) %cursor_phi
153155
}
154156

0 commit comments

Comments
 (0)