add PK_LOW_MEMORY_MODE

This commit is contained in:
blueloveTH 2024-12-31 13:34:37 +08:00
parent 4cf9199c72
commit 93ca8d88f3
5 changed files with 67 additions and 16 deletions

View File

@ -8,6 +8,11 @@
/*************** feature settings ***************/
// Reduce the startup memory usage for embedded systems
#ifndef PK_LOW_MEMORY_MODE // can be overridden by cmake
#define PK_LOW_MEMORY_MODE 0
#endif
// Whether to compile os-related modules or not
#ifndef PK_ENABLE_OS // can be overridden by cmake
#define PK_ENABLE_OS 1
@ -15,8 +20,12 @@
// GC min threshold
#ifndef PK_GC_MIN_THRESHOLD // can be overridden by cmake
#if PK_LOW_MEMORY_MODE
#define PK_GC_MIN_THRESHOLD 2048
#else
#define PK_GC_MIN_THRESHOLD 16384
#endif
#endif
// Memory allocation functions
#ifndef PK_MALLOC
@ -28,8 +37,12 @@
// This is the maximum size of the value stack in py_TValue units
// The actual size in bytes equals `sizeof(py_TValue) * PK_VM_STACK_SIZE`
#ifndef PK_VM_STACK_SIZE // can be overridden by cmake
#if PK_LOW_MEMORY_MODE
#define PK_VM_STACK_SIZE 2048
#else
#define PK_VM_STACK_SIZE 16384
#endif
#endif
// This is the maximum number of local variables in a function
// (not recommended to change this)

View File

@ -11,11 +11,10 @@ py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co,
NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co);
typedef struct ValueStack {
// We allocate extra PK_VM_STACK_SIZE/128 places to keep `_sp` valid when `is_overflow() ==
// true`.
py_TValue* sp;
py_TValue* end;
py_TValue begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE / 128];
// We allocate extra places to keep `_sp` valid to detect stack overflow
py_TValue begin[PK_VM_STACK_SIZE + PK_MAX_CO_VARNAMES * 2];
} ValueStack;
void ValueStack__ctor(ValueStack* self);

View File

@ -100,6 +100,7 @@ void c11_sbuf__write_quoted(c11_sbuf* self, c11_sv sv, char quote) {
case '\b': c11_sbuf__write_cstrn(self, "\\b", 2); break;
default: {
int u8bytes = c11__u8_header(c, true);
if(i + u8bytes > sv.size) u8bytes = 0; // invalid utf8
if(u8bytes <= 1) {
// not a valid utf8 char, or ascii
if(!isprint(c)) {

View File

@ -13,6 +13,14 @@ static bool stack_format_object(VM* self, c11_sv spec);
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
if(self->is_curr_exc_handled) py_clearexc(NULL)
#define CHECK_STACK_OVERFLOW() \
do { \
if(self->stack.sp > self->stack.end) { \
py_exception(tp_StackOverflowError, ""); \
goto __ERROR; \
} \
} while(0)
#define DISPATCH() \
do { \
frame->ip++; \
@ -132,15 +140,40 @@ FrameResult VM__run_top_frame(VM* self) {
POP();
DISPATCH();
/*****************************************/
case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
case OP_LOAD_NONE: py_newnone(SP()++); DISPATCH();
case OP_LOAD_TRUE: py_newbool(SP()++, true); DISPATCH();
case OP_LOAD_FALSE: py_newbool(SP()++, false); DISPATCH();
case OP_LOAD_CONST: {
CHECK_STACK_OVERFLOW();
PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg));
DISPATCH();
}
case OP_LOAD_NONE: {
CHECK_STACK_OVERFLOW();
py_newnone(SP()++);
DISPATCH();
}
case OP_LOAD_TRUE: {
CHECK_STACK_OVERFLOW();
py_newbool(SP()++, true);
DISPATCH();
}
case OP_LOAD_FALSE: {
CHECK_STACK_OVERFLOW();
py_newbool(SP()++, false);
DISPATCH();
}
/*****************************************/
case OP_LOAD_SMALL_INT: py_newint(SP()++, (int16_t)byte.arg); DISPATCH();
case OP_LOAD_SMALL_INT: {
CHECK_STACK_OVERFLOW();
py_newint(SP()++, (int16_t)byte.arg);
DISPATCH();
}
/*****************************************/
case OP_LOAD_ELLIPSIS: py_newellipsis(SP()++); DISPATCH();
case OP_LOAD_ELLIPSIS: {
CHECK_STACK_OVERFLOW();
py_newellipsis(SP()++);
DISPATCH();
}
case OP_LOAD_FUNCTION: {
CHECK_STACK_OVERFLOW();
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
Function__ctor(ud, decl, frame->module);
@ -952,8 +985,12 @@ FrameResult VM__run_top_frame(VM* self) {
goto __ERROR;
}
py_Type type =
pk_newtype(py_name2str(name), base, frame->module, NULL, base_ti->is_python, false);
py_Type type = pk_newtype(py_name2str(name),
base,
frame->module,
NULL,
base_ti->is_python,
false);
PUSH(py_tpobject(type));
self->__curr_class = TOP();
DISPATCH();

View File

@ -1,5 +1,6 @@
#include "pocketpy/interpreter/heap.h"
#include "pocketpy/common/memorypool.h"
#include "pocketpy/config.h"
#include "pocketpy/objects/base.h"
void ManagedHeap__ctor(ManagedHeap* self, VM* vm) {
@ -94,7 +95,7 @@ PyObject* PyObject__new(py_Type type, int slots, int size) {
PyObject* self;
// header + slots + udsize
size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + size;
if(size <= kPoolObjectBlockSize) {
if(!PK_LOW_MEMORY_MODE && size <= kPoolObjectBlockSize) {
self = PoolObject_alloc();
self->gc_is_large = false;
} else {