diff --git a/docs/retype.yml b/docs/retype.yml index e5063e0a..e4f41e54 100644 --- a/docs/retype.yml +++ b/docs/retype.yml @@ -3,7 +3,7 @@ output: .retype url: https://pocketpy.dev branding: title: pocketpy - label: v2.0.8 + label: v2.0.9 logo: "./static/logo.png" favicon: "./static/logo.png" meta: diff --git a/include/pocketpy/config.h b/include/pocketpy/config.h index 8b033e90..43af92a5 100644 --- a/include/pocketpy/config.h +++ b/include/pocketpy/config.h @@ -1,10 +1,10 @@ #pragma once // clang-format off -#define PK_VERSION "2.0.8" +#define PK_VERSION "2.0.9" #define PK_VERSION_MAJOR 2 #define PK_VERSION_MINOR 0 -#define PK_VERSION_PATCH 8 +#define PK_VERSION_PATCH 9 /*************** feature settings ***************/ // Whether to compile os-related modules or not diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 5a7ab101..188850f1 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -63,6 +63,7 @@ typedef struct Ctx { bool is_compiling_class; c11_vector /*T=Expr* */ s_expr; c11_smallmap_n2i global_names; + c11_smallmap_s2n co_consts_string_dedup_map; } Ctx; typedef struct Expr Expr; @@ -1080,6 +1081,7 @@ static void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) { self->is_compiling_class = false; c11_vector__ctor(&self->s_expr, sizeof(Expr*)); c11_smallmap_n2i__ctor(&self->global_names); + c11_smallmap_s2n__ctor(&self->co_consts_string_dedup_map); } static void Ctx__dtor(Ctx* self) { @@ -1089,6 +1091,12 @@ static void Ctx__dtor(Ctx* self) { } c11_vector__dtor(&self->s_expr); c11_smallmap_n2i__dtor(&self->global_names); + // free the dedup map + c11__foreach(c11_smallmap_s2n_KV, &self->co_consts_string_dedup_map, p_kv) { + const char* p = p_kv->key.data; + PK_FREE((void*)p); + } + c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map); } static int Ctx__prepare_loop_divert(Ctx* self, int line, bool is_break) { @@ -1198,10 +1206,28 @@ static int Ctx__add_varname(Ctx* self, py_Name name) { } static int Ctx__add_const_string(Ctx* self, c11_sv key) { - py_Ref p = c11_vector__emplace(&self->co->consts); - py_newstrv(p, key); - int index = self->co->consts.length - 1; - return index; + if(key.size > 100) { + py_Ref tmp = c11_vector__emplace(&self->co->consts); + py_newstrv(tmp, key); + int index = self->co->consts.length - 1; + return index; + } + uint16_t* val = c11_smallmap_s2n__try_get(&self->co_consts_string_dedup_map, key); + if(val) { + return *val; + } else { + py_Ref tmp = c11_vector__emplace(&self->co->consts); + py_newstrv(tmp, key); + int index = self->co->consts.length - 1; + // dedup + char* new_buf = PK_MALLOC(key.size + 1); + memcpy(new_buf, key.data, key.size); + new_buf[key.size] = 0; + c11_smallmap_s2n__set(&self->co_consts_string_dedup_map, + (c11_sv){new_buf, key.size}, + index); + return index; + } } static int Ctx__add_const(Ctx* self, py_Ref v) { diff --git a/src/interpreter/heap.c b/src/interpreter/heap.c index e3bd1631..37b1d2ff 100644 --- a/src/interpreter/heap.c +++ b/src/interpreter/heap.c @@ -44,7 +44,7 @@ void ManagedHeap__collect_if_needed(ManagedHeap* self) { const int lower = PK_GC_MIN_THRESHOLD / 2; float free_ratio = (float)avg_freed / self->gc_threshold; int new_threshold = self->gc_threshold * (1 / free_ratio); - printf("gc_threshold=%d, avg_freed=%d, new_threshold=%d\n", self->gc_threshold, avg_freed, new_threshold); + // printf("gc_threshold=%d, avg_freed=%d, new_threshold=%d\n", self->gc_threshold, avg_freed, new_threshold); self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper); }