1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_UnitHeap.cpp
4 
5   Copyright (C)2009 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: 35715 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/fnd/fnd_UnitHeap.h>
17 #include <nn/Assert.h>
18 #include <new>
19 
20 namespace nn { namespace fnd {
21 
Initialize(size_t unit,uptr addr,size_t size,s32 alignment,bit32 option)22 void UnitHeapBase::Initialize(size_t unit, uptr addr, size_t size, s32 alignment, bit32 option)
23 {
24     NN_TASSERT_(m_FreeNode == 0);
25     NN_TASSERT_(alignment >= sizeof(void*));
26     NN_TASSERT_(alignment % sizeof(void*) == 0);
27     HeapBase::Initialize(option);
28     this->m_Unit = RoundUp(unit, alignment);
29     this->m_Addr = RoundUp(addr, alignment);
30     this->m_Size = RoundDown(size, unit);
31     this->m_Alignment = alignment;
32     this->m_Count = 0;
33 
34     DebugFillMemory(addr, size, HEAP_FILL_TYPE_NOUSE);
35 
36     Node* freeNode = 0;
37     for (uptr addr2 = m_Addr + m_Size - m_Unit; addr2 >= m_Addr; addr2 -= m_Unit)
38     {
39         reinterpret_cast<Node*>(addr2)->next = freeNode;
40         freeNode = reinterpret_cast<Node*>(addr2);
41     }
42     NN_TASSERT_(reinterpret_cast<uptr>(freeNode) == m_Addr);
43     this->m_FreeNode = freeNode;
44 }
45 
GetRequiredHeapSize(size_t unit,size_t numUnit,s32 alignment)46 size_t UnitHeapBase::GetRequiredHeapSize(size_t unit, size_t numUnit, s32 alignment)
47 {
48     return RoundUp(unit, alignment) * numUnit;
49 }
50 
IsFreeNode(uptr addr) const51 bool UnitHeapBase::IsFreeNode(uptr addr) const
52 {
53     if(this->m_FreeNode == NULL)
54     {
55         return false;
56     }
57     else
58     {
59         Node* pNode = this->m_FreeNode;
60         while( pNode != NULL )
61         {
62             if(reinterpret_cast<uptr>(pNode) == addr)
63             {
64                 return true;
65             }
66             pNode = pNode->next;
67         }
68     }
69 
70     return false;
71 }
72 
Dump() const73 void UnitHeapBase::Dump() const
74 {
75 #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
76 
77     NN_TLOG_("     address(from - to):     size\n");   // ヘッダー行
78 
79     // ---------------- UsedBlock のダンプ ----------------
80     NN_TLOG_("    (Used Nodes)\n" );
81     if(this->m_Count == 0)
82     {
83         NN_TLOG_("    NONE\n");
84     }
85     else
86     {
87         for( int i = 0; i < m_Size / m_Unit; i++ )
88         {
89             uptr start = this->m_Addr + m_Unit * i;
90             if(! IsFreeNode(start))
91             {
92                 NN_TLOG_("    %08x - %08x: %8d\n",
93                     start, start + this->m_Unit, this->m_Unit);
94             }
95         }
96     }
97 
98     // ---------------- FreeBlock のダンプ ----------------
99     NN_TLOG_("    (Free Nodes)\n" );
100     if(this->m_FreeNode == NULL)
101     {
102         NN_TLOG_("    NONE\n");
103     }
104     else
105     {
106         Node* pNode = this->m_FreeNode;
107         while(pNode != NULL)
108         {
109             uptr start = reinterpret_cast<uptr>(pNode);
110             NN_TLOG_("    %08x - %08x: %8d\n",
111                 start, start + this->m_Unit, this->m_Unit);
112             pNode = pNode->next;
113         }
114     }
115 
116     u32 usedSize = this->m_Unit * this->m_Count;
117     NN_TLOG_("\n");
118     NN_TLOG_("    %d / %d bytes (%d%%) used\n",
119         usedSize, this->m_Size, 100 * usedSize / this->m_Size);
120     NN_TLOG_("\n");
121 
122 #endif
123 }
124 
125 }}
126