From ad7258f68ce525845508fc0c4a329c282982ffa0 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Wed, 9 Aug 2023 12:15:54 +0200 Subject: new .internal_allocator configuration IUNTESTED) new configuration option .internal_allocator to help LuaJIT users. THIS IS YET UNTESTED, USE AT YOUR OWN RISKS. --- src/deep.c | 2 +- src/keeper.c | 20 ++++---------------- src/keeper.h | 2 +- src/lanes.c | 16 +++------------- src/lanes.h | 2 +- src/lanes.lua | 8 +++++++- src/linda.c | 14 ++------------ src/macros_and_utils.h | 3 --- src/tools.c | 38 +++++++++++++++++++++++++++++++++----- src/universe.h | 2 ++ 10 files changed, 54 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/deep.c b/src/deep.c index c475dc5..9496477 100644 --- a/src/deep.c +++ b/src/deep.c @@ -389,7 +389,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_) DeepPrelude* prelude = idfunc( L, eDO_new); if( prelude == NULL) { - luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); + return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); } if( prelude->magic.value != DEEP_VERSION.value) { diff --git a/src/keeper.c b/src/keeper.c index 19b9e1a..f4dde0a 100644 --- a/src/keeper.c +++ b/src/keeper.c @@ -580,7 +580,7 @@ int keepercall_count( lua_State* L) */ // called as __gc for the keepers array userdata -void close_keepers( Universe* U, lua_State* L) +void close_keepers( Universe* U) { if( U->keepers != NULL) { @@ -611,15 +611,8 @@ void close_keepers( Universe* U, lua_State* L) } // free the keeper bookkeeping structure { - // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if USE_LUA_STATE_ALLOCATOR() - { - AllocatorDefinition* const allocD = &U->protected_allocator.definition; - allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); - } -#else // USE_LUA_STATE_ALLOCATOR() - free(U->keepers); -#endif // USE_LUA_STATE_ALLOCATOR() + AllocatorDefinition* const allocD = &U->internal_allocator; + allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); U->keepers = NULL; } } @@ -653,15 +646,10 @@ void init_keepers( Universe* U, lua_State* L) // Keepers contains an array of 1 s_Keeper, adjust for the actual number of keeper states { size_t const bytes = sizeof( Keepers) + (nb_keepers - 1) * sizeof( Keeper); - // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if USE_LUA_STATE_ALLOCATOR() { - AllocatorDefinition* const allocD = &U->protected_allocator.definition; + AllocatorDefinition* const allocD = &U->internal_allocator; U->keepers = (Keepers*) allocD->allocF( allocD->allocUD, NULL, 0, bytes); } -#else // USE_LUA_STATE_ALLOCATOR() - U->keepers = (Keepers*)malloc(bytes); -#endif // USE_LUA_STATE_ALLOCATOR() if( U->keepers == NULL) { (void) luaL_error( L, "init_keepers() failed while creating keeper array; out of memory"); diff --git a/src/keeper.h b/src/keeper.h index 8c09322..d30aa36 100644 --- a/src/keeper.h +++ b/src/keeper.h @@ -27,7 +27,7 @@ struct s_Keepers typedef struct s_Keepers Keepers; void init_keepers( Universe* U, lua_State* L); -void close_keepers( Universe* U, lua_State* L); +void close_keepers( Universe* U); Keeper* which_keeper( Keepers* keepers_, ptrdiff_t magic_); Keeper* keeper_acquire( Keepers* keepers_, ptrdiff_t magic_); diff --git a/src/lanes.c b/src/lanes.c index 9f6a4d6..0aab244 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -253,15 +253,10 @@ static void lane_cleanup( Lane* s) } #endif // HAVE_LANE_TRACKING() - // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if USE_LUA_STATE_ALLOCATOR() { - AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; + AllocatorDefinition* const allocD = &s->U->internal_allocator; allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); } -#else // USE_LUA_STATE_ALLOCATOR() - free(s); -#endif // USE_LUA_STATE_ALLOCATOR() } /* @@ -584,7 +579,7 @@ static int selfdestruct_gc( lua_State* L) U->timer_deep = NULL; } - close_keepers( U, L); + close_keepers( U); // remove the protected allocator, if any cleanup_allocator_function( U, L); @@ -1231,15 +1226,10 @@ LUAG_FUNC( lane_new) // // a Lane full userdata needs a single uservalue ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane - // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if USE_LUA_STATE_ALLOCATOR() { - AllocatorDefinition* const allocD = &U->protected_allocator.definition; + AllocatorDefinition* const allocD = &U->internal_allocator; s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); } -#else // USE_LUA_STATE_ALLOCATOR() - s = *ud = (Lane*) malloc(sizeof(Lane)); -#endif // USE_LUA_STATE_ALLOCATOR() if( s == NULL) { return luaL_error( L, "could not create lane: out of memory"); diff --git a/src/lanes.h b/src/lanes.h index 20524e6..420b31d 100644 --- a/src/lanes.h +++ b/src/lanes.h @@ -12,7 +12,7 @@ #define LANES_VERSION_MAJOR 3 #define LANES_VERSION_MINOR 16 -#define LANES_VERSION_PATCH 0 +#define LANES_VERSION_PATCH 1 #define LANES_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR>MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR>MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH>=PATCH)))) #define LANES_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJORprotected_allocator.definition; + AllocatorDefinition* const allocD = &U->internal_allocator; s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included } -#else // USE_LUA_STATE_ALLOCATOR() - s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included -#endif // USE_LUA_STATE_ALLOCATOR() if( s) { s->prelude.magic.value = DEEP_VERSION.value; @@ -837,17 +832,12 @@ static void* linda_id( lua_State* L, DeepOp op_) // There aren't any lanes waiting on these lindas, since all proxies have been gc'ed. Right? SIGNAL_FREE( &linda->read_happened); SIGNAL_FREE( &linda->write_happened); - // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if USE_LUA_STATE_ALLOCATOR() { Universe* const U = universe_get(L); - AllocatorDefinition* const allocD = &U->protected_allocator.definition; + AllocatorDefinition* const allocD = &U->internal_allocator; allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); } -#else // USE_LUA_STATE_ALLOCATOR() - free(linda); -#endif // USE_LUA_STATE_ALLOCATOR() return NULL; } diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 3ed234a..05a46b5 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -99,7 +99,4 @@ extern char const* debugspew_indent; #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) -// after all, it looks like we can use the state allocator for our own usage when running LuaJIT, as long as we mutex-protect it -#define USE_LUA_STATE_ALLOCATOR() 1 // (LUAJIT_FLAVOR()==0) - #endif // MACROS_AND_UTILS_H diff --git a/src/tools.c b/src/tools.c index 626da2b..5a6ae92 100644 --- a/src/tools.c +++ b/src/tools.c @@ -155,6 +155,20 @@ void luaG_dump( lua_State* L) // ################################################################################################ +static void* libc_lua_Alloc(void* ud, void* ptr, size_t osize, size_t nsize) +{ + (void)ud; (void)osize; /* not used */ + if (nsize == 0) + { + free(ptr); + return NULL; + } + else + { + return realloc(ptr, nsize); + } +} + static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsize) { void* p; @@ -217,6 +231,22 @@ void initialize_allocator_function( Universe* U, lua_State* L) U->protected_allocator.definition.allocF = lua_getallocf( L, &U->protected_allocator.definition.allocUD); } lua_pop( L, 1); // settings + STACK_MID(L, 0); + + lua_getfield( L, -1, "internal_allocator"); // settings "libc"|"allocator" + { + char const* allocator = lua_tostring( L, -1); + if (stricmp(allocator, "libc") == 0) + { + U->internal_allocator.allocF = libc_lua_Alloc; + U->internal_allocator.allocUD = NULL; + } + else + { + U->internal_allocator = U->protected_allocator.definition; + } + } + lua_pop( L, 1); // settings STACK_END( L, 0); } @@ -1337,17 +1367,17 @@ static void copy_cached_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua if( lua_isnil( L2, -1)) // function is unknown { - lua_pop( L2, 1); // ... {cache} ... p + lua_pop( L2, 1); // ... {cache} ... p // Set to 'true' for the duration of creation; need to find self-references // via upvalues // // pushes a copy of the func, stores a reference in the cache - copy_func( U, L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function + copy_func( U, L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function } else // found function in the cache { - lua_remove( L2, -2); // ... {cache} ... function + lua_remove( L2, -2); // ... {cache} ... function } STACK_END( L2, 1); ASSERT_L( lua_isfunction( L2, -1)); @@ -1725,9 +1755,7 @@ static bool_t inter_copy_function( Universe* U, lua_State* L2, uint_t L2_cache_i { DEBUGSPEW_CODE( fprintf( stderr, "FUNCTION %s\n", upName_)); DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); - STACK_CHECK( L2, 0); copy_cached_func( U, L2, L2_cache_i, L, source_i_, mode_, upName_); // ... f - STACK_END( L2, 1); DEBUGSPEW_CODE( -- U->debugspew_indent_depth); } STACK_END( L2, 1); diff --git a/src/universe.h b/src/universe.h index ba00e87..03c78cf 100644 --- a/src/universe.h +++ b/src/universe.h @@ -63,6 +63,8 @@ struct s_Universe // contains a mutex and the original allocator definition ProtectedAllocator protected_allocator; + AllocatorDefinition internal_allocator; + Keepers* keepers; // Initialized by 'init_once_LOCKED()': the deep userdata Linda object -- cgit v1.2.3-55-g6feb