From 0a03f20f910fc3121c40561d9e72b90ad991bb00 Mon Sep 17 00:00:00 2001 From: asmodai Date: Tue, 18 Oct 2016 02:56:58 +0300 Subject: [PATCH] Branch prediction optimization #3 Cleanup --- reapi/src/hook_callback.cpp | 19 ++++++------- reapi/src/hook_callback.h | 4 +-- reapi/src/hook_list.h | 5 ++++ reapi/src/natives/natives_hookchains.cpp | 8 +++--- reapi/src/precompiled.h | 27 ++++++++++-------- reapi/src/reapi_utils.h | 35 ++++++++++++++++++------ 6 files changed, 63 insertions(+), 35 deletions(-) diff --git a/reapi/src/hook_callback.cpp b/reapi/src/hook_callback.cpp index 99897ae6..c8bb77bd 100644 --- a/reapi/src/hook_callback.cpp +++ b/reapi/src/hook_callback.cpp @@ -275,8 +275,7 @@ CBasePlayer *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer { auto original = [chain](int _pthis, int _iPlayerIndex, bool _bSameTeam) { - auto pPlayer = chain->callNext(getPrivate(_pthis), _iPlayerIndex, _bSameTeam); - return pPlayer ? indexOfEdict(pPlayer->pev) : 0; + return indexOfPDataAmx(chain->callNext(getPrivate(_pthis), _iPlayerIndex, _bSameTeam)); }; return getPrivate(callForward(RG_CBasePlayer_Observer_IsValidTarget, original, indexOfEdict(pthis->pev), iPlayerIndex, bSameTeam)); @@ -526,24 +525,24 @@ void CSGameRules_ClientUserInfoChanged(IReGameHook_CSGameRules_ClientUserInfoCha callVoidForward(RG_CSGameRules_ClientUserInfoChanged, original, indexOfEdict(pPlayer->pev), infobuffer); } -void CSGameRules_PlayerKilled(IReGameHook_CSGameRules_PlayerKilled *chain, CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor) +void CSGameRules_PlayerKilled(IReGameHook_CSGameRules_PlayerKilled *chain, CBasePlayer *pVictim, entvars_t *pevKiller, entvars_t *pevInflictor) { - auto original = [chain](int _pVictim, int _pKiller, int _pInflictor) + auto original = [chain](int _pVictim, int _pevKiller, int _pevInflictor) { - chain->callNext(getPrivate(_pVictim), PEV(_pKiller), PEV(_pInflictor)); + chain->callNext(getPrivate(_pVictim), PEV(_pevKiller), PEV(_pevInflictor)); }; - callVoidForward(RG_CSGameRules_PlayerKilled, original, indexOfEdict(pVictim->pev), indexOfEdict(pKiller), pInflictor ? indexOfEdict(pInflictor) : -1); + callVoidForward(RG_CSGameRules_PlayerKilled, original, indexOfEdict(pVictim->pev), indexOfEdict(pevKiller), indexOfEdictAmx(pevInflictor)); } -void CSGameRules_DeathNotice(IReGameHook_CSGameRules_DeathNotice *chain, CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor) +void CSGameRules_DeathNotice(IReGameHook_CSGameRules_DeathNotice *chain, CBasePlayer *pVictim, entvars_t *pevKiller, entvars_t *pevInflictor) { - auto original = [chain](int _pVictim, int _pKiller, int _pevInflictor) + auto original = [chain](int _pVictim, int _pevKiller, int _pevInflictor) { - chain->callNext(getPrivate(_pVictim), PEV(_pKiller), PEV(_pevInflictor)); + chain->callNext(getPrivate(_pVictim), PEV(_pevKiller), PEV(_pevInflictor)); }; - callVoidForward(RG_CSGameRules_DeathNotice, original, indexOfEdict(pVictim->pev), indexOfEdict(pKiller), pevInflictor ? indexOfEdict(pevInflictor) : -1); + callVoidForward(RG_CSGameRules_DeathNotice, original, indexOfEdict(pVictim->pev), indexOfEdict(pevKiller), indexOfEdictAmx(pevInflictor)); } int CSGameRules_CanHavePlayerItem(IReGameHook_CSGameRules_CanHavePlayerItem *chain, CBasePlayer *pPlayer, CBasePlayerItem *pItem) diff --git a/reapi/src/hook_callback.h b/reapi/src/hook_callback.h index 7ea99903..2c5fc27d 100644 --- a/reapi/src/hook_callback.h +++ b/reapi/src/hook_callback.h @@ -338,8 +338,8 @@ void CSGameRules_PlayerSpawn(IReGameHook_CSGameRules_PlayerSpawn *chain, CBasePl BOOL CSGameRules_FPlayerCanRespawn(IReGameHook_CSGameRules_FPlayerCanRespawn *chain, CBasePlayer *pPlayer); edict_t *CSGameRules_GetPlayerSpawnSpot(IReGameHook_CSGameRules_GetPlayerSpawnSpot *chain, CBasePlayer *pPlayer); void CSGameRules_ClientUserInfoChanged(IReGameHook_CSGameRules_ClientUserInfoChanged *chain, CBasePlayer *pPlayer, char *infobuffer); -void CSGameRules_PlayerKilled(IReGameHook_CSGameRules_PlayerKilled *chain, CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor); -void CSGameRules_DeathNotice(IReGameHook_CSGameRules_DeathNotice *chain, CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor); +void CSGameRules_PlayerKilled(IReGameHook_CSGameRules_PlayerKilled *chain, CBasePlayer *pVictim, entvars_t *pevKiller, entvars_t *pevInflictor); +void CSGameRules_DeathNotice(IReGameHook_CSGameRules_DeathNotice *chain, CBasePlayer *pVictim, entvars_t *pevKiller, entvars_t *pevInflictor); int CSGameRules_CanHavePlayerItem(IReGameHook_CSGameRules_CanHavePlayerItem *chain, CBasePlayer *pPlayer, CBasePlayerItem *pItem); int CSGameRules_DeadPlayerWeapons(IReGameHook_CSGameRules_DeadPlayerWeapons *chain, CBasePlayer *pPlayer); void CSGameRules_ServerDeactivate(IReGameHook_CSGameRules_ServerDeactivate *chain); diff --git a/reapi/src/hook_list.h b/reapi/src/hook_list.h index fa529f98..5772cbbb 100644 --- a/reapi/src/hook_list.h +++ b/reapi/src/hook_list.h @@ -31,6 +31,11 @@ extern hook_t hooklist_animating[]; extern hook_t hooklist_player[]; extern hook_t hooklist_gamerules[]; +enum +{ + INVALID_HOOKCHAIN = 0 +}; + struct hooklist_t { hook_t *operator[](size_t hook) const diff --git a/reapi/src/natives/natives_hookchains.cpp b/reapi/src/natives/natives_hookchains.cpp index c2ccaa7c..1ff2a578 100644 --- a/reapi/src/natives/natives_hookchains.cpp +++ b/reapi/src/natives/natives_hookchains.cpp @@ -22,13 +22,13 @@ cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) if (unlikely(hook == nullptr)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: function with id (%d) doesn't exist in current API version.", __FUNCTION__, func); - return 0; + return INVALID_HOOKCHAIN; } if (unlikely(!hook->checkRequirements())) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: function (%s) is not available, %s required.", __FUNCTION__, hook->func_name, hook->depend_name); - return 0; + return INVALID_HOOKCHAIN; } int funcid; @@ -36,14 +36,14 @@ cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); - return 0; + return INVALID_HOOKCHAIN; } int fwid = hook->registerForward(amx, funcname); if (unlikely(fwid == -1)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: register forward failed.", __FUNCTION__); - return 0; + return INVALID_HOOKCHAIN; } return g_hookManager.addHandler(amx, func, fwid, post != 0); diff --git a/reapi/src/precompiled.h b/reapi/src/precompiled.h index 75efa094..a00321f0 100644 --- a/reapi/src/precompiled.h +++ b/reapi/src/precompiled.h @@ -1,47 +1,51 @@ #pragma once +// C #include #include #include #include #include // for strncpy(), etc + +// C++ #include // std::vector +// platform defs +#include + +// cssdk #include #include -#include #include #include -#include #include #include +#include -#include // win32 vsnprintf, etc -#include -#include -#include +// metamod SDK +#include // regamedll API -#include "gamerules.h" -#include "regamedll_api.h" +#include #include "mod_regamedll_api.h" // rehlds API -#include "rehlds_api.h" +#include #include "mod_rehlds_api.h" // VTC API -#include "vtc_api.h" +#include #include "mod_vtc_api.h" // Reunion API -#include "reunion_api.h" +#include #include "mod_reunion_api.h" // AmxModX API #include "amxxmodule.h" +// reapi main #include "main.h" #include "reapi_utils.h" #include "api_config.h" @@ -49,6 +53,7 @@ #include "hook_callback.h" #include "member_list.h" +// natives #include "natives_hookchains.h" #include "natives_members.h" #include "natives_misc.h" diff --git a/reapi/src/reapi_utils.h b/reapi/src/reapi_utils.h index c8564d2c..28ada432 100644 --- a/reapi/src/reapi_utils.h +++ b/reapi/src/reapi_utils.h @@ -6,6 +6,7 @@ char(&ArraySizeHelper(T(&array)[N]))[N]; #define INDEXENT edictByIndex #define ENTINDEX indexOfEdict +#define AMX_NULLENT -1 extern enginefuncs_t* g_pengfuncsTable; extern DLL_FUNCTIONS *g_pFunctionTable; @@ -35,13 +36,13 @@ inline size_t indexOfEdict(entvars_t* pev) return indexOfEdict(pev->pContainingEntity); } -// safe to index -1 -inline edict_t* edictByIndexAmx(int index) +// safe to nullptr +inline size_t indexOfEdictAmx(entvars_t* pev) { - auto ed = g_pEdicts + index; - if (unlikely(index < 0)) - ed = nullptr; - return ed; + size_t index = AMX_NULLENT; + if (likely(pev != nullptr)) + index = indexOfEdict(pev); + return index; } // fast @@ -50,11 +51,20 @@ inline edict_t* edictByIndex(int index) return g_pEdicts + index; } +// safe to index -1 +inline edict_t* edictByIndexAmx(int index) +{ + auto ed = g_pEdicts + index; + if (unlikely(index < 0)) // == AMX_NULLENT + ed = nullptr; + return ed; +} + template inline T* getPrivate(int index) { T* pdata = nullptr; - if (likely(index >= 0)) + if (likely(index >= 0)) // != AMX_NULLENT pdata = (T *)g_pEdicts[index].pvPrivateData; return pdata; } @@ -62,11 +72,20 @@ inline T* getPrivate(int index) inline entvars_t* PEV(int index) { entvars_t* pvars = nullptr; - if (likely(index >= 0)) + if (likely(index >= 0)) // != AMX_NULLENT pvars = &g_pEdicts[index].v; return pvars; } +template +inline size_t indexOfPDataAmx(T* pdata) +{ + size_t index = AMX_NULLENT; + if (likely(pdata != nullptr)) + index = indexOfEdict(pdata->pev); + return index; +} + // HLTypeConversion.h -> AMXModX template inline T &ref_member(void *ptr, int offset, int element = 0)