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 @@ ...@@ -8,10 +8,11 @@
#include "compiler/ParseHelper.h" #include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h" #include "compiler/ShHandle.h"
static bool InitializeSymbolTable( namespace {
const TBuiltInStrings& builtInStrings, bool InitializeSymbolTable(
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources, const TBuiltInStrings& builtInStrings,
TInfoSink& infoSink, TSymbolTable& symbolTable) ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
TInfoSink& infoSink, TSymbolTable& symbolTable)
{ {
TIntermediate intermediate(infoSink); TIntermediate intermediate(infoSink);
TExtensionBehavior extBehavior; TExtensionBehavior extBehavior;
...@@ -49,6 +50,34 @@ static bool InitializeSymbolTable( ...@@ -49,6 +50,34 @@ static bool InitializeSymbolTable(
return true; 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) TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type), : shaderType(type),
shaderSpec(spec) shaderSpec(spec)
...@@ -61,11 +90,13 @@ TCompiler::~TCompiler() ...@@ -61,11 +90,13 @@ TCompiler::~TCompiler()
bool TCompiler::Init(const ShBuiltInResources& resources) bool TCompiler::Init(const ShBuiltInResources& resources)
{ {
TScopedPoolAllocator scopedAlloc(&allocator, false);
// Generate built-in symbol table. // Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources)) if (!InitBuiltInSymbolTable(resources))
return false; return false;
InitExtensionBehavior(resources, extensionBehavior); InitExtensionBehavior(resources, extensionBehavior);
return true; return true;
} }
...@@ -73,6 +104,7 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -73,6 +104,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
const int numStrings, const int numStrings,
int compileOptions) int compileOptions)
{ {
TScopedPoolAllocator scopedAlloc(&allocator, true);
clearResults(); clearResults();
if (numStrings == 0) if (numStrings == 0)
......
...@@ -22,14 +22,10 @@ void InitializeGlobalPools() ...@@ -22,14 +22,10 @@ void InitializeGlobalPools()
if (globalPools) if (globalPools)
return; return;
TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
TThreadGlobalPools* threadData = new TThreadGlobalPools(); TThreadGlobalPools* threadData = new TThreadGlobalPools();
threadData->globalPoolAllocator = 0;
threadData->globalPoolAllocator = globalPoolAllocator;
OS_SetTLSValue(PoolIndex, threadData);
OS_SetTLSValue(PoolIndex, threadData);
globalPoolAllocator->push();
} }
void FreeGlobalPools() void FreeGlobalPools()
...@@ -38,9 +34,7 @@ void FreeGlobalPools() ...@@ -38,9 +34,7 @@ void FreeGlobalPools()
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex)); TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (!globalPools) if (!globalPools)
return; return;
GlobalPoolAllocator.popAll();
delete &GlobalPoolAllocator;
delete globalPools; delete globalPools;
} }
...@@ -66,7 +60,7 @@ TPoolAllocator& GetGlobalPoolAllocator() ...@@ -66,7 +60,7 @@ TPoolAllocator& GetGlobalPoolAllocator()
return *threadData->globalPoolAllocator; return *threadData->globalPoolAllocator;
} }
void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator) void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{ {
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex)); TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
...@@ -77,8 +71,7 @@ void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator) ...@@ -77,8 +71,7 @@ void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
// Implement the functionality of the TPoolAllocator class, which // Implement the functionality of the TPoolAllocator class, which
// is documented in PoolAlloc.h. // is documented in PoolAlloc.h.
// //
TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) : TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
global(g),
pageSize(growthIncrement), pageSize(growthIncrement),
alignment(allocationAlignment), alignment(allocationAlignment),
freeList(0), freeList(0),
...@@ -124,24 +117,14 @@ TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignm ...@@ -124,24 +117,14 @@ TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignm
TPoolAllocator::~TPoolAllocator() TPoolAllocator::~TPoolAllocator()
{ {
if (!global) { while (inUseList) {
// tHeader* next = inUseList->nextPage;
// Then we know that this object is not being inUseList->~tHeader();
// allocated after other, globally scoped objects delete [] reinterpret_cast<char*>(inUseList);
// that depend on it. So we can delete the "in use" memory. inUseList = next;
//
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
delete [] reinterpret_cast<char*>(inUseList);
inUseList = next;
}
} }
// // We should not check the guard blocks
// 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
// here, because we did it already when the block was // here, because we did it already when the block was
// placed into the free list. // placed into the free list.
// //
......
...@@ -115,7 +115,7 @@ private: ...@@ -115,7 +115,7 @@ private:
// //
class TPoolAllocator { class TPoolAllocator {
public: 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() // Don't call the destructor just to free up the memory, call pop()
...@@ -194,7 +194,6 @@ protected: ...@@ -194,7 +194,6 @@ protected:
return TAllocation::offsetAllocation(memory); 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 pageSize; // granularity of allocation from the OS
size_t alignment; // all returned allocations will be aligned at size_t alignment; // all returned allocations will be aligned at
// this granularity, which will be a power of 2 // this granularity, which will be a power of 2
...@@ -220,18 +219,15 @@ private: ...@@ -220,18 +219,15 @@ private:
// different times. But a simple use is to have a global pop // different times. But a simple use is to have a global pop
// with everyone using the same global allocator. // with everyone using the same global allocator.
// //
typedef TPoolAllocator* PoolAllocatorPointer;
extern TPoolAllocator& GetGlobalPoolAllocator(); extern TPoolAllocator& GetGlobalPoolAllocator();
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
#define GlobalPoolAllocator GetGlobalPoolAllocator() #define GlobalPoolAllocator GetGlobalPoolAllocator()
struct TThreadGlobalPools struct TThreadGlobalPools
{ {
TPoolAllocator* globalPoolAllocator; TPoolAllocator* globalPoolAllocator;
}; };
void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
// //
// This STL compatible allocator is intended to be used as the allocator // This STL compatible allocator is intended to be used as the allocator
// parameter to templatized STL containers, like vector and map. // parameter to templatized STL containers, like vector and map.
......
...@@ -28,9 +28,14 @@ class TCompiler; ...@@ -28,9 +28,14 @@ class TCompiler;
// //
class TShHandleBase { class TShHandleBase {
public: public:
TShHandleBase() { } TShHandleBase();
virtual ~TShHandleBase() { } virtual ~TShHandleBase();
virtual TCompiler* getAsCompiler() { return 0; } 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( ...@@ -161,15 +161,7 @@ int ShCompile(
if (compiler == 0) if (compiler == 0)
return 0; return 0;
GlobalPoolAllocator.push();
bool success = compiler->compile(shaderStrings, numStrings, compileOptions); bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
//
// Throw away all the temporary memory used by the compilation process.
//
GlobalPoolAllocator.pop();
return success ? 1 : 0; 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