// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** drccache.h Universal dynamic recompiler cache management. ***************************************************************************/ #pragma once #ifndef __DRCCACHE_H__ #define __DRCCACHE_H__ //************************************************************************** // MACROS //************************************************************************** // ensure that a given pointer is within the cache boundaries #define assert_in_cache(c,p) assert((c).contains_pointer(p)) #define assert_in_near_cache(c,p) assert((c).contains_near_pointer(p)) //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // generic code pointer typedef uint8_t *drccodeptr; // helper template for oob codegen typedef delegate drc_oob_delegate; // drc_cache class drc_cache { public: // construction/destruction drc_cache(size_t bytes); ~drc_cache(); // getters drccodeptr near() const { return m_near; } drccodeptr base() const { return m_base; } drccodeptr top() const { return m_top; } // pointer checking bool contains_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_near + m_size); } bool contains_near_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_neartop); } bool generating_code() const { return (m_codegen != nullptr); } // memory management void flush(); void *alloc(size_t bytes); void *alloc_near(size_t bytes); void *alloc_temporary(size_t bytes); void dealloc(void *memory, size_t bytes); // codegen helpers drccodeptr *begin_codegen(uint32_t reserve_bytes); drccodeptr end_codegen(); void request_oob_codegen(drc_oob_delegate callback, void *param1 = nullptr, void *param2 = nullptr); private: // largest block of code that can be generated at once static const size_t CODEGEN_MAX_BYTES = 131072; // minimum alignment, in bytes (must be power of 2) static const size_t CACHE_ALIGNMENT = alignof(std::max_align_t); // largest permanent allocation we allow static const size_t MAX_PERMANENT_ALLOC = 1024; // size of "near" area at the base of the cache static const size_t NEAR_CACHE_SIZE = 131072; // core parameters drccodeptr m_near; // pointer to the near part of the cache drccodeptr m_neartop; // top of the near part of the cache drccodeptr m_base; // base pointer to the compiler cache drccodeptr m_top; // current top of cache drccodeptr m_end; // end of cache memory drccodeptr m_codegen; // start of generated code size_t m_size; // size of the cache in bytes // oob management struct oob_handler { oob_handler *next() const { return m_next; } oob_handler * m_next; // next handler drc_oob_delegate m_callback; // callback function void * m_param1; // 1st pointer parameter void * m_param2; // 2nd pointer parameter }; simple_list m_ooblist; // list of oob handlers // free lists struct free_link { free_link * m_next; // pointer to the next guy }; free_link * m_free[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT]; free_link * m_nearfree[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT]; }; #endif /* __DRCCACHE_H__ */