ctr_Repair/trunk/SkipFirstLaunch/sysHeap.cpp
N2614 57bec8362f MSETのヒープ管理ライブラリを使うように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@665 385bec56-5757-e545-9c3a-d8741f4650f1
2012-03-15 06:26:23 +00:00

276 lines
7.4 KiB
C++

/*!
@file sysHeap.cpp
@brief ヒープ
*/
//#include "sys.h"
#include "sysHeap.h"
#ifndef NW_RELEASE
//#include "sceneManager.h"
#endif
static const size_t scMainHeapSize = 0x800000; // 8MB
static const size_t scSceneHeapSize = 0x200000; // 2MB
static const size_t scDeviceHeapSize = 0x1000000; // 16MB
#ifdef DEBUG_MEMORY
static size_t smSceneHeapSize = 0xffffffff;
static size_t smMainHeapSize = 0xffffffff;
static size_t smDeviceHeapSize = 0xffffffff;
#endif
// デフォルトのStartUp関数を呼ばないようにする
extern "C" void nninitStartUp(void)
{
nn::os::SetDeviceMemorySize(0);
nn::os::SetHeapSize(0);
}
namespace sys
{
#ifndef NW_RELEASE
Mem::MemList Mem::smList;
#endif
Heap Mem::smMainHeap;
Heap Mem::smSceneHeap;
Heap Mem::smDeviceHeap;
/*!
初期化
*/
void Mem::init()
{
NN_LOG("Use Memory Size:0x%x %x\n", nn::os::GetUsingMemorySize(), nn::os::GetAppMemorySize() );
nn::os::SetHeapSize( scMainHeapSize + scSceneHeapSize );
nn::Result result = nn::os::SetDeviceMemorySize( scDeviceHeapSize );
NN_UTIL_PANIC_IF_FAILED( result );
size_t size = nn::os::GetHeapSize();
uptr address = nn::os::GetHeapAddress();
NN_LOG("################# Main Memory : 0x%x - 0x%x #################\n", ( uint )address, ( ( uint )address + size ) );
// メインメモリ初期化
smMainHeap.getHeap()->Initialize( address, scMainHeapSize, nn::os::ALLOCATE_OPTION_LINEAR );
// シーンメモリ初期化
smSceneHeap.getHeap()->Initialize( address + scMainHeapSize, size - scMainHeapSize, nn::os::ALLOCATE_OPTION_LINEAR );
// デバイス用メモリ初期化
smDeviceHeap.getHeap()->Initialize( nn::os::GetDeviceMemoryAddress(), scDeviceHeapSize, nn::os::ALLOCATE_OPTION_LINEAR );
nwosPrintf("################# Device Memory : 0x%x - 0x%x #################\n", nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemoryAddress() + scDeviceHeapSize );
{
s32 memSize = nn::fs::GetRomRequiredMemorySize(
/*ROMFS_MAX_FILE, ROMFS_MAX_DIRECTORY*/128, 128 );
// s32 memSize = 32 * 1024;
u8* fs_buf = new( &smMainHeap ) u8[ memSize ];
bool ret = nn::fs::MountRom(
128,//ROMFS_MAX_FILE,
128,//ROMFS_MAX_DIRECTORY,
fs_buf,
memSize ).IsSuccess();
// NN_LOG("RomFS: mem(%p) size(%d) files(%d) dirs(%d)\n",
// fs_buf, memSize,
// /*ROMFS_MAX_FILE, ROMFS_MAX_DIRECTORY*/128, 128 );
}
#ifndef NW_RELEASE
// デバッグ用SDカードアクセス
nn::fs::MountSdmc();
#endif
}
/*!
終了処理
*/
void Mem::finish()
{
smSceneHeap.getHeap()->Invalidate();
smMainHeap.getHeap()->Invalidate();
smDeviceHeap.getHeap()->Invalidate();
nn::os::SetHeapSize(0);
nn::os::SetDeviceMemorySize(0);
}
void* Mem::AllocDeviceMemory( size_t size, s32 alignment )
{
// 2のべき乗のチェック
NW_ASSERT( (alignment & (alignment - 1)) == 0 );
if ( alignment == 0 ) { alignment = NN_FND_HEAP_DEFAULT_ALIGNMENT; }
void* memory = smDeviceHeap.getHeap()->Allocate( size, alignment );
#ifdef DEBUG_MEMORY
if( smDeviceHeap.getHeap()->GetAllocatableSize() < smDeviceHeapSize )
{
smDeviceHeapSize = smDeviceHeap.getHeap()->GetAllocatableSize();
NN_LOG("DeviceHeap AllocatableSize: 0x%x\n", smDeviceHeapSize );
// sys::Mem::getDeviceHeap()->getHeap()->Dump();
}
#endif
return memory;
}
void* Mem::Alloc( Heap* p_heap, size_t size, s32 alignment )
{
// 2のべき乗のチェック
NW_ASSERT( (alignment & (alignment - 1)) == 0 );
NW_ASSERT( p_heap != &smDeviceHeap );
if( alignment == 0 ) alignment = NN_FND_HEAP_DEFAULT_ALIGNMENT;
if( p_heap == NULL ) p_heap = &smMainHeap;
void* memory = p_heap->getHeap()->Allocate( size, alignment );
#ifndef NW_RELEASE
if( p_heap == &smSceneHeap )
{
NW_ASSERTMSG(memory, "Failed allocate SceneHeap %d/%d", size,
scSceneHeapSize - p_heap->getHeap()->GetTotalSize() );
//SceneMem* mem = new( &smMainHeap ) SceneMem( memory, scene::Manager::getActiveSceneID(), size );
//smList.PushBack( mem );
}
#endif
#ifdef DEBUG_MEMORY
if( p_heap == &smSceneHeap &&
smSceneHeap.getHeap()->GetAllocatableSize() < smSceneHeapSize )
{
smSceneHeapSize = smSceneHeap.getHeap()->GetAllocatableSize();
NN_LOG("SceneHeap AllocatableSize: 0x%x\n", smSceneHeapSize );
// sys::Mem::getSceneHeap()->getHeap()->Dump();
}
if( p_heap == &smMainHeap &&
smMainHeap.getHeap()->GetAllocatableSize() < smMainHeapSize )
{
smMainHeapSize = smMainHeap.getHeap()->GetAllocatableSize();
NN_LOG("MainHeap AllocatableSize: 0x%x\n", smMainHeapSize );
// sys::Mem::getMainHeap()->getHeap()->Dump();
}
#endif
return memory;
}
void Mem::Free( void* memory )
{
if( smDeviceHeap.getHeap()->HasAddress( memory ) )
{
smDeviceHeap.getHeap()->Free( memory );
}
else if( smMainHeap.getHeap()->HasAddress( memory ) )
{
smMainHeap.getHeap()->Free( memory );
}
else
{
smSceneHeap.getHeap()->Free( memory );
#ifndef NW_RELEASE
for( MemList::Iterator it = smList.GetBeginIter(); it != smList.GetEndIter(); ++it )
{
SceneMem* mem = reinterpret_cast< SceneMem* >( &(*it) );
if( mem->getAddress() == memory )
{
smList.Erase( mem );
delete mem;
break;
}
}
#endif
}
}
/*!
シーンヒープに開放忘れがないかチェック
*/
#ifndef NW_RELEASE
bool Mem::checkSceneHeap( int scene_id )
{
bool ret = true;
for( MemList::Iterator it = smList.GetBeginIter(); it != smList.GetEndIter(); ++it )
{
SceneMem* mem = reinterpret_cast< SceneMem* >( &(*it) );
if( mem->getID() == scene_id )
{
NN_LOG("%d Scene Memory Leak!!(size%d) (addr%x)\n", scene_id, mem->getSize(), mem->getAddress() );
ret = false;
}
}
return ret;
}
#endif
}
void* operator new( size_t size, int alignment ) throw()
{
NW_ASSERT( 0 );
return operator new( size, NULL, alignment );
}
void* operator new( size_t size, sys::Heap* p_heap, int alignment ) throw()
{
if( p_heap == sys::Mem::getDeviceHeap() )
{
return sys::Mem::AllocDeviceMemory( size, alignment );
}
return sys::Mem::Alloc( p_heap, size, alignment );
}
void* operator new[]( size_t size, int alignment ) throw()
{
NW_ASSERT( 0 );
return operator new[]( size, NULL, alignment );
}
void* operator new[]( size_t size, const ::std::nothrow_t& ) throw()
{
return operator new[]( size, NULL, NN_FND_HEAP_DEFAULT_ALIGNMENT );
}
void* operator new[]( size_t size, sys::Heap* p_heap, int alignment ) throw()
{
if( p_heap == sys::Mem::getDeviceHeap() )
{
return sys::Mem::AllocDeviceMemory( size, alignment );
}
return sys::Mem::Alloc( p_heap, size, alignment );
}
void operator delete( void* mem_block ) throw()
{
if( mem_block != NULL )
{
sys::Mem::Free( mem_block );
}
}
void operator delete[]( void* mem_block ) throw()
{
if( mem_block != NULL )
{
sys::Mem::Free( mem_block );
}
}