1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_ExpHeap.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46347 $
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