2014-12-13 00:57:06 +08:00
|
|
|
/****************************************************************************
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2014-12-13 00:57:06 +08:00
|
|
|
Author: Justin Graham (https://github.com/mannewalis)
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-03-24 15:13:05 +08:00
|
|
|
#ifndef CC_ALLOCATOR_STRATEGY_GLOBAL_SMALL_BLOCK_H
|
|
|
|
#define CC_ALLOCATOR_STRATEGY_GLOBAL_SMALL_BLOCK_H
|
2015-03-24 20:23:51 +08:00
|
|
|
/// @cond DO_NOT_SHOW
|
2015-03-24 15:13:05 +08:00
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
/****************************************************************************
|
2014-12-14 02:40:45 +08:00
|
|
|
WARNING!
|
|
|
|
Do not use Console::log or any other methods that use NEW inside of this
|
|
|
|
allocator. Failure to do so will result in recursive memory allocation.
|
2014-12-13 00:57:06 +08:00
|
|
|
****************************************************************************/
|
Bug in mp3reader.cpp (#18476)
* Bug in mp3reader.cpp
This directive #include <string.h> is used for memset(b, c, l).
Without it the attemt to install .apk (ex. cocos run . -p android --android-studio) is creshed.
Found in the downloaded from http://cocos2d-x.org/download version cocos2d-x-3.16
* #include <string.h> added to avoid crash
The directive #include <string.h> is used for memset(b, c, l).
Without it the attempt to install .apk (ex. cocos run . -p android --android-studio) is crashed.
Found in the downloaded from http://cocos2d-x.org/download version cocos2d-x-3.16:
Here part of log:
In file included from C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorGlobalNewDelete.cpp:27:0:
C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorStrategyGlobalSmallBlock.h: In constructor 'cocos2d::allocator::AllocatorStrategyGlobalSmallBlock::AllocatorStrategyGlobalSmallBlock()':
C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorStrategyGlobalSmallBlock.h:96:75: error: 'memset' was not declared in this scope
memset(_smallBlockAllocators, 0, sizeof(_smallBlockAllocators));
^
make: *** [C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/runtime-src/proj.android-studio/app/build/intermediates/ndkBuild/debug/obj/local/x86/objs-debug/cocos2dx_internal_static/base/allocator/CCAllocatorGlobalNewDelete.o] Error 1
make: *** Waiting for unfinished jobs....
:TestAndroidGame2:externalNativeBuildDebug (Thread[Task worker for ':',5,main]) completed. Took 16.425 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':TestAndroidGame2:externalNativeBuildDebug'.
> Build command failed.
Error while executing process F:\android-ndk-r16\ndk-build.cmd with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Users\Vadim\Documents\Cocos2d\TestAndroidGame2\frameworks\runtime-src\proj.android-studio\app\jni\Android.mk NDK_APPLICATION_MK=C:\Users\Vadim\Documents\Cocos2d\TestAndroidGame2\frameworks\runtime-src\proj.android-studio\app\jni\Application.mk APP_ABI=x86 NDK_ALL_ABIS=x86 NDK_DEBUG=1 APP_PLATFORM=android-21 NDK_OUT=C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/runtime-src/proj.android-studio/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=C:\Users\Vadim\Documents\Cocos2d\TestAndroidGame2\frameworks\runtime-src\proj.android-studio\app\build\intermediates\ndkBuild\debug\lib NDK_TOOLCHAIN_VERSION=4.9 APP_PLATFORM=android-26 NDK_MODULE_PATH=C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x;C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos;C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/external -j4 NDK_DEBUG=1 C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/runtime-src/proj.android-studio/app/build/intermediates/ndkBuild/debug/obj/local/x86/libcocos2djs.so}
[x86] Compile++ : audioengine_static <= mp3reader.cpp
[x86] Compile++ : cocos2dx_internal_static <= CCAllocatorGlobalNewDelete.cpp
In file included from C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorGlobalNewDelete.cpp:27:0:
C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorStrategyGlobalSmallBlock.h: In constructor 'cocos2d::allocator::AllocatorStrategyGlobalSmallBlock::AllocatorStrategyGlobalSmallBlock()':
C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/cocos2d-x/cocos/./base/allocator/CCAllocatorStrategyGlobalSmallBlock.h:96:75: error: 'memset' was not declared in this scope
memset(_smallBlockAllocators, 0, sizeof(_smallBlockAllocators));
^
make: *** [C:/Users/Vadim/Documents/Cocos2d/TestAndroidGame2/frameworks/runtime-src/proj.android-studio/app/build/intermediates/ndkBuild/debug/obj/local/x86/objs-debug/cocos2dx_internal_static/base/allocator/CCAllocatorGlobalNewDelete.o] Error 1
make: *** Waiting for unfinished jobs....
2017-11-21 16:16:25 +08:00
|
|
|
#include <string.h>
|
2014-12-13 00:57:06 +08:00
|
|
|
#include "base/allocator/CCAllocatorMacros.h"
|
2014-12-16 01:34:25 +08:00
|
|
|
#include "base/allocator/CCAllocatorBase.h"
|
2014-12-13 00:57:06 +08:00
|
|
|
#include "base/allocator/CCAllocatorGlobal.h"
|
|
|
|
#include "base/allocator/CCAllocatorStrategyFixedBlock.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
NS_CC_ALLOCATOR_BEGIN
|
|
|
|
|
2014-12-13 06:54:24 +08:00
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
#define TRACK(slot, size, op) _smallBlockAllocations[slot] op size
|
|
|
|
#else
|
|
|
|
#define TRACK(...)
|
|
|
|
#endif
|
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
// @brief
|
|
|
|
class AllocatorStrategyGlobalSmallBlock
|
2014-12-16 01:34:25 +08:00
|
|
|
: public AllocatorBase
|
2014-12-13 00:57:06 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// default number of block to allocate per page.
|
2014-12-19 11:49:40 +08:00
|
|
|
static const size_t kDefaultSmallBlockCount = 100;
|
2014-12-13 00:57:06 +08:00
|
|
|
|
|
|
|
// default max small block size pool.
|
2014-12-19 11:49:40 +08:00
|
|
|
static const size_t kMaxSmallBlockPower = 13; // 2^13 8kb
|
2014-12-14 02:40:45 +08:00
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
// @brief define for allocator strategy, cannot be typedef because we want to eval at use
|
2014-12-14 02:40:45 +08:00
|
|
|
#define SType(size) AllocatorStrategyFixedBlock<size>
|
2014-12-13 00:57:06 +08:00
|
|
|
|
|
|
|
void _lazy_init()
|
|
|
|
{
|
2014-12-14 02:40:45 +08:00
|
|
|
// this gets called before static constructors
|
|
|
|
// so make sure we only get called once.
|
|
|
|
static bool once = true;
|
|
|
|
if (once)
|
2014-12-13 00:57:06 +08:00
|
|
|
{
|
2014-12-14 02:40:45 +08:00
|
|
|
once = false;
|
2014-12-13 00:57:06 +08:00
|
|
|
|
|
|
|
// call our own constructor. Global new can be called before the constructors are called.
|
|
|
|
// Make sure it gets called by having it done lazily in the call to allocate.
|
|
|
|
new (this) AllocatorStrategyGlobalSmallBlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AllocatorStrategyGlobalSmallBlock()
|
|
|
|
{
|
2014-12-14 02:40:45 +08:00
|
|
|
// this gets called before static constructors
|
|
|
|
// so make sure we only get called once.
|
2014-12-13 00:57:06 +08:00
|
|
|
static bool once = true;
|
|
|
|
if (once)
|
|
|
|
{
|
|
|
|
once = false;
|
|
|
|
|
2014-12-14 02:40:45 +08:00
|
|
|
_maxBlockSize = 1 << kMaxSmallBlockPower;
|
2014-12-13 00:57:06 +08:00
|
|
|
|
2014-12-13 06:54:24 +08:00
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
AllocatorDiagnostics::instance()->trackAllocator(this);
|
|
|
|
AllocatorBase::setTag("GlobalSmallBlock");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
memset(_smallBlockAllocators, 0, sizeof(_smallBlockAllocators));
|
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
memset(_smallBlockAllocations, 0, sizeof(_smallBlockAllocations));
|
|
|
|
#endif
|
2014-12-13 00:57:06 +08:00
|
|
|
// cannot call new on the allocator here because it will recurse
|
|
|
|
// so instead we allocate from the global allocator and construct in place.
|
|
|
|
#define SBA(n, size) \
|
2014-12-14 02:40:45 +08:00
|
|
|
if (size <= _maxBlockSize) \
|
|
|
|
{ \
|
|
|
|
auto v = ccAllocatorGlobal.allocate(sizeof(SType(size))); \
|
|
|
|
_smallBlockAllocators[n] = (AllocatorBase*)(new (v) SType(size)("GlobalSmallBlock::"#size)); \
|
|
|
|
}
|
|
|
|
|
|
|
|
SBA(2, 4)
|
|
|
|
SBA(3, 8);
|
|
|
|
SBA(4, 16);
|
|
|
|
SBA(5, 32);
|
|
|
|
SBA(6, 64);
|
|
|
|
SBA(7, 128);
|
|
|
|
SBA(8, 256);
|
|
|
|
SBA(9, 512);
|
|
|
|
SBA(10, 1024);
|
|
|
|
SBA(11, 2048);
|
|
|
|
SBA(12, 4096);
|
|
|
|
SBA(13, 8192);
|
2014-12-13 00:57:06 +08:00
|
|
|
|
|
|
|
#undef SBA
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~AllocatorStrategyGlobalSmallBlock()
|
|
|
|
{
|
2014-12-14 02:40:45 +08:00
|
|
|
for (int i = 0; i <= kMaxSmallBlockPower; ++i)
|
2014-12-13 00:57:06 +08:00
|
|
|
if (_smallBlockAllocators[i])
|
|
|
|
ccAllocatorGlobal.deallocate(_smallBlockAllocators[i]);
|
2014-12-13 06:54:24 +08:00
|
|
|
|
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
AllocatorDiagnostics::instance()->untrackAllocator(this);
|
|
|
|
#endif
|
2014-12-13 00:57:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// @brief Allocate a block of some size. If the block is <= 8192 it is allocated out of an array
|
|
|
|
// of fixed size block allocators. If larger, then we default back to the global allocator.
|
|
|
|
// @param size Size of block to allocate. This will be rounded to the next power of two.
|
|
|
|
CC_ALLOCATOR_INLINE void* allocate(size_t size)
|
|
|
|
{
|
|
|
|
_lazy_init();
|
|
|
|
|
|
|
|
if (size < sizeof(intptr_t)) // always allocate at least enough space to store a pointer. this is
|
|
|
|
size = sizeof(intptr_t); // so we can link the empty blocks together in the block allocator.
|
|
|
|
|
|
|
|
// if the size is greater than what we determine to be a small block
|
|
|
|
// size then fall through to calling the global allocator instead.
|
|
|
|
if (size > _maxBlockSize)
|
|
|
|
return ccAllocatorGlobal.allocate(size);
|
|
|
|
|
|
|
|
// make sure the size fits into one of the
|
|
|
|
// fixed sized block allocators we have above.
|
|
|
|
size_t adjusted_size = AllocatorBase::nextPow2BlockSize(size);
|
2014-12-14 02:40:45 +08:00
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
#define ALLOCATE(slot, size) \
|
|
|
|
case size: \
|
|
|
|
{ \
|
|
|
|
void* v = _smallBlockAllocators[slot]; \
|
|
|
|
CC_ASSERT(nullptr != v); \
|
|
|
|
auto a = (SType(size)*)v; \
|
|
|
|
address = a->allocate(adjusted_size); \
|
2014-12-13 06:54:24 +08:00
|
|
|
TRACK(slot, size, +=); \
|
2014-12-13 00:57:06 +08:00
|
|
|
} \
|
|
|
|
break;
|
2014-12-14 02:40:45 +08:00
|
|
|
|
2016-06-16 13:27:52 +08:00
|
|
|
void* address = nullptr;
|
2014-12-13 00:57:06 +08:00
|
|
|
|
|
|
|
switch (adjusted_size)
|
|
|
|
{
|
2014-12-14 03:42:35 +08:00
|
|
|
ALLOCATE(2, 4);
|
|
|
|
ALLOCATE(3, 8);
|
|
|
|
ALLOCATE(4, 16);
|
|
|
|
ALLOCATE(5, 32);
|
|
|
|
ALLOCATE(6, 64);
|
|
|
|
ALLOCATE(7, 128);
|
|
|
|
ALLOCATE(8, 256);
|
|
|
|
ALLOCATE(9, 512);
|
|
|
|
ALLOCATE(10, 1024);
|
|
|
|
ALLOCATE(11, 2048);
|
|
|
|
ALLOCATE(12, 4096);
|
|
|
|
ALLOCATE(13, 8192);
|
|
|
|
default:
|
|
|
|
CC_ASSERT(false);
|
|
|
|
break;
|
2014-12-13 00:57:06 +08:00
|
|
|
}
|
2014-12-14 02:40:45 +08:00
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
#undef ALLOCATE
|
|
|
|
|
|
|
|
CC_ASSERT(adjusted_size < AllocatorBase::kDefaultAlignment || 0 == ((intptr_t)address & (AllocatorBase::kDefaultAlignment - 1)));
|
|
|
|
CC_ASSERT(nullptr != address);
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @brief Deallocate a block by choosing one of the fixed size block allocators
|
|
|
|
// or defaulting to the global allocator if we do not own this block.
|
|
|
|
CC_ALLOCATOR_INLINE void deallocate(void* address, size_t size = 0)
|
|
|
|
{
|
|
|
|
// if we didn't get a size, then we need to find the allocator
|
|
|
|
// by asking each if they own the block. For allocators that
|
|
|
|
// have few large pages, this is extremely fast.
|
|
|
|
if (0 == size)
|
|
|
|
{
|
|
|
|
#define OWNS(slot, S, address) \
|
2014-12-14 02:40:45 +08:00
|
|
|
case S: \
|
2014-12-13 00:57:06 +08:00
|
|
|
{ \
|
2014-12-14 02:40:45 +08:00
|
|
|
void* v = _smallBlockAllocators[slot]; \
|
|
|
|
if (v) \
|
|
|
|
{ \
|
|
|
|
auto a = (SType(S)*)v; \
|
|
|
|
if (a->owns(address)) \
|
|
|
|
{ \
|
|
|
|
size = SType(S)::block_size; \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
}
|
2014-12-13 00:57:06 +08:00
|
|
|
|
2014-12-14 02:40:45 +08:00
|
|
|
// falls through until found
|
2014-12-13 00:57:06 +08:00
|
|
|
switch (sizeof(uint32_t))
|
|
|
|
{
|
2014-12-14 02:40:45 +08:00
|
|
|
OWNS(2, 4, address);
|
|
|
|
OWNS(3, 8, address);
|
|
|
|
OWNS(4, 16, address);
|
|
|
|
OWNS(5, 32, address);
|
|
|
|
OWNS(6, 64, address);
|
|
|
|
OWNS(7, 128, address);
|
|
|
|
OWNS(8, 256, address);
|
|
|
|
OWNS(9, 512, address);
|
|
|
|
OWNS(10, 1024, address);
|
|
|
|
OWNS(11, 2048, address);
|
|
|
|
OWNS(12, 4096, address);
|
|
|
|
OWNS(13, 8192, address);
|
2014-12-13 00:57:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the size is greater than what we determine to be a small block
|
|
|
|
// size then default to calling the global allocator instead.
|
|
|
|
if (0 == size || size > _maxBlockSize)
|
|
|
|
return ccAllocatorGlobal.deallocate(address, size);
|
|
|
|
|
|
|
|
if (size < sizeof(intptr_t)) // always allocate at least enough space to store a pointer. this is
|
|
|
|
size = sizeof(intptr_t); // so we can link the empty blocks together in the block allocator.
|
2014-12-14 02:40:45 +08:00
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
// make sure the size fits into one of the
|
|
|
|
// fixed sized block allocators we have above.
|
|
|
|
size_t adjusted_size = AllocatorBase::nextPow2BlockSize(size);
|
|
|
|
|
|
|
|
#define DEALLOCATE(slot, size, address) \
|
|
|
|
case size: \
|
|
|
|
{ \
|
|
|
|
void* v = _smallBlockAllocators[slot]; \
|
|
|
|
CC_ASSERT(nullptr != v); \
|
|
|
|
auto a = (SType(size)*)v; \
|
|
|
|
a->deallocate(address, size); \
|
2014-12-13 06:54:24 +08:00
|
|
|
TRACK(slot, size, -=); \
|
2014-12-13 00:57:06 +08:00
|
|
|
} \
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (adjusted_size)
|
|
|
|
{
|
2014-12-16 08:21:12 +08:00
|
|
|
DEALLOCATE(2, 4, address);
|
|
|
|
DEALLOCATE(3, 8, address);
|
|
|
|
DEALLOCATE(4, 16, address);
|
|
|
|
DEALLOCATE(5, 32, address);
|
|
|
|
DEALLOCATE(6, 64, address);
|
|
|
|
DEALLOCATE(7, 128, address);
|
|
|
|
DEALLOCATE(8, 256, address);
|
|
|
|
DEALLOCATE(9, 512, address);
|
|
|
|
DEALLOCATE(10, 1024, address);
|
|
|
|
DEALLOCATE(11, 2048, address);
|
|
|
|
DEALLOCATE(12, 4096, address);
|
|
|
|
DEALLOCATE(13, 8192, address);
|
|
|
|
default:
|
|
|
|
CC_ASSERT(false);
|
2014-12-13 00:57:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef DEALLOCATE
|
|
|
|
}
|
|
|
|
|
2014-12-13 06:54:24 +08:00
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
std::string diagnostics() const
|
|
|
|
{
|
|
|
|
std::stringstream s;
|
2014-12-14 03:42:35 +08:00
|
|
|
size_t total = 0;
|
2014-12-14 03:45:08 +08:00
|
|
|
for (auto i = 2; i <= kMaxSmallBlockPower; ++i)
|
2014-12-13 06:54:24 +08:00
|
|
|
{
|
|
|
|
auto a = _smallBlockAllocators[i];
|
|
|
|
if (a)
|
|
|
|
{
|
2014-12-14 03:42:35 +08:00
|
|
|
total += _smallBlockAllocations[i];
|
2014-12-13 06:54:24 +08:00
|
|
|
s << a->tag() << " allocated:" << _smallBlockAllocations[i] << "\n";
|
|
|
|
}
|
|
|
|
}
|
2014-12-14 03:42:35 +08:00
|
|
|
s << "Total:" << total << "\n";
|
2014-12-13 06:54:24 +08:00
|
|
|
return s.str();
|
|
|
|
}
|
|
|
|
size_t _highestCount;
|
|
|
|
#endif
|
|
|
|
|
2014-12-13 00:57:06 +08:00
|
|
|
protected:
|
|
|
|
|
|
|
|
// @brief the max size of a block this allocator will pool before using global allocator
|
|
|
|
size_t _maxBlockSize;
|
2014-12-13 06:54:24 +08:00
|
|
|
|
2014-12-14 02:40:45 +08:00
|
|
|
// @brief array of small block allocators from 2^0 -> 2^kMaxSmallBlockPower
|
|
|
|
AllocatorBase* _smallBlockAllocators[kMaxSmallBlockPower + 1];
|
|
|
|
|
2014-12-13 06:54:24 +08:00
|
|
|
#if CC_ENABLE_ALLOCATOR_DIAGNOSTICS
|
|
|
|
size_t _smallBlockAllocations[kMaxSmallBlockPower + 1];
|
|
|
|
#endif
|
2014-12-13 00:57:06 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
NS_CC_ALLOCATOR_END
|
|
|
|
NS_CC_END
|
|
|
|
|
2015-03-24 15:13:05 +08:00
|
|
|
/// @endcond
|
2014-12-13 00:57:06 +08:00
|
|
|
#endif//CC_ALLOCATOR_STRATEGY_GLOBAL_SMALL_BLOCK_H
|