1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     init_Alloc.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: 20442 $
14  *---------------------------------------------------------------------------*/
15 
16 //---------------------------------------------------------------------------
17 
18 #include <new>
19 #include <nn/Result.h>
20 #include <nn/config.h>
21 #include <nn/assert.h>
22 #include <nn/fnd/fnd_ExpHeap.h>
23 #include <nn/init/init_Allocator.h>
24 #include <nn/os/os_LockPolicy.h>
25 #include <nn/os/os_Memory.h>
26 #include <nn/os/os_MemoryMapSelect.h>
27 #include <nn/os/os_CriticalSection.h>
28 #include <nn/svc/svc_stub.h>
29 #include <nn/util/util_Result.h>
30 #include <nn/util/util_TypeTraits.h>
31 
32 using namespace nn::os;
33 
34 typedef nn::fnd::ExpHeapTemplate<nn::os::LockPolicy::Object<nn::os::CriticalSection> > SystemExpHeap;
35 
36 namespace
37 {
38     SystemExpHeap*              s_pSystemHeap = 0;       //!< システムヒープ
39     nn::util::aligned_storage<sizeof(SystemExpHeap::Allocator), nn::util::alignment_of<SystemExpHeap::Allocator>::value >::type s_SystemAllocatorBuffer;
40     SystemExpHeap::Allocator*   s_pSystemAllocator = 0;  //<! システムヒープ用アロケータ
41 
42 #if NN_PLATFORM_HAS_MMU
43     nnosMemoryBlock s_HeapMemoryBlock;
44 #endif  // if NN_PLATFORM_HAS_MMU
45 }
46 
47 extern "C"{
48 
49 // ABI のオーバーライド
malloc(size_t size)50 NN_WEAK_SYMBOL void* malloc(size_t size)
51 {
52     return s_pSystemHeap->Allocate(size);
53 }
54 
55 // ABI のオーバーライド
free(void * p)56 NN_WEAK_SYMBOL void free(void* p)
57 {
58     if (p)
59     {
60         s_pSystemHeap->Free(p);
61     }
62 }
63 
64 } // extern "C"
65 
66 
operator new(size_t size,const::std::nothrow_t &)67 NN_WEAK_SYMBOL void* operator new (size_t size, const ::std::nothrow_t&) throw()
68 {
69     return malloc(size);
70 }
71 
operator new[](size_t size,const::std::nothrow_t &)72 NN_WEAK_SYMBOL void* operator new[] (size_t size, const ::std::nothrow_t&) throw()
73 {
74     return operator new(size, ::std::nothrow_t());
75 }
76 
operator delete(void * p)77 NN_WEAK_SYMBOL void operator delete (void* p) throw()
78 {
79     free(p);
80 }
81 
operator delete[](void * p)82 NN_WEAK_SYMBOL void operator delete[] (void* p) throw()
83 {
84     operator delete(p);
85 }
86 
87 //NN_WEAK_SYMBOL void operator delete (void* p, const ::std::nothrow_t&) throw()
88 //{
89 //    if( p != 0 )
90 //    {
91 //        free(p);
92 //    }
93 //}
94 
95 //NN_WEAK_SYMBOL void operator delete[] (void* p, const ::std::nothrow_t&) throw()
96 //{
97 //    if( p != 0 )
98 //    {
99 //        free(p);
100 //    }
101 //}
102 
103 namespace nn { namespace init {
104 
105 // 注意
106 // この周辺の関数は initStartup から呼ばれるものがある。
107 // initStartup は static initializer 以前に呼ばれる関数のため、
108 // この周辺の関数で non-POD クラスの static オブジェクトを初期化すると、
109 // static initializer で再初期化されてしまい、正常に動作しない。
110 // aligned_storage + placement new で実装すること。
111 
112 // システムヒープを作成
InitializeAllocator(uptr addr,size_t size)113 void InitializeAllocator(uptr addr, size_t size)
114 {
115     NN_TASSERT_(size >= sizeof(SystemExpHeap));
116     const size_t alignment = nn::util::alignment_of<SystemExpHeap>::value;
117     uptr heapAddr = (((addr - 1) / alignment) + 1) * alignment;
118     uptr headAddr = heapAddr + sizeof(SystemExpHeap);
119     s_pSystemHeap = new (reinterpret_cast<void*>(heapAddr)) SystemExpHeap(headAddr, addr + size - headAddr);
120     s_pSystemAllocator = new (&s_SystemAllocatorBuffer) SystemExpHeap::Allocator(*s_pSystemHeap);
121 }
122 
123 #if NN_PLATFORM_HAS_MMU
InitializeAllocator(size_t size)124 void InitializeAllocator(size_t size)
125 {
126     nnosMemoryBlockAllocate(&s_HeapMemoryBlock, size);
127     NN_TASSERT_(nnosMemoryBlockGetSize(&s_HeapMemoryBlock) == size);
128     InitializeAllocator(nnosMemoryBlockGetAddress(&s_HeapMemoryBlock), size);
129 }
130 #endif  // if NN_PLATFORM_HAS_MMU
131 
GetAllocator(void)132 nn::fnd::IAllocator* GetAllocator(void)
133 {
134     return s_pSystemAllocator;
135 }
136 
137 }} // namespace nn::init
138 
139