blob: 01adaafd981addbc7dc5d93af867f733e9754656 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
drccache.h
Universal dynamic recompiler cache management.
***************************************************************************/
#ifndef MAME_CPU_DRCCACHE_H
#define MAME_CPU_DRCCACHE_H
#pragma once
#include "modules/lib/osdlib.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<void (drccodeptr *, void *, void *)> 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
void codegen_init();
void codegen_complete();
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 constexpr size_t CODEGEN_MAX_BYTES = 131072;
// minimum alignment, in bytes (must be power of 2)
static constexpr size_t CACHE_ALIGNMENT = alignof(std::max_align_t);
// largest permanent allocation we allow
static constexpr size_t MAX_PERMANENT_ALLOC = 1024;
// size of "near" area at the base of the cache
static constexpr size_t NEAR_CACHE_SIZE = 131072;
osd::virtual_memory_allocation m_cache;
// core parameters
drccodeptr const m_near; // pointer to the near part of the cache
drccodeptr m_neartop; // unallocated area of near cache
drccodeptr const m_base; // end of near cache
drccodeptr m_top; // end of temporary allocations and code
drccodeptr m_limit; // limit for temporary allocations and code (page-aligned)
drccodeptr m_end; // first allocated byte in cache
drccodeptr m_codegen; // start of current generated code block
size_t const m_size; // size of the cache in bytes
bool m_executable; // whether cached code is currently executable
bool m_rwx; // whether pages can be simultaneously writable and executable
// oob management
struct oob_handler
{
drc_oob_delegate m_callback; // callback function
void * m_param1; // 1st pointer parameter
void * m_param2; // 2nd pointer parameter
};
std::list<oob_handler> m_oob_list; // list of active oob handlers
std::list<oob_handler> m_oob_free; // list of recyclable 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 // MAME_CPU_DRCCACHE_H
|