diff options
author | bunnei <bunneidev@gmail.com> | 2015-07-22 02:08:49 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2015-08-15 23:33:45 +0200 |
commit | ddbeebb887cff61b087a48738650832bc62c9e83 (patch) | |
tree | 130ff470aa19d7cdbdd2a8183ae4fcb12e061fc8 /src/common/code_block.h | |
parent | Common: Ported over Dolphin's code for x86 CPU capability detection. (diff) | |
download | yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar.gz yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar.bz2 yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar.lz yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar.xz yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.tar.zst yuzu-ddbeebb887cff61b087a48738650832bc62c9e83.zip |
Diffstat (limited to 'src/common/code_block.h')
-rw-r--r-- | src/common/code_block.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/common/code_block.h b/src/common/code_block.h new file mode 100644 index 000000000..9ef7296d3 --- /dev/null +++ b/src/common/code_block.h @@ -0,0 +1,87 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "common_types.h" +#include "memory_util.h" + +// Everything that needs to generate code should inherit from this. +// You get memory management for free, plus, you can use all emitter functions without +// having to prefix them with gen-> or something similar. +// Example implementation: +// class JIT : public CodeBlock<ARMXEmitter> {} +template<class T> class CodeBlock : public T, NonCopyable +{ +private: + // A privately used function to set the executable RAM space to something invalid. + // For debugging usefulness it should be used to set the RAM to a host specific breakpoint instruction + virtual void PoisonMemory() = 0; + +protected: + u8 *region; + size_t region_size; + +public: + CodeBlock() : region(nullptr), region_size(0) {} + virtual ~CodeBlock() { if (region) FreeCodeSpace(); } + + // Call this before you generate any code. + void AllocCodeSpace(int size) + { + region_size = size; + region = (u8*)AllocateExecutableMemory(region_size); + T::SetCodePtr(region); + } + + // Always clear code space with breakpoints, so that if someone accidentally executes + // uninitialized, it just breaks into the debugger. + void ClearCodeSpace() + { + PoisonMemory(); + ResetCodePtr(); + } + + // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. + void FreeCodeSpace() + { +#ifdef __SYMBIAN32__ + ResetExecutableMemory(region); +#else + FreeMemoryPages(region, region_size); +#endif + region = nullptr; + region_size = 0; + } + + bool IsInSpace(const u8 *ptr) + { + return (ptr >= region) && (ptr < (region + region_size)); + } + + // Cannot currently be undone. Will write protect the entire code region. + // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). + void WriteProtect() + { + WriteProtectMemory(region, region_size, true); + } + + void ResetCodePtr() + { + T::SetCodePtr(region); + } + + size_t GetSpaceLeft() const + { + return region_size - (T::GetCodePtr() - region); + } + + u8 *GetBasePtr() { + return region; + } + + size_t GetOffset(const u8 *ptr) const { + return ptr - region; + } +}; |