Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ target
*.plb
*.piv
.VSCodeCounter
# ignore all ll file except alloc.ll
*.ll
!alloc.ll
*.out
*.ilk
*.exe
Expand Down
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
]
},
"args": [
"test/main.pi",
// "-O1"
"${workspaceFolder}/test/main.pi",
"-O3"
]
},
{
Expand Down
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"lldb.dereferencePointers": true,
"lldb.consoleMode": "commands",
"makefile.configureOnOpen": true,
"vs-browser.localProxyServer.cookieDomainRewrite": true,
"vs-browser.localProxyServer.enabled": true,
"vs-browser.localProxyServer.forceLocation": true,
"vs-browser.proxyMode": true,
// "rust-analyzer.check.targets": [
// "wasm32-unknown-unknown",
// ],
Expand Down
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ thread = ["threadpool"]
members = ["internal_macro", "vm", "pl_linker", "immix", "kagari"]

[profile.release]
lto = "fat"
lto = "thin"
opt-level = 3
debug = "line-tables-only"

Expand All @@ -107,7 +107,7 @@ opt-level = 3
# debug = true
debug-assertions = false
overflow-checks = false
lto = "fat"
lto = "thin"
#panic = 'unwind' # This setting is always ignored.
incremental = true
codegen-units = 1
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ devmac:
@echo "环境变量已加入~/.bashrc,请重启终端和vsc应用更改"

vm:
@cd vm && cargo build --release
@cd vm && cargo build --release --locked

vmdebug:
@mkdir -p target/release
Expand Down
129 changes: 129 additions & 0 deletions alloc.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
; create a threadlocal collecor handle

@gc_handle = thread_local(localexec) global ptr null, align 8

; declare DioGC__malloc_slowpath
declare noalias ptr addrspace(1) @DioGC__malloc_slowpath(
i64 %size,
i8 %obj_type,
i64 %rsp,
ptr %space
) allockind("alloc")

declare double @llvm.sqrt.f64(double %Val)

define double @sqrt_64(double %Val) {
%1 = call double @llvm.sqrt.f64(double %Val)
ret double %1
}

; define new DioGC__malloc
define ptr addrspace(1) @DioGC__malloc(i64 %size, i8 %obj_type, ptr %rsp) noinline optnone allockind("alloc") {
entry:
; if size > 7936, call slowpath
%size_gt_7936 = icmp ugt i64 %size, 7936
br i1 %size_gt_7936, label %call_slowpath, label %check_collector
check_collector:
; Load collector from gc_handle
%collector_ptr = load ptr, ptr @gc_handle, align 8

; Check if collector_ptr is null
%is_null = icmp eq ptr %collector_ptr, null
br i1 %is_null, label %call_slowpath, label %fastpath_start


call_slowpath:
%slowpath_result = call ptr addrspace(1) @DioGC__malloc_slowpath(i64 %size, i8 %obj_type, ptr %rsp, ptr @gc_handle)
ret ptr addrspace(1) %slowpath_result
fastpath_start:
%thread_local_allocator_ptr = load ptr, ptr %collector_ptr, align 8

; get second field of collector, which is bytes_allocated_since_last_gc
%bytes_allocated_since_last_gc_ptr = getelementptr i64, ptr %collector_ptr, i32 1

; Get thread_local_allocator (first field)
%block = load ptr addrspace(1), ptr %thread_local_allocator_ptr, align 8

; Load block fields
%cursor_ptr = getelementptr i64, ptr addrspace(1) %block, i32 0
%cursor = load i64, ptr addrspace(1) %cursor_ptr, align 8

; ; if cursor > 256, call slowpath
; %cursor_gt_256 = icmp ugt i64 %cursor, 255
; br i1 %cursor_gt_256, label %call_slowpath, label %load_block_fields_2

; load_block_fields_2:

%next_hole_size_ptr = getelementptr i64, ptr addrspace(1) %block, i32 1
%next_hole_size = load i64, ptr addrspace(1) %next_hole_size_ptr, align 8

%available_line_num_ptr = getelementptr i64, ptr addrspace(1) %block, i32 2
%available_line_num = load i64, ptr addrspace(1) %available_line_num_ptr, align 8


; Calculate line_size = (size - 1) / LINE_SIZE + 1
; LINE_SIZE is 128
%size_minus_1 = sub i64 %size, 1
%div = udiv i64 %size_minus_1, 128
%line_size = add i64 %div, 1

; Check if fast path is possible (next_hole_size >= line_size)
%fast_path_possible = icmp uge i64 %next_hole_size, %line_size
br i1 %fast_path_possible, label %fast_path, label %call_slowpath

fast_path:
; Update available_line_num
%new_available = sub i64 %available_line_num, %line_size
store i64 %new_available, ptr addrspace(1) %available_line_num_ptr, align 8

; Get line map pointer (after the first three fields)
%line_map_ptr = getelementptr i64, ptr addrspace(1) %block, i32 3

; Mark lines as used and set object type for first line
%first_line_ptr = getelementptr i8, ptr addrspace(1) %line_map_ptr, i64 %cursor
; Set object type and mark as used (obj_type << 2 | 0b10000001)
%shifted_type = shl i8 %obj_type, 2
%header_val = or i8 %shifted_type, 129 ; 129 = 0b10000001
store i8 %header_val, ptr addrspace(1) %first_line_ptr, align 1

; Check if line_size is 1
%is_one_line = icmp eq i64 %line_size, 1
br i1 %is_one_line, label %finish_fast_path, label %mark_lines_start

mark_lines_start:
; Mark remaining lines as used (0b00000001)
%next_cursor = add i64 %cursor, 1
%end_cursor = add i64 %cursor, %line_size
br label %mark_lines

mark_lines:
%current = phi i64 [ %next, %mark_lines ], [ %next_cursor, %mark_lines_start ]
%line_ptr = getelementptr i8, ptr addrspace(1) %line_map_ptr, i64 %current
store i8 1, ptr addrspace(1) %line_ptr, align 1
%next = add i64 %current, 1
%continue = icmp ult i64 %next, %end_cursor
br i1 %continue, label %mark_lines, label %finish_fast_path

finish_fast_path:
; Calculate return address (block + cursor * LINE_SIZE)
%base_offset = mul i64 %cursor, 128
%result_addr = getelementptr i8, ptr addrspace(1) %block, i64 %base_offset

; Update cursor
%new_cursor = add i64 %cursor, %line_size
store i64 %new_cursor, ptr addrspace(1) %cursor_ptr, align 8

; Update next_hole_size
%new_hole_size = sub i64 %next_hole_size, %line_size
store i64 %new_hole_size, ptr addrspace(1) %next_hole_size_ptr, align 8

; Update bytes_allocated_since_last_gc (the size should be line_size * 128)
%bytes_allocated_since_last_gc = load i64, ptr %bytes_allocated_since_last_gc_ptr, align 8
%size_128 = mul i64 %line_size, 128
%new_bytes_allocated = add i64 %size_128, %bytes_allocated_since_last_gc
store i64 %new_bytes_allocated, ptr %bytes_allocated_since_last_gc_ptr, align 8
ret ptr addrspace(1) %result_addr
}


attributes #0 = { nounwind allockind("alloc") "gc-leaf-function" }
18 changes: 10 additions & 8 deletions planglib/core/gc.pi
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
fn DioGC__malloc(size: i64, obj_type: u8, rsp:i64) *();

pub fn gc_print_block_time() void;

pub fn DioGC__collect() void;

pub fn DioGC__malloc_no_collect(size: i64, obj_type: u8) *u8;
Expand Down Expand Up @@ -102,15 +104,15 @@ pub fn utf8_count(ptr: *u8, len:i64) i64;
impl string {
pub fn append(str: string) void {
let old = self.data;
// let atomic: u8 = 0;
// let new = DioGC__malloc(self._byte_len + str._byte_len, atomic);
// memcpy(new, old, self._byte_len);
let arr = [u8*self._byte_len + str._byte_len;];
memcpy(&arr[0], old, self._byte_len);
// let new_i_end = ptr_to_int(new) + self._byte_len;
let new_end = &arr[self._byte_len];
let atomic: u8 = 0;
let new = DioGC__malloc(self._byte_len + str._byte_len, atomic, asm_sp());
memcpy(unsafe_cast<u8>(new), old, self._byte_len);
// let arr = arr_from_raw(unsafe_cast<u8>(new), self._byte_len + str._byte_len);
// let p = ptr_to_int(unsafe_cast<u8>(new));
let new_i_end = ptr_to_int(unsafe_cast<u8>(new)) + self._byte_len;
let new_end = int_to_ptr(new_i_end);
memcpy(new_end, str.data, str._byte_len);
self.data = &arr[0];
self.data = unsafe_cast<u8>(new);
self._len = self._len + str._len;
self._byte_len = self._byte_len + str._byte_len;
return;
Expand Down
8 changes: 8 additions & 0 deletions planglib/core/string.pi
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ pub fn stringbuilder(len: i64) StringBuilder {
}

impl StringBuilder {

pub fn current_pos() i64 {
return self.len;
}
pub fn set_pos(pos: i64) void {
self.len = pos;
return;
}
pub fn add_byte(ch: u8) void {
self.data[self.len] = ch;
self.len = self.len + 1;
Expand Down
1 change: 1 addition & 0 deletions planglib/std/__private.pi
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ use std::task::executor;
use std::task::helper;
use std::task::delay;
use std::task::tcp;
use std::json::encode;
2 changes: 1 addition & 1 deletion planglib/std/cols/hashtable.pi
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl <K:Hash+Eq<K>|V> HashTable<K|V> {
// current = self.buckets[bucket as i64];
let head = current as *TableNode<K|V>!;
while !head.next is None {
if head.hash == hash {
if head.key.eq(&k) {
return head.value;
}
head = head.next as *TableNode<K|V>!;
Expand Down
101 changes: 101 additions & 0 deletions planglib/std/json/encode.pi
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use core::string::stringbuilder;
use core::string::ToString;
use std::slice::SliceExt;


pub trait JSONSerilizable {
fn to_json() string;
}

pub fn encode<T>(t:T) string {
let sb = stringbuilder(10);
let isarr = false;
if_arr(t, {
let a = _arr;
sb.add_char('[');
for let i = 0; i < arr_len(a); i = i + 1 {
let elm = a[i];
let elm_encode = encode(elm);
sb.add_str(elm_encode);
sb.add_char(',');

}
let pos = sb.current_pos();
if arr_len(a) > 0 {
sb.set_pos(pos - 1);
}
sb.add_char(']');
isarr = true;
});
if isarr {
return sb.str();
}
sb.add_char('{');
forfields(t, {
let pos = sb.current_pos();
sb.add_char('"');
sb.add_str(_field_name);
sb.add_char('"');
sb.add_char(':');

let succ = false;

if let i = _field impl JSONSerilizable {
let re = i.to_json();
sb.add_str(re);
succ = true;
}
if !succ {
match_type<string>(_field, {
sb.add_char('"');
sb.add_str(_value);
sb.add_char('"');
succ = true;
});
match_type<i64>(_field, {
sb.add_str(_value.to_string());
succ = true;
});
match_type<u64>(_field, {
sb.add_str(_value.to_string());
succ = true;
});
match_type<f64>(_field, {
sb.add_str(_value.to_string());
succ = true;
});
match_type<f32>(_field, {
sb.add_str(_value.to_string());
succ = true;
});
match_type<bool>(_field, {
sb.add_str(_value.to_string());
succ = true;
});
match_type<char>(_field, {
sb.add_char('"');
sb.add_char(_value);
sb.add_char('"');
succ = true;
});

}
if !succ {
let re = encode(_field);
sb.add_str(re);
succ = true;
}



sb.add_char(',');
if !succ {
sb.set_pos(pos);
}
});
let pos = sb.current_pos();
sb.set_pos(pos - 1);
sb.add_char('}');

return sb.str();
}
Loading
Loading