From 91ced7c47f98dbb3071cea0ba05bb9e1b1edeaab Mon Sep 17 00:00:00 2001 From: nitsuja Date: Thu, 15 Oct 2009 06:34:41 +0000 Subject: [PATCH] moved CallRegisteredLuaMemHook into a header so that it doesn't slow down release fastbuild quite so much --- desmume/src/lua-engine.cpp | 100 +--------------------------------- desmume/src/lua-engine.h | 108 +++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 99 deletions(-) diff --git a/desmume/src/lua-engine.cpp b/desmume/src/lua-engine.cpp index 15b675626..7252c5f56 100644 --- a/desmume/src/lua-engine.cpp +++ b/desmume/src/lua-engine.cpp @@ -4851,89 +4851,6 @@ void CloseLuaContext(int uid) } -// the purpose of this structure is to provide a way of -// QUICKLY determining whether a memory address range has a hook associated with it, -// with a bias toward fast rejection because the majority of addresses will not be hooked. -// (it must not use any part of Lua or perform any per-script operations, -// otherwise it would definitely be too slow.) -// calculating the regions when a hook is added/removed may be slow, -// but this is an intentional tradeoff to obtain a high speed of checking during later execution -struct TieredRegion -{ - template - struct Region - { - struct Island - { - unsigned int start; - unsigned int end; - __forceinline bool Contains(unsigned int address, int size) const { return address < end && address+size > start; } - }; - std::vector islands; - - void Calculate(const std::vector& bytes) - { - islands.clear(); - - unsigned int lastEnd = ~0; - - std::vector::const_iterator iter = bytes.begin(); - std::vector::const_iterator end = bytes.end(); - for(; iter != end; ++iter) - { - unsigned int addr = *iter; - if(addr < lastEnd || addr > lastEnd + (long long)maxGap) - { - islands.push_back(Island()); - islands.back().start = addr; - } - islands.back().end = addr+1; - lastEnd = addr+1; - } - } - - bool Contains(unsigned int address, int size) const - { - std::vector::const_iterator iter = islands.begin(); - std::vector::const_iterator end = islands.end(); - for(; iter != end; ++iter) - if(iter->Contains(address, size)) - return true; - return false; - } - }; - - Region<0xFFFFFFFF> broad; - Region<0x1000> mid; - Region<0> narrow; - - void Calculate(std::vector& bytes) - { - std::sort(bytes.begin(), bytes.end()); - - broad.Calculate(bytes); - mid.Calculate(bytes); - narrow.Calculate(bytes); - } - - TieredRegion() - { - Calculate(std::vector()); - } - - __forceinline int NotEmpty() - { - return broad.islands.size(); - } - - // note: it is illegal to call this if NotEmpty() returns 0 - __forceinline bool Contains(unsigned int address, int size) - { - return broad.islands[0].Contains(address,size) && - mid.Contains(address,size) && - narrow.Contains(address,size); - } -}; TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; @@ -4979,7 +4896,7 @@ static void CalculateMemHookRegions(LuaMemHookType hookType) -static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) +void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) { std::map::iterator iter = luaContextInfo.begin(); std::map::iterator end = luaContextInfo.end(); @@ -5030,21 +4947,6 @@ static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, un } } -void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) -{ - // performance critical! (called VERY frequently) - // I suggest timing a large number of calls to this function in Release if you change anything in here, - // before and after, because even the most innocent change can make it become 30% to 400% slower. - // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. - // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter case) - if(hookedRegions[hookType].NotEmpty()) - { - //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) - // address |= 0xFF0000; // gens: account for mirroring of RAM - if(hookedRegions[hookType].Contains(address, size)) - CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this specific address - } -} bool AnyLuaActive() { diff --git a/desmume/src/lua-engine.h b/desmume/src/lua-engine.h index cfddd827a..d9db3b4ae 100644 --- a/desmume/src/lua-engine.h +++ b/desmume/src/lua-engine.h @@ -1,6 +1,7 @@ #ifndef LUA_SCRIPT_H #define LUA_SCRIPT_H +#include "types.h" void OpenLuaContext(int uid, void(*print)(int uid, const char* str) = 0, void(*onstart)(int uid) = 0, void(*onstop)(int uid, bool statusOK) = 0); void RunLuaScriptFile(int uid, const char* filename); @@ -92,5 +93,112 @@ void DontWorryLua(); +#include +#include + +// the purpose of this structure is to provide a way of +// QUICKLY determining whether a memory address range has a hook associated with it, +// with a bias toward fast rejection because the majority of addresses will not be hooked. +// (it must not use any part of Lua or perform any per-script operations, +// otherwise it would definitely be too slow.) +// calculating the regions when a hook is added/removed may be slow, +// but this is an intentional tradeoff to obtain a high speed of checking during later execution +struct TieredRegion +{ + template + struct Region + { + struct Island + { + unsigned int start; + unsigned int end; + FORCEINLINE bool Contains(unsigned int address, int size) const { return address < end && address+size > start; } + }; + std::vector islands; + + void Calculate(const std::vector& bytes) + { + islands.clear(); + + unsigned int lastEnd = ~0; + + std::vector::const_iterator iter = bytes.begin(); + std::vector::const_iterator end = bytes.end(); + for(; iter != end; ++iter) + { + unsigned int addr = *iter; + if(addr < lastEnd || addr > lastEnd + (long long)maxGap) + { + islands.push_back(Island()); + islands.back().start = addr; + } + islands.back().end = addr+1; + lastEnd = addr+1; + } + } + + bool Contains(unsigned int address, int size) const + { + std::vector::const_iterator iter = islands.begin(); + std::vector::const_iterator end = islands.end(); + for(; iter != end; ++iter) + if(iter->Contains(address, size)) + return true; + return false; + } + }; + + Region<0xFFFFFFFF> broad; + Region<0x1000> mid; + Region<0> narrow; + + void Calculate(std::vector& bytes) + { + std::sort(bytes.begin(), bytes.end()); + + broad.Calculate(bytes); + mid.Calculate(bytes); + narrow.Calculate(bytes); + } + + TieredRegion() + { + Calculate(std::vector()); + } + + FORCEINLINE int NotEmpty() + { + return broad.islands.size(); + } + + // note: it is illegal to call this if NotEmpty() returns 0 + FORCEINLINE bool Contains(unsigned int address, int size) + { + return broad.islands[0].Contains(address,size) && + mid.Contains(address,size) && + narrow.Contains(address,size); + } +}; +extern TieredRegion hookedRegions [LUAMEMHOOK_COUNT]; + +void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, unsigned int value, LuaMemHookType hookType); + +FORCEINLINE void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType) +{ + // performance critical! (called VERY frequently) + // I suggest timing a large number of calls to this function in Release if you change anything in here, + // before and after, because even the most innocent change can make it become 30% to 400% slower. + // a good amount to test is: 100000000 calls with no hook set, and another 100000000 with a hook set. + // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter case) + if(hookedRegions[hookType].NotEmpty()) + { + //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) + // address |= 0xFF0000; // gens: account for mirroring of RAM + if(hookedRegions[hookType].Contains(address, size)) + CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this specific address + } +} + + #endif