aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Moon Flower <moon@coffin.ir> 2025-02-28 01:50:25 +0330
committerGravatar Moon Flower <moon@coffin.ir> 2025-02-28 01:50:25 +0330
commitf7a08d4db77eaef1f6685c3fb263bb1cb1376deb (patch)
treec6fb20ba555421bf5fc483717810ba2234ce235b
parentDecently performant double-linked two-way linked list implementation (diff)
Added a (rather useless) profiler (and also linked list speed optimizations)
-rw-r--r--Makefile12
-rw-r--r--main.c27
-rw-r--r--moonshine.h104
3 files changed, 107 insertions, 36 deletions
diff --git a/Makefile b/Makefile
index b73f7a6..d079677 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
FLAGS = -Wno-incompatible-library-redeclaration -nostartfiles
-SIZE_FLAGS = -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -s -fno-unwind-tables -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-ident -fvisibility=hidden -march=native -Wl,--build-id=none
+SIZE_FLAGS = -Wl,--undefined=main -flto -Oz -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--strip-all -finline-hint-functions -fno-builtin -Wl,--print-gc-sections -fno-unwind-tables -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-ident -fvisibility=hidden -march=native -Wl,--build-id=none
all: m4 c test
@@ -12,6 +12,16 @@ c:
test:
./out.bin
+# useless. it don't work.
+# profile:
+# clang -D__MOONSHINE_PROFILER main.c -o out.bin.profile $(FLAGS) $(SIZE_FLAGS) -fprofile-generate
+# echo NOTE: Let the program run completely and provide it with typical inputs.
+# ./out.bin.profile
+# llvm-profdata merge -output=default.profdata profile.profraw
+# rm -rf profile.profraw
+# clang main.c -o out.bin.release $(FLAGS) $(SIZE_FLAGS) -fprofile-use
+# rm -rf profile.profdata
+
release:
clang main.c -o out.bin.release $(FLAGS) $(SIZE_FLAGS)
diff --git a/main.c b/main.c
index 58c28dd..c59984f 100644
--- a/main.c
+++ b/main.c
@@ -2,17 +2,30 @@
#include "moonshine.h"
-datatype(binarytree, ((leaf, int), (node, binarytree *, int, binarytree *) ));
+const enum { test_datatype, test_linkedlist } current_test = test_linkedlist;
int main() {
- const auto tree = instance(binarytree, leaf, 3);
+ if (current_test == test_datatype) {
+ datatype(binarytree, ((leaf, int), (node, binarytree *, int, binarytree *) ));
+ const auto tree = instance(binarytree, leaf, 3);
- print(&tree);
+ print(&tree);
- match(tree) {
- of(leaf, v) print("Leafy ", v);
- of(node, _, v, _) print("Nodey ", v);
- other() print("Idk man");
+ match(tree) {
+ of(leaf, v) print("Leafy ", v);
+ of(node, _, v, _) print("Nodey ", v);
+ other() print("Idk man");
+ }
+ } else if (current_test == test_linkedlist) {
+ const auto ll = create_linkedlist();
+
+ for (u8 i = 0; i < 100; i++) push_linkedlist(ll, (var) i);
+
+ print((u8) index_to_ptr(ll, 12)->data);
+ }
+
+ else {
+ print("Unknown test.");
}
return 0;
diff --git a/moonshine.h b/moonshine.h
index eb47a6c..19c125a 100644
--- a/moonshine.h
+++ b/moonshine.h
@@ -38,8 +38,9 @@
}
#define instance(__type, kind, ...) ((struct __type) { .type = cat(kind, _type), .data.kind = { __VA_ARGS__ } })
#define scope(name, ...) \
- for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; datatype_break == (typeof(name)) 0; \
- datatype_break = (typeof(name)) 1)
+ _Pragma("unroll") for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; \
+ datatype_break == (typeof(name)) 0; \
+ datatype_break = (typeof(name)) 1)
#define match(value) scope(parent_value, &value) switch (parent_value->type)
#define algebra_field_sum(extra, time, field) +sizeof(cat(extra, field))
#define algebra_of_field(extra, time, field) scope(field, ({ parent_value->data.extra.cat4(object_type_, extra, _, time); }))
@@ -1085,17 +1086,16 @@ void unsafe_push(var *array, const var ptr, const u4 ptr_size) [[clang::allocati
__attribute__((deprecated(LIBC_WARNINGS_TEXT("strdup"))))
#endif
-__attribute__((diagnose_as_builtin(__builtin_strdup, 1)))
-t(char) strdup(ctring str) {
- const u8 len = strlen(str);
- const auto obj = new (char, len + 1);
+// ctring strdup(ctring str) {
+// const u8 len = strlen(str);
+// string obj = alloc(len + 1);
- for (u8 i = 0; i < len; i++) obj[ 0 ][ i ] = str[ i ];
+// for (u8 i = 0; i < len; i++) obj[ i ] = str[ i ];
- obj[ 0 ][ len ] = 0;
+// obj[ len ] = 0;
- return obj;
-}
+// return obj;
+// }
var *__reverse_array(var *array) {
const u4 element_size = element_size(array);
@@ -1188,29 +1188,41 @@ linkednode *index_to_ptr(linkedlist *list, u8 index) {
else if (index == last - 2) return list->tail->back[ 1 ];
// clang-format on
+ linkednode *current;
+ u8 current_index;
+
// decide whether to start from the head or the tail of the list
- if (index < (last / 2)) { // start from the head
- byte body = 0;
- auto start = list->head->front[ 1 ]->front;
- for (u8 i = 3; i <= index; i++) {
- if (start[ body ] == NULL) return NULL;
- if (i == index) return start[ body ];
- if (body) start = start[ 1 ]->front;
- body = 1 - body;
+ if (index <= (last / 2)) { // start from the head
+ current = list->head;
+ current_index = 0;
+ while (current && current_index < index) {
+ if (current->front[ 1 ] && current_index + 2 <= index) {
+ current = current->front[ 1 ];
+ current_index += 2;
+ } else if (current->front[ 0 ]) {
+ current = current->front[ 0 ];
+ current_index += 1;
+ } else {
+ break;
+ }
}
} else { // start from the tail
- byte body = 0;
- auto end = list->tail->back[ 1 ]->back;
- for (u8 i = last - 3; i >= index; i--) {
- if (end[ body ] == NULL) return NULL;
- if (i == index) return end[ body ];
- if (i == 0) return NULL;
- if (body) end = end[ 1 ]->back;
- body = 1 - body;
+ current = list->tail;
+ current_index = list->size - 1;
+ while (current && current_index > index) {
+ if (current->back[ 1 ] && current_index - 2 >= index) {
+ current = current->back[ 1 ];
+ current_index -= 2;
+ } else if (current->back[ 0 ]) {
+ current = current->back[ 0 ];
+ current_index -= 1;
+ } else {
+ break;
+ }
}
}
- return NULL;
+ return (current_index == index) ? current : NULL;
}
// This function will return a pointer to the linkednode, if free = false, and a pointer to the data contained inside, if free =
@@ -1234,6 +1246,8 @@ overload var pop_item(linkedlist *list, bool free, linkednode *item) {
item->front[ 0 ] = item->front[ 1 ] = item->back[ 0 ] = item->back[ 1 ] = 0;
+ list->size--;
+
auto ptr = item->data;
if (free) {
release(item);
@@ -1263,7 +1277,19 @@ line void front_insert(linkedlist *list, u8 index) { return front_insert(list, i
string *environ;
-[[noreturn]] void __moonshine_start(int argc, string *argv, string *envp) {
+#ifdef __MOONSHINE_PROFILER
+extern void __llvm_profile_reset_counters(void);
+extern int __llvm_profile_write_file(void);
+extern void __llvm_profile_set_filename(const char *name);
+#endif
+
+[[noreturn]] __attribute__((used)) void __moonshine_start(int argc, string *argv, string *envp) {
+#ifdef __MOONSHINE_PROFILER
+ static const char profile_filename[] __attribute__((used)) = "profile.profraw";
+ __llvm_profile_reset_counters();
+ __llvm_profile_set_filename(profile_filename);
+#endif
+
global_page_table = PageTable();
environ = envp;
@@ -1277,7 +1303,13 @@ string *environ;
: "r"((long) argc), "r"(argv)
: "rdi", "rsi", "rax", "memory");
+#ifdef __MOONSHINE_PROFILER
+ extern int __llvm_profile_write_file(void);
+ __llvm_profile_write_file();
+#endif
+
exit(exit_code);
+ __builtin_unreachable();
}
__attribute__((force_align_arg_pointer)) __attribute__((naked)) void _start(void) {
@@ -1357,7 +1389,11 @@ FILE *fopen(const char *pathname, const char *mode) {
int fd = syscall5(SYS_openat, AT_FDCWD, pathname, flags, perms);
if (fd < 0) return 0;
+#ifdef __MOONSHINE_PROFILER
+ FILE *file = (FILE *) __bare_alloc(sizeof(FILE));
+#else
FILE *file = (FILE *) alloc(sizeof(FILE));
+#endif
if (!file) {
(void) syscall2(SYS_close, fd);
return 0;
@@ -1381,7 +1417,11 @@ size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
int fclose(FILE *stream) {
if (!stream) return -1;
int ret = syscall2(SYS_close, stream->fd);
+#ifdef __MOONSHINE_PROFILER
+ __bare_munmap((var) stream, sizeof(FILE));
+#else
release((var) stream);
+#endif
return (ret < 0) ? -1 : 0;
}
@@ -1406,4 +1446,12 @@ size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
long ftell(FILE *stream) { return syscall4(SYS_lseek, stream->fd, 0, SEEK_CUR); }
+#ifdef __MOONSHINE_PROFILER
+void *__dso_handle = (void *) 0;
+int atexit(void (*func)(void)) {
+ func(); // Call immediately since we don’t buffer exits
+ return 0;
+}
+#endif
+
#endif