Skip to content

Commit b62dc34

Browse files
authored
Merge pull request #331 from Pivot-Studio/feat/libc
feat: core lib improvments & multiple bug fixes
2 parents 5e6ff62 + 7762482 commit b62dc34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2917
-759
lines changed

Cargo.lock

Lines changed: 224 additions & 81 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ rowan = "0.15"
2222
dissimilar = "1.0"
2323
stderrlog = "0.5"
2424
log = "0.4"
25-
clap = { version = "4.1", features = ["derive", "unstable-styles"] }
25+
clap = { version = "4.4", features = ["derive", "string"] }
2626
colored = "2.0"
2727
serde = "1.0"
2828
lsp-types = { branch = "master", features = ["proposed"], git = "https://github.com/Pivot-Studio/lsp-types" }
@@ -35,7 +35,7 @@ enum_dispatch = "0.3"
3535
threadpool = {version = "1.8", optional = true}
3636
dunce = "1.0"
3737
toml = "0.7"
38-
ariadne = "0.2"
38+
ariadne = {version = "0.3", features = []}
3939
dyn-fmt = "0.3"
4040
petgraph = "0.6"
4141
kagari = { path = "./kagari" }
@@ -104,3 +104,5 @@ codegen-units = 1
104104
[dev-dependencies]
105105
expect-test = "1.4.1"
106106

107+
[build-dependencies]
108+
vergen = "7.3.2"

build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// build.rs
2+
3+
use vergen::{vergen, Config};
4+
fn main() {
5+
let mut cfg = Config::default();
6+
*cfg.sysinfo_mut().name_mut() = false;
7+
vergen(cfg).expect("Fail to generate version info");
8+
}

immix/llvm/plimmixprinter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,9 @@ void PLImmixGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter
145145
continue;
146146
}
147147

148-
if (GV->isManifestConstant()) // skip constants
148+
if (isa<GlobalVariable>(GV) && cast<GlobalVariable>(GV)->isConstant()) // skip constants
149149
{
150+
// printf("skip %s\n", GV->getName().bytes());
150151
continue;
151152
}
152153

@@ -156,6 +157,7 @@ void PLImmixGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter
156157
{
157158
continue;
158159
}
160+
// printf("%s\n", GV->getName().bytes());
159161

