Commit bafcbaa3 by alokp@chromium.org

Moved the global-pool-allocator to TCompiler so that all memory allocated by the…

Moved the global-pool-allocator to TCompiler so that all memory allocated by the compiler can be de-allocated. Earlier the global-pool-allocator kept accumulating memory from all compilers (symbol-table in particular). The memory was only de-allocated when gpu-process exited or ShFinalize() was called. This was a problem for Chromium which keeps the GPU process around for the browser session. Now the memory is de-allocated as soon as the compiler is deleted, which happens when a tab is closed. BUG=58808 (crbug.com) Review URL: http://codereview.appspot.com/3280041 git-svn-id: https://angleproject.googlecode.com/svn/trunk@489 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent a5a8a0ad
......@@ -8,10 +8,11 @@
#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
static bool InitializeSymbolTable(
const TBuiltInStrings& builtInStrings,
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
TInfoSink& infoSink, TSymbolTable& symbolTable)
namespace {
bool InitializeSymbolTable(
const TBuiltInStrings& builtInStrings,
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
TInfoSink& infoSink, TSymbolTable& symbolTable)
{
TIntermediate intermediate(infoSink);
TExtensionBehavior extBehavior;
......@@ -49,6 +50,34 @@ static bool InitializeSymbolTable(
return true;
}
class TScopedPoolAllocator {
public:
TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
: mAllocator(allocator), mPushPopAllocator(pushPop) {
if (mPushPopAllocator) mAllocator->push();
SetGlobalPoolAllocator(mAllocator);
}
~TScopedPoolAllocator() {
SetGlobalPoolAllocator(NULL);
if (mPushPopAllocator) mAllocator->pop();
}
private:
TPoolAllocator* mAllocator;
bool mPushPopAllocator;
};
} // namespace
TShHandleBase::TShHandleBase() {
allocator.push();
SetGlobalPoolAllocator(&allocator);
}
TShHandleBase::~TShHandleBase() {
SetGlobalPoolAllocator(NULL);
allocator.popAll();
}
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec)
......@@ -61,11 +90,13 @@ TCompiler::~TCompiler()
bool TCompiler::Init(const ShBuiltInResources& resources)
{
TScopedPoolAllocator scopedAlloc(&allocator, false);
// Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources))
return false;
InitExtensionBehavior(resources, extensionBehavior);
return true;
}
......@@ -73,6 +104,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
const int numStrings,
int compileOptions)
{
TScopedPoolAllocator scopedAlloc(&allocator, true);
clearResults();
if (numStrings == 0)
......
......@@ -22,14 +22,10 @@ void InitializeGlobalPools()
if (globalPools)
return;
TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
TThreadGlobalPools* threadData = new TThreadGlobalPools();
threadData->globalPoolAllocator = globalPoolAllocator;
OS_SetTLSValue(PoolIndex, threadData);
globalPoolAllocator->push();
threadData->globalPoolAllocator = 0;
OS_SetTLSValue(PoolIndex, threadData);
}
void FreeGlobalPools()
......@@ -38,9 +34,7 @@ void FreeGlobalPools()
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (!globalPools)
return;
GlobalPoolAllocator.popAll();
delete &GlobalPoolAllocator;
delete globalPools;
}
......@@ -66,7 +60,7 @@ TPoolAllocator& GetGlobalPoolAllocator()
return *threadData->globalPoolAllocator;
}
void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
......@@ -77,8 +71,7 @@ void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
// Implement the functionality of the TPoolAllocator class, which
// is documented in PoolAlloc.h.
//
TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) :
global(g),
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
pageSize(growthIncrement),
alignment(allocationAlignment),
freeList(0),
......@@ -124,24 +117,14 @@ TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignm
TPoolAllocator::~TPoolAllocator()
{
if (!global) {
//
// Then we know that this object is not being
// allocated after other, globally scoped objects
// that depend on it. So we can delete the "in use" memory.
//
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
delete [] reinterpret_cast<char*>(inUseList);
inUseList = next;
}
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
delete [] reinterpret_cast<char*>(inUseList);
inUseList = next;
}
//
// Always delete the free list memory - it can't be being
// (correctly) referenced, whether the pool allocator was
// global or not. We should not check the guard blocks
// We should not check the guard blocks
// here, because we did it already when the block was
// placed into the free list.
//
......
......@@ -115,7 +115,7 @@ private:
//
class TPoolAllocator {
public:
TPoolAllocator(bool global = false, int growthIncrement = 8*1024, int allocationAlignment = 16);
TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
//
// Don't call the destructor just to free up the memory, call pop()
......@@ -194,7 +194,6 @@ protected:
return TAllocation::offsetAllocation(memory);
}
bool global; // should be true if this object is globally scoped
size_t pageSize; // granularity of allocation from the OS
size_t alignment; // all returned allocations will be aligned at
// this granularity, which will be a power of 2
......@@ -220,18 +219,15 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
typedef TPoolAllocator* PoolAllocatorPointer;
extern TPoolAllocator& GetGlobalPoolAllocator();
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
#define GlobalPoolAllocator GetGlobalPoolAllocator()
struct TThreadGlobalPools
{
TPoolAllocator* globalPoolAllocator;
};
void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
//
// This STL compatible allocator is intended to be used as the allocator
// parameter to templatized STL containers, like vector and map.
......
......@@ -28,9 +28,14 @@ class TCompiler;
//
class TShHandleBase {
public:
TShHandleBase() { }
virtual ~TShHandleBase() { }
TShHandleBase();
virtual ~TShHandleBase();
virtual TCompiler* getAsCompiler() { return 0; }
protected:
// Memory allocator. Allocates and tracks memory required by the compiler.
// Deallocates all memory when compiler is destructed.
TPoolAllocator allocator;
};
//
......
......@@ -161,15 +161,7 @@ int ShCompile(
if (compiler == 0)
return 0;
GlobalPoolAllocator.push();
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
//
// Throw away all the temporary memory used by the compilation process.
//
GlobalPoolAllocator.pop();
return success ? 1 : 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment