From 6ea82f01fd50b60e5ad4953441965e049fe0d49e Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 28 Mar 2023 21:56:05 +0800 Subject: [PATCH] update gc --- src/codeobject.h | 4 +-- src/compiler.h | 8 +++--- src/memory.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ src/obj.h | 4 +-- src/parser.h | 4 +-- src/vm.h | 2 +- 6 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/codeobject.h b/src/codeobject.h index 92f4ba70..98fdb47f 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -47,11 +47,11 @@ struct CodeBlock { }; struct CodeObject { - std::shared_ptr src; + shared_ptr src; Str name; bool is_generator = false; - CodeObject(std::shared_ptr src, Str name) { + CodeObject(shared_ptr src, Str name) { this->src = src; this->name = name; } diff --git a/src/compiler.h b/src/compiler.h index 85f7a733..c20cc606 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -35,7 +35,7 @@ public: Compiler(VM* vm, const char* source, Str filename, CompileMode mode){ this->vm = vm; this->parser = std::make_unique( - std::make_shared(source, filename, mode) + make_sp(source, filename, mode) ); // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ @@ -394,7 +394,7 @@ private: _compile_f_args(func, false); consume(TK(":")); } - func.code = std::make_shared(parser->src, func.name.str()); + func.code = make_sp(parser->src, func.name.str()); this->codes.push(func.code); co()->_rvalue += 1; EXPR(); co()->_rvalue -= 1; emit(OP_RETURN_VALUE); @@ -1090,7 +1090,7 @@ private: if(match(TK("->"))){ if(!match(TK("None"))) consume(TK("@id")); } - func.code = std::make_shared(parser->src, func.name.str()); + func.code = make_sp(parser->src, func.name.str()); this->codes.push(func.code); compile_block_body(); func.code->optimize(vm); @@ -1154,7 +1154,7 @@ public: if(used) UNREACHABLE(); used = true; - CodeObject_ code = std::make_shared(parser->src, Str("")); + CodeObject_ code = make_sp(parser->src, Str("")); codes.push(code); lex_token(); lex_token(); diff --git a/src/memory.h b/src/memory.h index 1b4eab16..16e2321c 100644 --- a/src/memory.h +++ b/src/memory.h @@ -4,6 +4,70 @@ namespace pkpy{ +template +struct shared_ptr { + int* counter; + + T* _t() const noexcept { return (T*)(counter + 1); } + void _inc_counter() { if(counter) ++(*counter); } + void _dec_counter() { if(counter && --(*counter) == 0) {((T*)(counter + 1))->~T(); free(counter);} } + +public: + shared_ptr() : counter(nullptr) {} + shared_ptr(int* counter) : counter(counter) {} + shared_ptr(const shared_ptr& other) : counter(other.counter) { + _inc_counter(); + } + shared_ptr(shared_ptr&& other) noexcept : counter(other.counter) { + other.counter = nullptr; + } + ~shared_ptr() { _dec_counter(); } + + bool operator==(const shared_ptr& other) const { return counter == other.counter; } + bool operator!=(const shared_ptr& other) const { return counter != other.counter; } + bool operator<(const shared_ptr& other) const { return counter < other.counter; } + bool operator>(const shared_ptr& other) const { return counter > other.counter; } + bool operator<=(const shared_ptr& other) const { return counter <= other.counter; } + bool operator>=(const shared_ptr& other) const { return counter >= other.counter; } + bool operator==(std::nullptr_t) const { return counter == nullptr; } + bool operator!=(std::nullptr_t) const { return counter != nullptr; } + + shared_ptr& operator=(const shared_ptr& other) { + _dec_counter(); + counter = other.counter; + _inc_counter(); + return *this; + } + + shared_ptr& operator=(shared_ptr&& other) noexcept { + _dec_counter(); + counter = other.counter; + other.counter = nullptr; + return *this; + } + + T& operator*() const { return *_t(); } + T* operator->() const { return _t(); } + T* get() const { return _t(); } + + int use_count() const { + return counter ? *counter : 0; + } + + void reset(){ + _dec_counter(); + counter = nullptr; + } +}; + +template +shared_ptr make_sp(Args&&... args) { + int* p = (int*)malloc(sizeof(int) + sizeof(T)); + *p = 1; + new(p+1) T(std::forward(args)...); + return shared_ptr(p); +} + template struct FreeListA { std::vector buckets[__Bucket+1]; diff --git a/src/obj.h b/src/obj.h index 48d358ee..8abcea95 100644 --- a/src/obj.h +++ b/src/obj.h @@ -13,8 +13,8 @@ struct BaseRef; class VM; typedef std::function NativeFuncRaw; -typedef std::shared_ptr CodeObject_; -typedef std::shared_ptr NameDict_; +typedef shared_ptr CodeObject_; +typedef shared_ptr NameDict_; struct NativeFunc { NativeFuncRaw f; diff --git a/src/parser.h b/src/parser.h index fd281c6c..da36b888 100644 --- a/src/parser.h +++ b/src/parser.h @@ -95,7 +95,7 @@ enum Precedence { // The context of the parsing phase for the compiler. struct Parser { - std::shared_ptr src; + shared_ptr src; const char* token_start; const char* curr_char; @@ -290,7 +290,7 @@ struct Parser { else set_next_token(one); } - Parser(std::shared_ptr src) { + Parser(shared_ptr src) { this->src = src; this->token_start = src->source; this->curr_char = src->source; diff --git a/src/vm.h b/src/vm.h index 75413e71..686d9056 100644 --- a/src/vm.h +++ b/src/vm.h @@ -737,7 +737,7 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo return f(this, args); } else if(is_type(callable, tp_function)){ const Function& fn = CAST(Function&, callable); - NameDict_ locals = std::make_shared( + NameDict_ locals = make_sp( fn.code->perfect_locals_capacity, kLocalsLoadFactor, fn.code->perfect_hash_seed