1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_ExpHeap.cpp
4   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law. They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10   $Rev: 25911 $
11  *---------------------------------------------------------------------------
12 
13 
14 */
15 
16 #include <nn/fnd/fnd_Expheap.h>
17 #include "./detail/fnd_DetailHeap.h"
18 
19 namespace nn { namespace fnd {
20 
HasAddress(const void * addr) const21 bool ExpHeapBase::HasAddress(const void* addr) const
22 {
23     return reinterpret_cast<uptr>(m_ExpHeapImpl.heapStart) <= reinterpret_cast<uptr>(addr)
24        && reinterpret_cast<uptr>(addr) < reinterpret_cast<uptr>(m_ExpHeapImpl.heapEnd);
25 }
26 
27 
Initialize(uptr addr,size_t size,bit32 option)28 void ExpHeapBase::Initialize(uptr addr, size_t size, bit32 option)
29 {
30     // TODO: Use this->m_Option rather than an internal implementation for option
31     nn::fnd::detail::Heap heap = detail::CreateHeap(&m_ExpHeapImpl, reinterpret_cast<void*>(addr), size, option);
32     if (heap == NN_OS_HEAP_INVALID_HANDLE)
33     {
34         NN_PANIC("Failed to detail::CreateHeap");
35     }
36     this->m_AllocCount = 0;
37 }
38 
Finalize()39 void ExpHeapBase::Finalize()
40 {
41     NN_TASSERT_(m_AllocCount == 0);
42     if (m_ExpHeapImpl.signature != 0)
43     {
44         detail::DestroyHeap(&m_ExpHeapImpl);
45         m_ExpHeapImpl.signature = 0;
46     }
47 }
48 
Invalidate()49 void ExpHeapBase::Invalidate()
50 {
51     m_AllocCount = 0;
52     Finalize();
53 }
54 
Allocate(size_t byteSize,s32 alignment,bit8 groupId,AllocationMode mode,bool reuse)55 void* ExpHeapBase::Allocate(size_t byteSize, s32 alignment, bit8 groupId, AllocationMode mode, bool reuse)
56 {
57     detail::SetGroupIDForHeap(&m_ExpHeapImpl, groupId);
58     detail::SetAllocModeForHeap(&m_ExpHeapImpl, mode);
59     detail::UseMarginOfAlignmentForHeap(&m_ExpHeapImpl, reuse);
60     void* memory =  detail::AllocFromHeap(&m_ExpHeapImpl, byteSize, alignment);
61     if(memory != NULL)
62     {
63         ++this->m_AllocCount;
64     }
65     return memory;
66 }
67 
Free(void * p)68 void ExpHeapBase::Free(void* p)
69 {
70     NN_TASSERT_(CheckBlock(p));
71     detail::FreeToHeap(&m_ExpHeapImpl, p);
72     --this->m_AllocCount;
73 }
74 
ResizeBlock(void * p,size_t newSize)75 size_t ExpHeapBase::ResizeBlock(void *p, size_t newSize)
76 {
77     return detail::ResizeForMBlockHeap(&m_ExpHeapImpl, p, newSize);
78 }
79 
80 namespace {
81 
82     struct FuncAndParam {
83         nn::fnd::ExpHeapBase::BlockVisitor f;
84         uptr param;
85         ExpHeapBase* heap;
86     };
87 
VisitFunc(void * p,detail::Heap,u32 param)88     void VisitFunc(void* p, detail::Heap, u32 param)
89     {
90         FuncAndParam& fap = *reinterpret_cast<FuncAndParam*>(param);
91         fap.f(p, fap.heap, fap.param);
92     }
93 
94 }
95 
VisitAllBlocks(nn::fnd::ExpHeapBase::BlockVisitor visitor,uptr param)96 void ExpHeapBase::VisitAllBlocks(nn::fnd::ExpHeapBase::BlockVisitor visitor, uptr param)
97 {
98     // TODO: Optimize this
99     FuncAndParam fap;
100     fap.f = visitor;
101     fap.param = param;
102     fap.heap = this;
103     detail::VisitAllocatedForHeap(&m_ExpHeapImpl, VisitFunc, reinterpret_cast<u32>(&fap));
104 }
105 
GetTotalFreeSize() const106 size_t ExpHeapBase::GetTotalFreeSize() const
107 {
108     return detail::GetTotalFreeSizeForHeap(&m_ExpHeapImpl);
109 }
110 
GetAllocatableSize(s32 alignment) const111 size_t ExpHeapBase::GetAllocatableSize(s32 alignment) const
112 {
113     return detail::GetAllocatableSizeForHeap(&m_ExpHeapImpl, alignment);
114 }
115 
GetSizeOf(const void * p) const116 size_t ExpHeapBase::GetSizeOf(const void* p) const
117 {
118     return detail::GetSizeForMBlockHeap(p);
119 }
120 
GetGroupIdOf(const void * p) const121 bit8 ExpHeapBase::GetGroupIdOf(const void* p) const
122 {
123     return detail::GetGroupIDForMBlockHeap(p);
124 }
125 
GetDirectionOf(const void * p) const126 ExpHeapBase::AllocationDirection ExpHeapBase::GetDirectionOf(const void* p) const
127 {
128     return static_cast<AllocationDirection>(detail::GetAllocDirForMBlockHeap(p));
129 }
130 
Adjust()131 u32 ExpHeapBase::Adjust()
132 {
133     u32 oldsize = ExpHeapBase::GetTotalSize();
134     return oldsize - detail::AdjustHeap(&m_ExpHeapImpl, HEAP_ADJUST_TAIL).GetSize();
135 }
136 
Adjust(HeapAdjustMode mode)137 MemoryRange ExpHeapBase::Adjust(HeapAdjustMode mode)
138 {
139     return detail::AdjustHeap(&m_ExpHeapImpl, mode);
140 }
141 
CheckHeap(bit32 option) const142 bool ExpHeapBase::CheckHeap(bit32 option) const
143 {
144     return detail::CheckHeap(&m_ExpHeapImpl, option);
145 }
146 
CheckBlock(const void * p,bit32 option) const147 bool ExpHeapBase::CheckBlock(const void* p, bit32 option) const
148 {
149     return detail::CheckForMBlockHeap(p, &m_ExpHeapImpl, option);
150 }
151 
GetStartAddress() const152 void* ExpHeapBase::GetStartAddress() const
153 {
154     return GetHeapStartAddress(&m_ExpHeapImpl);
155 }
156 
GetTotalSize() const157 size_t ExpHeapBase::GetTotalSize() const
158 {
159     return GetHeapTotalSize(&m_ExpHeapImpl);
160 }
161 
Dump() const162 void ExpHeapBase::Dump() const
163 {
164 #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
165     detail::NNSi_FndDumpHeap(&m_ExpHeapImpl);
166 #endif
167 }
168 
169 }}
170