mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Potential very hacky workaround for arm64 JIT allocation issues.
Try to reserve blocks of executable memory before external library code claims the address space. LuaJIT on arm64 currently has a very limited range of memory it can use for JIT code.
This commit is contained in:
@@ -1849,6 +1849,7 @@
|
|||||||
FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = "<group>"; };
|
FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = "<group>"; };
|
||||||
FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = "<group>"; };
|
FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = "<group>"; };
|
||||||
FA665DC321C34C900074BBD6 /* wrap_GraphicsShader.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_GraphicsShader.lua; sourceTree = "<group>"; };
|
FA665DC321C34C900074BBD6 /* wrap_GraphicsShader.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_GraphicsShader.lua; sourceTree = "<group>"; };
|
||||||
|
FA69B918273828DD00CDC2E7 /* jitsetup.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = jitsetup.lua; sourceTree = "<group>"; };
|
||||||
FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = "<group>"; };
|
FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = "<group>"; };
|
||||||
FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = "<group>"; };
|
FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = "<group>"; };
|
||||||
FA6A2B681F5F7F560074C308 /* DataView.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataView.cpp; sourceTree = "<group>"; };
|
FA6A2B681F5F7F560074C308 /* DataView.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataView.cpp; sourceTree = "<group>"; };
|
||||||
@@ -2966,6 +2967,7 @@
|
|||||||
FA1E95B4271F932B0044CF08 /* arg.lua */,
|
FA1E95B4271F932B0044CF08 /* arg.lua */,
|
||||||
FA577A8D16C71D3600860150 /* boot.lua */,
|
FA577A8D16C71D3600860150 /* boot.lua */,
|
||||||
FA1E95B5271F932B0044CF08 /* callbacks.lua */,
|
FA1E95B5271F932B0044CF08 /* callbacks.lua */,
|
||||||
|
FA69B918273828DD00CDC2E7 /* jitsetup.lua */,
|
||||||
FA0B7BFE1A95902C000E1D17 /* love.cpp */,
|
FA0B7BFE1A95902C000E1D17 /* love.cpp */,
|
||||||
FA0B7BFF1A95902C000E1D17 /* love.h */,
|
FA0B7BFF1A95902C000E1D17 /* love.h */,
|
||||||
);
|
);
|
||||||
|
|||||||
+16
-8
@@ -142,14 +142,6 @@ enum DoneAction
|
|||||||
|
|
||||||
static DoneAction runlove(int argc, char **argv, int &retval)
|
static DoneAction runlove(int argc, char **argv, int &retval)
|
||||||
{
|
{
|
||||||
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
|
|
||||||
int hack_argc = 0;
|
|
||||||
char **hack_argv = 0;
|
|
||||||
get_app_arguments(argc, argv, hack_argc, hack_argv);
|
|
||||||
argc = hack_argc;
|
|
||||||
argv = hack_argv;
|
|
||||||
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
|
|
||||||
|
|
||||||
// Oh, you just want the version? Okay!
|
// Oh, you just want the version? Okay!
|
||||||
if (argc > 1 && strcmp(argv[1], "--version") == 0)
|
if (argc > 1 && strcmp(argv[1], "--version") == 0)
|
||||||
{
|
{
|
||||||
@@ -166,6 +158,22 @@ static DoneAction runlove(int argc, char **argv, int &retval)
|
|||||||
lua_State *L = luaL_newstate();
|
lua_State *L = luaL_newstate();
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
|
|
||||||
|
// LuaJIT-specific setup needs to be done as early as possible - before
|
||||||
|
// get_app_arguments because that loads external library code. This is also
|
||||||
|
// loaded inside require("love"). Note that it doesn't use the love table.
|
||||||
|
love_preload(L, luaopen_love_jitsetup, "love.jitsetup");
|
||||||
|
lua_getglobal(L, "require");
|
||||||
|
lua_pushstring(L, "love.jitsetup");
|
||||||
|
lua_call(L, 1, 0);
|
||||||
|
|
||||||
|
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
|
||||||
|
int hack_argc = 0;
|
||||||
|
char **hack_argv = nullptr;
|
||||||
|
get_app_arguments(argc, argv, hack_argc, hack_argv);
|
||||||
|
argc = hack_argc;
|
||||||
|
argv = hack_argv;
|
||||||
|
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
|
||||||
|
|
||||||
// Add love to package.preload for easy requiring.
|
// Add love to package.preload for easy requiring.
|
||||||
love_preload(L, luaopen_love, "love");
|
love_preload(L, luaopen_love, "love");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
R"luastring"--(
|
||||||
|
-- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string.
|
||||||
|
-- There is a matching delimiter at the bottom of the file.
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Copyright (c) 2006-2021 LOVE Development Team
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
if type(jit) ~= "table" or not jit.status() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Double the defaults.
|
||||||
|
jit.opt.start("maxtrace=2000", "maxrecord=8000")
|
||||||
|
|
||||||
|
-- Somewhat arbitrary value. Needs to be higher than the combined sizes below,
|
||||||
|
-- and higher than the default (512) because that's already too low.
|
||||||
|
jit.opt.start("maxmcode=16384")
|
||||||
|
|
||||||
|
if jit.arch == "arm64" then
|
||||||
|
-- https://github.com/LuaJIT/LuaJIT/issues/285
|
||||||
|
-- LuaJIT 2.1 on arm64 currently (as of commit b4b2dce) can only use memory
|
||||||
|
-- for JIT compilation within a certain short range. Other libraries such as
|
||||||
|
-- SDL can take all the usable space in that range and cause attempts at JIT
|
||||||
|
-- compilation to both fail and take a long time.
|
||||||
|
-- This is a very hacky attempt at a workaround. LuaJIT allocates executable
|
||||||
|
-- code in pools. We'll try "reserving" pools before any external code is
|
||||||
|
-- executed, by causing JIT compilation via a small loop. We can't easily
|
||||||
|
-- tell if JIT compilation succeeded, so we do several successively smaller
|
||||||
|
-- pool allocations in case previous ones fail.
|
||||||
|
-- This is a really hacky hack and by no means foolproof - there are a lot of
|
||||||
|
-- potential situations (especially when threads are used) where previously
|
||||||
|
-- executed external code will still take up space that LuaJIT needed for itself.
|
||||||
|
|
||||||
|
jit.opt.start("sizemcode=2048")
|
||||||
|
for i=1, 100 do end
|
||||||
|
|
||||||
|
jit.opt.start("sizemcode=1024")
|
||||||
|
for i=1, 100 do end
|
||||||
|
|
||||||
|
jit.opt.start("sizemcode=512")
|
||||||
|
for i=1, 100 do end
|
||||||
|
|
||||||
|
jit.opt.start("sizemcode=256")
|
||||||
|
for i=1, 100 do end
|
||||||
|
|
||||||
|
jit.opt.start("sizemcode=128")
|
||||||
|
for i=1, 100 do end
|
||||||
|
else
|
||||||
|
-- Somewhat arbitrary value (>= the default).
|
||||||
|
jit.opt.start("sizemcode=128")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string.
|
||||||
|
--)luastring"--"
|
||||||
@@ -97,6 +97,10 @@ static const char boot_lua[] =
|
|||||||
#include "boot.lua"
|
#include "boot.lua"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
static const char jit_setup_lua[] =
|
||||||
|
#include "jitsetup.lua"
|
||||||
|
;
|
||||||
|
|
||||||
// All modules define a c-accessible luaopen
|
// All modules define a c-accessible luaopen
|
||||||
// so let's make use of those, instead
|
// so let's make use of those, instead
|
||||||
// of addressing implementations directly.
|
// of addressing implementations directly.
|
||||||
@@ -160,6 +164,7 @@ extern "C"
|
|||||||
extern int luaopen_love_window(lua_State*);
|
extern int luaopen_love_window(lua_State*);
|
||||||
#endif
|
#endif
|
||||||
extern int luaopen_love_nogame(lua_State*);
|
extern int luaopen_love_nogame(lua_State*);
|
||||||
|
extern int luaopen_love_jitsetup(lua_State*);
|
||||||
extern int luaopen_love_arg(lua_State*);
|
extern int luaopen_love_arg(lua_State*);
|
||||||
extern int luaopen_love_callbacks(lua_State*);
|
extern int luaopen_love_callbacks(lua_State*);
|
||||||
extern int luaopen_love_boot(lua_State*);
|
extern int luaopen_love_boot(lua_State*);
|
||||||
@@ -224,6 +229,7 @@ static const luaL_Reg modules[] = {
|
|||||||
{ "love.window", luaopen_love_window },
|
{ "love.window", luaopen_love_window },
|
||||||
#endif
|
#endif
|
||||||
{ "love.nogame", luaopen_love_nogame },
|
{ "love.nogame", luaopen_love_nogame },
|
||||||
|
{ "love.jitsetup", luaopen_love_jitsetup },
|
||||||
{ "love.arg", luaopen_love_arg },
|
{ "love.arg", luaopen_love_arg },
|
||||||
{ "love.callbacks", luaopen_love_callbacks },
|
{ "love.callbacks", luaopen_love_callbacks },
|
||||||
{ "love.boot", luaopen_love_boot },
|
{ "love.boot", luaopen_love_boot },
|
||||||
@@ -404,6 +410,15 @@ static void luax_addcompatibilityalias(lua_State *L, const char *module, const c
|
|||||||
|
|
||||||
int luaopen_love(lua_State *L)
|
int luaopen_love(lua_State *L)
|
||||||
{
|
{
|
||||||
|
// Preload module loaders.
|
||||||
|
for (int i = 0; modules[i].name != nullptr; i++)
|
||||||
|
love::luax_preload(L, modules[i].func, modules[i].name);
|
||||||
|
|
||||||
|
// jitsetup is also loaded in the love executable runlove function. It's
|
||||||
|
// needed here too for threads. Note that it doesn't use the love table.
|
||||||
|
love::luax_require(L, "love.jitsetup");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
love::luax_insistpinnedthread(L);
|
love::luax_insistpinnedthread(L);
|
||||||
|
|
||||||
love::luax_insistglobal(L, "love");
|
love::luax_insistglobal(L, "love");
|
||||||
@@ -501,10 +516,6 @@ int luaopen_love(lua_State *L)
|
|||||||
lua_setfield(L, -2, "hasDeprecationOutput");
|
lua_setfield(L, -2, "hasDeprecationOutput");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preload module loaders.
|
|
||||||
for (int i = 0; modules[i].name != nullptr; i++)
|
|
||||||
love::luax_preload(L, modules[i].func, modules[i].name);
|
|
||||||
|
|
||||||
// Necessary for Data-creating methods to work properly in Data subclasses.
|
// Necessary for Data-creating methods to work properly in Data subclasses.
|
||||||
love::luax_require(L, "love.data");
|
love::luax_require(L, "love.data");
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@@ -657,6 +668,14 @@ int luaopen_love_nogame(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int luaopen_love_jitsetup(lua_State *L)
|
||||||
|
{
|
||||||
|
if (luaL_loadbuffer(L, jit_setup_lua, sizeof(jit_setup_lua), "jitsetup.lua") == 0)
|
||||||
|
lua_call(L, 0, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int luaopen_love_arg(lua_State *L)
|
int luaopen_love_arg(lua_State *L)
|
||||||
{
|
{
|
||||||
if (luaL_loadbuffer(L, arg_lua, sizeof(arg_lua), "arg.lua") == 0)
|
if (luaL_loadbuffer(L, arg_lua, sizeof(arg_lua), "arg.lua") == 0)
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ LOVE_EXPORT const char *love_version();
|
|||||||
LOVE_EXPORT const char *love_codename();
|
LOVE_EXPORT const char *love_codename();
|
||||||
LOVE_EXPORT int luaopen_love(lua_State *L);
|
LOVE_EXPORT int luaopen_love(lua_State *L);
|
||||||
LOVE_EXPORT int luaopen_love_nogame(lua_State *L);
|
LOVE_EXPORT int luaopen_love_nogame(lua_State *L);
|
||||||
|
LOVE_EXPORT int luaopen_love_jitsetup(lua_State *L);
|
||||||
|
LOVE_EXPORT int luaopen_love_arg(lua_State *L);
|
||||||
|
LOVE_EXPORT int luaopen_love_callbacks(lua_State *L);
|
||||||
LOVE_EXPORT int luaopen_love_boot(lua_State *L);
|
LOVE_EXPORT int luaopen_love_boot(lua_State *L);
|
||||||
|
|
||||||
#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
|
#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
|
||||||
|
|||||||
Reference in New Issue
Block a user