From 615fcc621dcf823a25f104d97097f3bd7270ba12 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 21 Mar 2017 18:10:25 +0000 Subject: CodeBlock: Add support for multiple children --- Source/Core/Common/CodeBlock.h | 53 ++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'Source/Core/Common/CodeBlock.h') diff --git a/Source/Core/Common/CodeBlock.h b/Source/Core/Common/CodeBlock.h index 28a4919e66..9eb1732ec7 100644 --- a/Source/Core/Common/CodeBlock.h +++ b/Source/Core/Common/CodeBlock.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "Common/Assert.h" #include "Common/CommonTypes.h" @@ -27,12 +28,13 @@ private: protected: u8* region = nullptr; + // Size of region we can use. size_t region_size = 0; - size_t parent_region_size = 0; + // Original size of the region we allocated. + size_t total_region_size = 0; - bool m_has_child = false; bool m_is_child = false; - CodeBlock* m_child = nullptr; + std::vector m_children; public: virtual ~CodeBlock() @@ -45,7 +47,8 @@ public: virtual void AllocCodeSpace(size_t size, bool need_low = true) { region_size = size; - region = static_cast(Common::AllocateExecutableMemory(region_size, need_low)); + total_region_size = size; + region = static_cast(Common::AllocateExecutableMemory(total_region_size, need_low)); T::SetCodePtr(region); } @@ -60,14 +63,16 @@ public: // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. void FreeCodeSpace() { - Common::FreeMemoryPages(region, region_size); + _assert_(!m_is_child); + Common::FreeMemoryPages(region, total_region_size); region = nullptr; region_size = 0; - parent_region_size = 0; - if (m_has_child) + total_region_size = 0; + for (CodeBlock* child : m_children) { - m_child->region = nullptr; - m_child->region_size = 0; + child->region = nullptr; + child->region_size = 0; + child->total_region_size = 0; } } @@ -78,7 +83,8 @@ public: void ResetCodePtr() { T::SetCodePtr(region); } size_t GetSpaceLeft() const { - return (m_has_child ? parent_region_size : region_size) - (T::GetCodePtr() - region); + _assert_(static_cast(T::GetCodePtr() - region) < region_size); + return region_size - (T::GetCodePtr() - region); } bool IsAlmostFull() const @@ -86,16 +92,23 @@ public: // This should be bigger than the biggest block ever. return GetSpaceLeft() < 0x10000; } - void AddChildCodeSpace(CodeBlock* child, size_t size) + + bool HasChildren() const { return region_size != total_region_size; } + u8* AllocChildCodeSpace(size_t child_size) + { + _assert_msg_(DYNA_REG, child_size < GetSpaceLeft(), "Insufficient space for child allocation."); + u8* child_region = region + region_size - child_size; + region_size -= child_size; + return child_region; + } + void AddChildCodeSpace(CodeBlock* child, size_t child_size) { - _assert_msg_(DYNA_REC, !m_has_child, "Already have a child! Can't have another!"); - m_child = child; - m_has_child = true; - m_child->m_is_child = true; - u8* child_region = region + region_size - size; - m_child->region = child_region; - m_child->region_size = size; - m_child->ResetCodePtr(); - parent_region_size = region_size - size; + u8* child_region = AllocChildCodeSpace(child_size); + child->m_is_child = true; + child->region = child_region; + child->region_size = child_size; + child->total_region_size = child_size; + child->ResetCodePtr(); + m_children.emplace_back(child); } }; -- cgit v1.2.3 From da434e1a1cf1afb17945a38b5fce7c022e8a8dae Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 21 Mar 2017 18:37:48 +0000 Subject: ConstantPool: Externalize memory allocation --- Source/Core/Common/CodeBlock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/Common/CodeBlock.h') diff --git a/Source/Core/Common/CodeBlock.h b/Source/Core/Common/CodeBlock.h index 9eb1732ec7..9c3da1058b 100644 --- a/Source/Core/Common/CodeBlock.h +++ b/Source/Core/Common/CodeBlock.h @@ -44,7 +44,7 @@ public: } // Call this before you generate any code. - virtual void AllocCodeSpace(size_t size, bool need_low = true) + void AllocCodeSpace(size_t size, bool need_low = true) { region_size = size; total_region_size = size; @@ -54,7 +54,7 @@ public: // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. - virtual void ClearCodeSpace() + void ClearCodeSpace() { PoisonMemory(); ResetCodePtr(); -- cgit v1.2.3