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