160162
ii++;
161163
}
@@ -167,7 +169,20 @@ void PLImmixGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter
167169
{
168170
AP.OutStreamer.get()->AddComment("global address");
169171
const GlobalValue *GV = &*GI;
170-
if (GV->getName().contains("llvm."))
172+
if (GV->getName().contains("llvm.")) // skip magic variables e.g. @llvm.global_ctors
173+
{
174+
continue;
175+
}
176+
177+
if (isa<GlobalVariable>(GV) && cast<GlobalVariable>(GV)->isConstant()) // skip constants
178+
{
179+
// printf("skip %s\n", GV->getName().bytes());
180+
continue;
181+
}
182+
183+
if (GV->getName().startswith("_IMMIX_GC_MAP") ||
184+
GV->getName().contains("_@IMMIX_OBJTYPE_") ||
185+
GV->getName().startswith(".str")) // skip generated globals
171186
{
172187
continue;
173188
}

immix/src/allocator/big_obj_allocator.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use std::cell::RefCell;
2+
13
use parking_lot::ReentrantMutex;
24

3-
use crate::{bigobj::BigObj, mmap::Mmap, round_n_up, ALIGN};
5+
use crate::{bigobj::BigObj, mmap::Mmap, round_n_up, ALIGN, BIG_OBJ_ALIGN};
46

57
pub struct BigObjAllocator {
68
mmap: Mmap,
@@ -9,6 +11,7 @@ pub struct BigObjAllocator {
911
heap_end: *mut u8,
1012
unused_chunks: Vec<*mut BigObj>,
1113
lock: ReentrantMutex<()>,
14+
commited_to: RefCell<*mut u8>,
1215
}
1316

1417
impl BigObjAllocator {
@@ -17,6 +20,7 @@ impl BigObjAllocator {
1720
Self {
1821
current: mmap.aligned(ALIGN),
1922
heap_start: mmap.aligned(ALIGN),
23+
commited_to: RefCell::new(mmap.aligned(ALIGN)),
2024
heap_end: mmap.end(),
2125
mmap,
2226
unused_chunks: Vec::new(),
@@ -41,8 +45,16 @@ impl BigObjAllocator {
4145
if next >= heap_end {
4246
panic!("big object mmap out of memory");
4347
}
48+
unsafe {
49+
let end = current.add(size);
50+
let offset = current.align_offset(ALIGN);
51+
let dest = *self.commited_to.borrow();
4452

45-
self.mmap.commit(current, size);
53+
if end > dest && !self.mmap.commit(dest, size - offset) {
54+
panic!("big object mmap out of memory");
55+
}
56+
self.commited_to.replace(end.add(end.align_offset(ALIGN)));
57+
}
4658

4759
// self.current = next;
4860
let obj = BigObj::new(current, size);
@@ -51,7 +63,7 @@ impl BigObjAllocator {
5163
}
5264

5365
pub fn get_chunk(&mut self, size: usize) -> *mut BigObj {
54-
let size = round_n_up!(size + 16, ALIGN); // 16 is the size of BigObj
66+
let size = round_n_up!(size + 16, BIG_OBJ_ALIGN); // 16 is the size of BigObj
5567
let _lock = self.lock.lock();
5668
for i in 0..self.unused_chunks.len() {
5769
let unused_obj = self.unused_chunks[i];

immix/src/allocator/global_allocator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl GlobalAllocator {
4646
///
4747
/// size is the max heap size
4848
pub fn new(size: usize) -> Self {
49-
let mmap = Mmap::new(size);
49+
let mmap = Mmap::new(size * 3 / 4);
5050

5151
// mmap.commit(mmap.aligned(), BLOCK_SIZE);
5252

@@ -57,7 +57,7 @@ impl GlobalAllocator {
5757
mmap,
5858
free_blocks: Vec::new(),
5959
lock: ReentrantMutex::new(()),
60-
big_obj_allocator: BigObjAllocator::new(size),
60+
big_obj_allocator: BigObjAllocator::new(size / 4),
6161
last_get_block_time: std::time::Instant::now(),
6262
mem_usage_flag: 0,
6363
round: 0,

immix/src/allocator/thread_local_allocator.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,9 @@ impl ThreadLocalAllocator {
276276
self.unavailable_blocks.push(new_block);
277277
} else {
278278
// new_block未被用完,将它加入recyclable blocks
279-
unsafe {
280-
debug_assert!((*new_block).find_first_hole().is_some());
281-
}
279+
// unsafe {
280+
// debug_assert!((*new_block).find_first_hole().is_some());
281+
// }
282282
self.recyclable_blocks.push_back(new_block);
283283
}
284284
re
@@ -357,14 +357,14 @@ impl ThreadLocalAllocator {
357357
let block = *block;
358358
if (*block).marked {
359359
total_used += (*block).correct_header(mark_histogram);
360-
let (line, hole) = (*block).get_available_line_num_and_holes();
360+
let (line, _) = (*block).get_available_line_num_and_holes();
361361
if line > 0 {
362-
debug_assert!(
363-
(*block).find_first_hole().is_some(),
364-
"line {}, hole {}",
365-
line,
366-
hole
367-
);
362+
// debug_assert!(
363+
// (*block).find_first_hole().is_some(),
364+
// "line {}, hole {}",
365+
// line,
366+
// hole
367+
// );
368368
recyclable_blocks.push_back(block);
369369
} else {
370370
unavailable_blocks.push(block);

immix/src/bigobj.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::consts::ALIGN;
1+
use crate::BIG_OBJ_ALIGN;
22

33
// big obj struct
44
#[derive(Debug)]
@@ -19,8 +19,8 @@ impl BigObj {
1919
pub fn new(at: *mut u8, size: usize) -> &'static mut Self {
2020
unsafe {
2121
let ptr = at as *mut Self;
22-
debug_assert!(ptr as usize % ALIGN == 0);
23-
debug_assert!(size % ALIGN == 0);
22+
debug_assert!(ptr as usize % BIG_OBJ_ALIGN == 0);
23+
debug_assert!(size % BIG_OBJ_ALIGN == 0);
2424
ptr.write(Self {
2525
header: 0b10000000,
2626
size, // size of [[ obj_st | data ]]

immix/src/block.rs

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ pub struct Block {
5757
line_map: [LineHeader; NUM_LINES_PER_BLOCK],
5858
/// 第一个hole的起始行号
5959
cursor: usize,
60-
/// 第一个hole的长度(行数
61-
limit: usize,
60+
// /// 第一个hole的长度(行数
61+
// limit: usize,
6262
/// 是否被标记
6363
pub marked: bool,
6464
/// 洞的数量
@@ -166,7 +166,6 @@ impl Block {
166166
ptr.write(Self {
167167
line_map: [0; NUM_LINES_PER_BLOCK],
168168
cursor: 3, // 跳过前三行,都用来放metadata。浪费一点空间(metadata从0.8%->1.2%)
169-
limit: (NUM_LINES_PER_BLOCK - 3),
170169
marked: false,
171170
hole_num: 1,
172171
available_line_num: NUM_LINES_PER_BLOCK - 3,
@@ -184,7 +183,6 @@ impl Block {
184183
pub fn show(&self) {
185184
println!("size: {}", self.get_size());
186185
println!("first_hole_line_idx: {}", self.cursor);
187-
println!("first_hole_line_len: {}", self.limit);
188186
println!("marked: {}", self.marked);
189187
println!("hole_num: {}", self.hole_num);
190188
println!("available_line_num: {}", self.available_line_num);
@@ -213,7 +211,6 @@ impl Block {
213211
}
214212
pub fn reset_header(&mut self) {
215213
self.cursor = 3;
216-
self.limit = NUM_LINES_PER_BLOCK - 3;
217214
self.line_map = [0; NUM_LINES_PER_BLOCK];
218215
self.marked = false;
219216
self.hole_num = 1;
@@ -270,17 +267,14 @@ impl Block {
270267
if len > 0 {
271268
if first_hole_line_len == 0 {
272269
first_hole_line_idx = idx - len;
273-
first_hole_line_len = len;
274270
}
275271
holes += 1;
276272
}
277273

278274
self.cursor = first_hole_line_idx;
279-
self.limit = first_hole_line_len;
280275
self.marked = false;
281276
self.hole_num = holes;
282277
self.eva_target = false;
283-
// println!("holes: {}, first_idx: {} , first_len: {} {:?}", holes,first_hole_line_idx,first_hole_line_len,self.line_map.iter().map(|&x| x & 1).collect::<Vec<_>>());
284278
if let Some(count) = (*mark_histogram).get_mut(&self.hole_num) {
285279
*count += marked_num;
286280
} else {
@@ -325,32 +319,16 @@ impl Block {
325319
}
326320
len = 0;
327321
}
328-
// self.show();
329-
// panic!("prev_hole: {:?}, idx: {}, len: {}, size_line: {}", prev_hole, idx, len, size_line);
322+
330323
idx += 1;
331324
}
332-
// panic!("xxx");
333325

334326
if len >= size_line {
335327
return Some((idx - len, len));
336328
}
337329
None
338330
}
339331

340-
/// # find_first_hole
341-
///
342-
/// Find the first hole in the block.
343-
///
344-
/// Return the start line index and the length of the hole (u8, u8).
345-
///
346-
/// If no hole found, return `None`.
347-
pub fn find_first_hole(&self) -> Option<(usize, usize)> {
348-
if self.limit == 0 {
349-
return None;
350-
}
351-
(self.cursor, self.limit).into()
352-
}
353-
354332
/// # get_nth_line
355333
///
356334
/// get the line at nth index as * mut u8
@@ -477,21 +455,17 @@ impl Block {
477455
// 设置起始line header的obj_type
478456
let header = self.line_map.get_mut(start).unwrap();
479457
*header |= (obj_type as u8) << 2 | 0b10000000;
480-
// header.set_obj_type(obj_type);
481-
// header.set_is_head(true);
458+
482459
// 更新first_hole_line_idx和first_hole_line_len
483460
if start == self.cursor {
484461
self.cursor += line_size;
485-
self.limit -= line_size;
462+
// self.limit -= line_size;
486463
}
487-
if self.limit == 0 {
488-
if let Some((idx, len)) = self.find_next_hole((self.cursor, self.limit), 1) {
489-
self.cursor = idx;
490-
self.limit = len;
491-
} else {
492-
self.hole_num -= 1;
493-
return Some((start, false));
494-
}
464+
if let Some((idx, _)) = self.find_next_hole((self.cursor, 0), 1) {
465+
self.cursor = idx;
466+
} else {
467+
self.hole_num -= 1;
468+
return Some((start, false));
495469
}
496470
if self.cursor > start + len && len == line_size {
497471
// 正好匹配,那么减少一个hole
@@ -512,8 +486,8 @@ mod tests {
512486
unsafe {
513487
let mut ga = GlobalAllocator::new(1024 * 1024 * 1024);
514488
let block = &mut *ga.get_block();
515-
// 第一个hole应该是从第三行开始,长度是253
516-
assert_eq!(block.find_first_hole(), Some((3, 253)));
489+
// // 第一个hole应该是从第三行开始,长度是253
490+
// assert_eq!(block.find_first_hole(), Some((3, 253)));
517491
// 标记hole隔一行之后的第一行为已使用
518492
let header = block.get_nth_line_header(4);
519493
header.set_used(true);
@@ -535,7 +509,7 @@ mod tests {
535509
let block = &mut *ga.get_block();
536510
// 设置第5行已被使用
537511
block.get_nth_line_header(5).set_used(true);
538-
block.limit = 2;
512+
// block.limit = 2;
539513
block.hole_num = 2;
540514
// 从第三行开始分配,长度为128
541515
// 分配前:
@@ -566,7 +540,7 @@ mod tests {
566540
assert_eq!(start, 3);
567541
// assert_eq!(newcursor, Some(block.get_nth_line(4)));
568542
assert_eq!(block.cursor, 4);
569-
assert_eq!(block.limit, 1);
543+
// assert_eq!(block.limit, 1);
570544
let l = block.get_nth_line_header(3).get_obj_type();
571545
assert_eq!(l, crate::block::ObjectType::Atomic);
572546
// 从第4行开始分配,长度为129
@@ -585,15 +559,15 @@ mod tests {
585559
// ......
586560
assert_eq!(block.alloc(129, crate::block::ObjectType::Atomic), None);
587561
assert_eq!(block.cursor, 4);
588-
assert_eq!(block.limit, 1);
562+
// assert_eq!(block.limit, 1);
589563

590564
block.cursor = 6;
591-
block.limit = 250;
565+
// block.limit = 250;
592566
let (start, newcursor) = block
593567
.alloc((256 - 6) * LINE_SIZE, crate::block::ObjectType::Complex)
594568
.expect("cannot alloc new line");
595569
block.cursor = 4;
596-
block.limit = 1;
570+
// block.limit = 1;
597571
// 从第6行开始分配,长度为256-6
598572
// 分配后:
599573
// --------
@@ -613,7 +587,7 @@ mod tests {
613587
assert_eq!(start, 6);
614588
assert_eq!(newcursor, false);
615589
assert_eq!(block.cursor, 4);
616-
assert_eq!(block.limit, 1);
590+
// assert_eq!(block.limit, 1);
617591
let (start, newcursor) = block
618592
.alloc(128, crate::block::ObjectType::Atomic)
619593
.expect("cannot alloc new line");
@@ -634,7 +608,7 @@ mod tests {
634608
assert_eq!(start, 4);
635609
assert_eq!(newcursor, false);
636610
// assert_eq!(block.first_hole_line_idx, 255); 这个时候没hole了,此值无意义,len为0
637-
assert_eq!(block.limit, 0);
611+
// assert_eq!(block.limit, 0);
638612

639613
// test big alloc
640614
let obj = ga.get_big_obj(BLOCK_SIZE);

0 commit comments

Comments
 (0)