mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
parent
3b36673e03
commit
00953e39f4
@ -1 +1 @@
|
||||
1544b2568499a11bfd400f6bb1361e39f9f1022d
|
||||
0db2b02901c5b62cd181d817ba71c3b0d417a40a
|
||||
|
34
repos/ports/src/virtualbox5/patches/rem_mem.patch
Normal file
34
repos/ports/src/virtualbox5/patches/rem_mem.patch
Normal file
@ -0,0 +1,34 @@
|
||||
--- a/src/app/virtualbox/include/iprt/mem.h
|
||||
+++ b/src/app/virtualbox/include/iprt/mem.h
|
||||
@@ -1014,6 +1014,14 @@
|
||||
*/
|
||||
RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_PROTO;
|
||||
|
||||
+/**
|
||||
+ * REM memory allocations must be within 1<<31 window - use specific calls
|
||||
+ */
|
||||
+RTDECL(void *) RTMemTCGAlloc(size_t cb) RT_NO_THROW_PROTO;
|
||||
+RTDECL(void *) RTMemTCGAllocZ(size_t cb) RT_NO_THROW_PROTO;
|
||||
+RTDECL(void *) RTMemTCGRealloc(void *pvOld, size_t cbNew) RT_NO_THROW_PROTO;
|
||||
+RTDECL(void) RTMemTCGFree(void *pv) RT_NO_THROW_PROTO;
|
||||
+
|
||||
/** @} */
|
||||
|
||||
RT_C_DECLS_END
|
||||
--- a/src/app/virtualbox/src/recompiler/osdep.h
|
||||
+++ b/src/app/virtualbox/src/recompiler/osdep.h
|
||||
@@ -21,10 +21,10 @@
|
||||
RTLogPrintfV((pszFormat), (args))
|
||||
|
||||
/**@todo the following macros belongs elsewhere */
|
||||
-#define qemu_malloc(cb) RTMemAlloc(cb)
|
||||
-#define qemu_mallocz(cb) RTMemAllocZ(cb)
|
||||
-#define qemu_realloc(ptr, cb) RTMemRealloc(ptr, cb)
|
||||
-#define qemu_free(pv) RTMemFree(pv)
|
||||
+#define qemu_malloc(cb) RTMemTCGAlloc(cb)
|
||||
+#define qemu_mallocz(cb) RTMemTCGAllocZ(cb)
|
||||
+#define qemu_realloc(ptr, cb) RTMemTCGRealloc(ptr, cb)
|
||||
+#define qemu_free(pv) RTMemTCGFree(pv)
|
||||
#define qemu_strdup(psz) RTStrDup(psz)
|
||||
|
||||
/* Misc wrappers */
|
@ -32,3 +32,4 @@ tm_tpr.patch
|
||||
tm_4s.patch
|
||||
rem_tss.patch
|
||||
mem_leak.patch
|
||||
rem_mem.patch
|
||||
|
@ -14,6 +14,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <util/bit_allocator.h>
|
||||
|
||||
|
||||
/* VirtualBox includes */
|
||||
@ -29,7 +30,7 @@
|
||||
#include "vmm.h"
|
||||
|
||||
enum {
|
||||
MEMORY_MAX = 64 * 1024 * 1024,
|
||||
MEMORY_MAX = 128 * 1024 * 1024,
|
||||
MEMORY_CACHED = 16 * 1024 * 1024,
|
||||
};
|
||||
|
||||
@ -132,6 +133,18 @@ class Avl_ds : public Genode::Avl_node<Avl_ds>
|
||||
: head->find_size(size);
|
||||
}
|
||||
|
||||
static Genode::addr_t max_size_at(void * p)
|
||||
{
|
||||
Avl_ds * ds_obj = Avl_ds::_runtime_ds.first();
|
||||
if (ds_obj)
|
||||
ds_obj = ds_obj->find_virt(reinterpret_cast<Genode::addr_t>(p));
|
||||
|
||||
if (!ds_obj)
|
||||
return 0;
|
||||
|
||||
return ds_obj->_size;
|
||||
}
|
||||
|
||||
Genode::addr_t ds_virt() const { return _virt; }
|
||||
|
||||
static void memory_freeup(Genode::addr_t const cb)
|
||||
@ -273,6 +286,137 @@ void RTMemPageFree(void *pv, size_t cb)
|
||||
Avl_ds::free_memory(pv, cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* The tiny code generator (TCG) of the REM allocates quite a hugh amount
|
||||
* of individal TCG_CACHED_SIZE blocks. Using a dataspace per allocation
|
||||
* increases the cap count significantly (e.g. 9G RAM caused 2500 allocations).
|
||||
* Using a Slab for the known size avoids the cap issue.
|
||||
*/
|
||||
|
||||
enum { TCG_CACHE = 4 * 1024 * 1024, TCG_CACHED_SIZE = 0x4000 };
|
||||
|
||||
typedef Genode::Bit_allocator<TCG_CACHE / TCG_CACHED_SIZE> Tcg_idx_allocator;
|
||||
|
||||
struct Tcg_slab : Genode::List<Tcg_slab>::Element {
|
||||
Tcg_idx_allocator _slots;
|
||||
Genode::addr_t _base { 0 };
|
||||
bool _full { false };
|
||||
|
||||
Tcg_slab(void *memory)
|
||||
: _base(reinterpret_cast<Genode::addr_t>(memory)) { };
|
||||
|
||||
void * alloc()
|
||||
{
|
||||
unsigned idx = _slots.alloc();
|
||||
return reinterpret_cast<void *>(_base + idx * TCG_CACHED_SIZE);
|
||||
}
|
||||
|
||||
Genode::addr_t contains(Genode::addr_t const ptr) const {
|
||||
return _base <= ptr && ptr < _base + TCG_CACHED_SIZE; }
|
||||
};
|
||||
|
||||
static Genode::List<Tcg_slab> list;
|
||||
|
||||
void * RTMemTCGAlloc(size_t cb)
|
||||
{
|
||||
if (cb != TCG_CACHED_SIZE)
|
||||
return alloc_mem(cb, __func__);
|
||||
|
||||
{
|
||||
Genode::Lock::Guard guard(lock_ds);
|
||||
|
||||
for (Tcg_slab * tcg = list.first(); tcg; tcg = tcg->next()) {
|
||||
if (tcg->_full)
|
||||
continue;
|
||||
|
||||
try {
|
||||
return tcg->alloc();
|
||||
} catch (Tcg_idx_allocator::Out_of_indices) {
|
||||
tcg->_full = true;
|
||||
/* try on another slab */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tcg_slab * tcg = new (vmm_heap()) Tcg_slab(alloc_mem(TCG_CACHE, __func__));
|
||||
if (tcg && tcg->_base) {
|
||||
{
|
||||
Genode::Lock::Guard guard(lock_ds);
|
||||
list.insert(tcg);
|
||||
}
|
||||
return RTMemTCGAlloc(cb);
|
||||
}
|
||||
|
||||
Genode::error("no memory left for TCG");
|
||||
|
||||
if (tcg)
|
||||
destroy(vmm_heap(), tcg);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void * RTMemTCGAllocZ(size_t cb)
|
||||
{
|
||||
void * ptr = RTMemTCGAlloc(cb);
|
||||
if (ptr)
|
||||
Genode::memset(ptr, 0, cb);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void RTMemTCGFree(void *pv)
|
||||
{
|
||||
Genode::Lock::Guard guard(lock_ds);
|
||||
|
||||
Genode::addr_t const ptr = reinterpret_cast<Genode::addr_t>(pv);
|
||||
for (Tcg_slab * tcg = list.first(); tcg; tcg = tcg->next()) {
|
||||
if (!tcg->contains(ptr))
|
||||
continue;
|
||||
|
||||
Genode::warning("could not free up TCG memory ", pv);
|
||||
return;
|
||||
}
|
||||
Avl_ds::free_memory(pv, Avl_ds::max_size_at(pv));
|
||||
}
|
||||
|
||||
void * RTMemTCGRealloc(void *ptr, size_t size)
|
||||
{
|
||||
if (!ptr && size)
|
||||
return RTMemTCGAllocZ(size);
|
||||
|
||||
if (!size) {
|
||||
if (ptr)
|
||||
RTMemTCGFree(ptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Genode::addr_t max_size = 0;
|
||||
{
|
||||
Genode::Lock::Guard guard(lock_ds);
|
||||
|
||||
max_size = Avl_ds::max_size_at(ptr);
|
||||
if (!max_size) {
|
||||
Genode::error("bug - unknown pointer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (size <= max_size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void * new_ptr = RTMemTCGAllocZ(size);
|
||||
if (!new_ptr) {
|
||||
Genode::error("no memory left ", size);
|
||||
return nullptr;
|
||||
}
|
||||
Genode::memcpy(new_ptr, ptr, max_size);
|
||||
|
||||
RTMemTCGFree(ptr);
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
#include <iprt/buildconfig.h>
|
||||
|
||||
uint32_t RTBldCfgVersionMajor(void) { return VBOX_VERSION_MAJOR; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user