moved CallRegisteredLuaMemHook into a header so that it doesn't slow down release fastbuild quite so much
This commit is contained in:
parent
e6c0897328
commit
91ced7c47f
|
@ -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<unsigned int maxGap>
|
|
||||||
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<Island> islands;
|
|
||||||
|
|
||||||
void Calculate(const std::vector<unsigned int>& bytes)
|
|
||||||
{
|
|
||||||
islands.clear();
|
|
||||||
|
|
||||||
unsigned int lastEnd = ~0;
|
|
||||||
|
|
||||||
std::vector<unsigned int>::const_iterator iter = bytes.begin();
|
|
||||||
std::vector<unsigned int>::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<Island>::const_iterator iter = islands.begin();
|
|
||||||
std::vector<Island>::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<unsigned int>& bytes)
|
|
||||||
{
|
|
||||||
std::sort(bytes.begin(), bytes.end());
|
|
||||||
|
|
||||||
broad.Calculate(bytes);
|
|
||||||
mid.Calculate(bytes);
|
|
||||||
narrow.Calculate(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
TieredRegion()
|
|
||||||
{
|
|
||||||
Calculate(std::vector<unsigned int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
__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];
|
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<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin();
|
std::map<int, LuaContextInfo*>::iterator iter = luaContextInfo.begin();
|
||||||
std::map<int, LuaContextInfo*>::iterator end = luaContextInfo.end();
|
std::map<int, LuaContextInfo*>::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()
|
bool AnyLuaActive()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef LUA_SCRIPT_H
|
#ifndef LUA_SCRIPT_H
|
||||||
#define 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 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);
|
void RunLuaScriptFile(int uid, const char* filename);
|
||||||
|
@ -92,5 +93,112 @@ void DontWorryLua();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// 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<unsigned int maxGap>
|
||||||
|
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<Island> islands;
|
||||||
|
|
||||||
|
void Calculate(const std::vector<unsigned int>& bytes)
|
||||||
|
{
|
||||||
|
islands.clear();
|
||||||
|
|
||||||
|
unsigned int lastEnd = ~0;
|
||||||
|
|
||||||
|
std::vector<unsigned int>::const_iterator iter = bytes.begin();
|
||||||
|
std::vector<unsigned int>::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<Island>::const_iterator iter = islands.begin();
|
||||||
|
std::vector<Island>::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<unsigned int>& bytes)
|
||||||
|
{
|
||||||
|
std::sort(bytes.begin(), bytes.end());
|
||||||
|
|
||||||
|
broad.Calculate(bytes);
|
||||||
|
mid.Calculate(bytes);
|
||||||
|
narrow.Calculate(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
TieredRegion()
|
||||||
|
{
|
||||||
|
Calculate(std::vector<unsigned int>());
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue