## Linux compilation
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Hide all symbols and allows the symbols declared as visible to be exported
- # set (VISIBILITY_FLAG "-fvisibility=hidden")
+ if (NOT GBE_COMPILE_UTESTS)
+ set (CMAKE_C_CXX_FLAGS "-fvisibility=hidden")
+ endif (NOT GBE_COMPILE_UTESTS)
if (COMPILER STREQUAL "GCC")
- set (CMAKE_C_CXX_FLAGS "-Wstrict-aliasing=2 -fstrict-aliasing -msse2 -ffast-math -fPIC -Wall")
+ set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS} -Wstrict-aliasing=2 -fstrict-aliasing -msse2 -ffast-math -fPIC -Wall")
set (CMAKE_CXX_FLAGS "${CMAKE_C_CXX_FLAGS} -Wno-invalid-offsetof -fno-rtti -std=c++0x")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GBE_DEBUG_MEMORY_FLAG}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GBE_COMPILE_UTESTS_FLAG}")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VISIBILITY_FLAG} -Wl,-E")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-E")
+ set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined")
if (NOT GBE_COMPILE_UTESTS)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
endif (NOT GBE_COMPILE_UTESTS)
set (CMAKE_C_FLAGS "${CMAKE_C_CXX_FLAGS}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GBE_DEBUG_MEMORY_FLAG}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GBE_COMPILE_UTESTS_FLAG}")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VISIBILITY_FLAG} -Wl,-E")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-E")
set (CMAKE_C_FLAGS_DEBUG "-g -DGBE_DEBUG=1")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DGBE_DEBUG=1")
set (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG -DGBE_DEBUG=0")
ir/value.cpp
ir/value.hpp
gen/program.cpp
+ gen/program.hpp
+ gen/program.h
gen/brw_disasm.c
gen/brw_eu_emit.c
gen/brw_eu.c)
include (${LLVM_DIR}/AddLLVMDefinitions.cmake)
target_link_libraries (gbe
LLVMGenBackend
+ LLVMTransformUtils
+ LLVMCore
+ LLVMTarget
+ LLVMAnalysis
+ LLVMCodeGen
+ LLVMScalarOpts
LLVMSelectionDAG
LLVMAsmPrinter
LLVMMCParser
target_link_libraries (tester gbe)
endif (GBE_COMPILE_UTESTS)
+install (TARGETS gbe LIBRARY DESTINATION lib)
+install (FILES gen/program.h DESTINATION include/gen)
+
#include <stdint.h>
-struct {
+static struct {
char *name;
int nsrc;
int ndst;
[BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
};
-char *conditional_modifier[16] = {
+static char *conditional_modifier[16] = {
[BRW_CONDITIONAL_NONE] = "",
[BRW_CONDITIONAL_Z] = ".e",
[BRW_CONDITIONAL_NZ] = ".ne",
[BRW_CONDITIONAL_U] = ".u",
};
-char *negate[2] = {
+static char *negate[2] = {
[0] = "",
[1] = "-",
};
-char *_abs[2] = {
+static char *_abs[2] = {
[0] = "",
[1] = "(abs)",
};
-char *vert_stride[16] = {
+static char *vert_stride[16] = {
[0] = "0",
[1] = "1",
[2] = "2",
[15] = "VxH",
};
-char *width[8] = {
+static char *width[8] = {
[0] = "1",
[1] = "2",
[2] = "4",
[4] = "16",
};
-char *horiz_stride[4] = {
+static char *horiz_stride[4] = {
[0] = "0",
[1] = "1",
[2] = "2",
[3] = "4"
};
-char *chan_sel[4] = {
+static char *chan_sel[4] = {
[0] = "x",
[1] = "y",
[2] = "z",
[3] = "w",
};
-char *dest_condmod[16] = {
-};
-
-char *debug_ctrl[2] = {
+static char *debug_ctrl[2] = {
[0] = "",
[1] = ".breakpoint"
};
-char *saturate[2] = {
+static char *saturate[2] = {
[0] = "",
[1] = ".sat"
};
-char *accwr[2] = {
+static char *accwr[2] = {
[0] = "",
[1] = "AccWrEnable"
};
-char *wectrl[2] = {
+static char *wectrl[2] = {
[0] = "WE_normal",
[1] = "WE_all"
};
-char *exec_size[8] = {
+static char *exec_size[8] = {
[0] = "1",
[1] = "2",
[2] = "4",
[5] = "32"
};
-char *pred_inv[2] = {
+static char *pred_inv[2] = {
[0] = "+",
[1] = "-"
};
-char *pred_ctrl_align16[16] = {
+static char *pred_ctrl_align16[16] = {
[1] = "",
[2] = ".x",
[3] = ".y",
[7] = ".all4h",
};
-char *pred_ctrl_align1[16] = {
+static char *pred_ctrl_align1[16] = {
[1] = "",
[2] = ".anyv",
[3] = ".allv",
[11] = ".all16h",
};
-char *thread_ctrl[4] = {
+static char *thread_ctrl[4] = {
[0] = "",
[2] = "switch"
};
-char *compr_ctrl[4] = {
+static char *compr_ctrl[4] = {
[0] = "",
[1] = "sechalf",
[2] = "compr",
[3] = "compr4",
};
-char *dep_ctrl[4] = {
+static char *dep_ctrl[4] = {
[0] = "",
[1] = "NoDDClr",
[2] = "NoDDChk",
[3] = "NoDDClr,NoDDChk",
};
-char *mask_ctrl[4] = {
+static char *mask_ctrl[4] = {
[0] = "",
[1] = "nomask",
};
-char *access_mode[2] = {
+static char *access_mode[2] = {
[0] = "align1",
[1] = "align16",
};
-char *reg_encoding[8] = {
+static char *reg_encoding[8] = {
[0] = "UD",
[1] = "D",
[2] = "UW",
[7] = "F"
};
-int reg_type_size[8] = {
+const int reg_type_size[8] = {
[0] = 4,
[1] = 4,
[2] = 2,
[7] = 4
};
-char *imm_encoding[8] = {
- [0] = "UD",
- [1] = "D",
- [2] = "UW",
- [3] = "W",
- [5] = "VF",
- [6] = "V",
- [7] = "F"
-};
-
-char *reg_file[4] = {
+static char *reg_file[4] = {
[0] = "A",
[1] = "g",
[2] = "m",
[3] = "imm",
};
-char *writemask[16] = {
+static char *writemask[16] = {
[0x0] = ".",
[0x1] = ".x",
[0x2] = ".y",
[0xf] = "",
};
-char *end_of_thread[2] = {
+static char *end_of_thread[2] = {
[0] = "",
[1] = "EOT"
};
-char *target_function[16] = {
+static char *target_function[16] = {
[BRW_SFID_NULL] = "null",
[BRW_SFID_MATH] = "math",
[BRW_SFID_SAMPLER] = "sampler",
[BRW_SFID_THREAD_SPAWNER] = "thread_spawner"
};
-char *target_function_gen6[16] = {
+static char *target_function_gen6[16] = {
[BRW_SFID_NULL] = "null",
[BRW_SFID_MATH] = "math",
[BRW_SFID_SAMPLER] = "sampler",
[GEN7_SFID_DATAPORT_DATA_CACHE] = "data"
};
-char *dp_rc_msg_type_gen6[16] = {
+static char *dp_rc_msg_type_gen6[16] = {
[BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read",
[GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read",
[GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read",
[GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORMc write",
};
-char *math_function[16] = {
+static char *math_function[16] = {
[BRW_MATH_FUNCTION_INV] = "inv",
[BRW_MATH_FUNCTION_LOG] = "log",
[BRW_MATH_FUNCTION_EXP] = "exp",
[BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
};
-char *math_saturate[2] = {
+static char *math_saturate[2] = {
[0] = "",
[1] = "sat"
};
-char *math_signed[2] = {
+static char *math_signed[2] = {
[0] = "",
[1] = "signed"
};
-char *math_scalar[2] = {
+static char *math_scalar[2] = {
[0] = "",
[1] = "scalar"
};
-char *math_precision[2] = {
+static char *math_precision[2] = {
[0] = "",
[1] = "partial_precision"
};
-char *urb_opcode[2] = {
+static char *urb_opcode[2] = {
[0] = "urb_write",
[1] = "ff_sync",
};
-char *urb_swizzle[4] = {
+static char *urb_swizzle[4] = {
[BRW_URB_SWIZZLE_NONE] = "",
[BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
[BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
};
-char *urb_allocate[2] = {
+static char *urb_allocate[2] = {
[0] = "",
[1] = "allocate"
};
-char *urb_used[2] = {
+static char *urb_used[2] = {
[0] = "",
[1] = "used"
};
-char *urb_complete[2] = {
+static char *urb_complete[2] = {
[0] = "",
[1] = "complete"
};
-char *sampler_target_format[4] = {
+static char *sampler_target_format[4] = {
[0] = "F",
[2] = "UD",
[3] = "D"
struct brw_reg src0,
struct brw_reg src1);
+void brw_EOT(struct brw_compile *p, uint32_t msg_nr);
+
void brw_oword_block_read(struct brw_compile *p,
struct brw_reg dest,
struct brw_reg mrf,
insn->header.execution_size = reg.width; /* note - definitions are compatible */
}
-
/**
* Prior to Sandybridge, the SEND instruction accepted non-MRF source
* registers, implicitly moving the operand to a message register.
brw_next_insn(struct brw_compile *p, uint32_t opcode)
{
struct brw_instruction *insn;
- assert(0);
-#if 0
- if (p->nr_insn + 1 > p->store_size) {
- p->store_size <<= 1;
- p->store = reralloc(p->mem_ctx, p->store,
- struct brw_instruction, p->store_size);
- if (!p->store)
- assert(!"realloc eu store memeory failed");
- }
-#endif
-
insn = &p->store[p->nr_insn++];
memcpy(insn, p->current, sizeof(*insn));
-
- /* Reset this one-shot flag:
- */
-
- if (p->current->header.destreg__conditionalmod) {
- p->current->header.destreg__conditionalmod = 0;
- p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
- }
-
insn->header.opcode = opcode;
return insn;
}
}
+void
+brw_EOT(struct brw_compile *p, uint32_t msg_nr)
+{
+ struct brw_instruction *insn = NULL;
+
+ brw_MOV(p, brw_message_reg(msg_nr), brw_vec8_grf(0,0));
+ insn = next_insn(p, BRW_OPCODE_SEND);
+ brw_set_dest(p, insn, brw_null_reg());
+ brw_set_src0(p, insn, brw_message_reg(msg_nr));
+ brw_set_src1(p, insn, brw_imm_ud(0));
+
+ insn->header.execution_size = BRW_EXECUTE_1;
+ insn->header.predicate_control = 0; /* XXX */
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = BRW_EXECUTE_1;
+ insn->bits3.spawner_gen5.opcode = 0;
+ insn->bits3.spawner_gen5.request = 1;
+ insn->bits3.spawner_gen5.resource = 0;
+ insn->bits3.spawner_gen5.header = 0;
+ insn->bits3.spawner_gen5.response_length = 0;
+ insn->bits3.spawner_gen5.msg_length = 1;
+ insn->bits3.spawner_gen5.end_of_thread = 1;
+ insn->header.destreg__conditionalmod = BRW_SFID_THREAD_SPAWNER;
+}
+
uint32_t end_of_thread:1;
} generic_gen5;
+ struct {
+ uint32_t opcode:1;
+ uint32_t request:1;
+ uint32_t pad0:2;
+ uint32_t resource:1;
+ uint32_t pad1:14;
+ uint32_t header:1;
+ uint32_t response_length:5;
+ uint32_t msg_length:4;
+ uint32_t pad2:2;
+ uint32_t end_of_thread:1;
+ } spawner_gen5;
+
/** G45 PRM, Volume 4, Section 6.1.1.1 */
struct {
uint32_t function:4;
#include "ir/value.hpp"
#include "ir/unit.hpp"
#include "llvm/llvm_to_gen.hpp"
+#include "gen/brw_eu.h"
+#include <cstring>
namespace gbe {
namespace gen {
- Kernel::Kernel(void) :
- args(NULL), insns(NULL), argNum(0), insnNum(0), liveness(NULL), dag(NULL)
+ Kernel::Kernel(const std::string &name) :
+ name(name), args(NULL), insns(NULL), argNum(0), insnNum(0), liveness(NULL), dag(NULL)
{}
Kernel::~Kernel(void) {
GBE_SAFE_DELETE_ARRAY(insns);
NOT_IMPLEMENTED;
return false;
}
+
bool Program::buildFromLLVMFile(const char *fileName, std::string &error) {
ir::Unit unit;
if (llvmToGen(unit, fileName) == false) {
this->buildFromUnit(unit, error);
return true;
}
+
bool Program::buildFromUnit(const ir::Unit &unit, std::string &error) {
- return false;
+ const auto &set = unit.getFunctionSet();
+ const uint32_t kernelNum = set.size();
+ if (kernelNum == 0) return true;
+
+ // Dummy functions now
+ for (auto it = set.begin(); it != set.end(); ++it) {
+ const std::string &name = it->first;
+ // const ir::Function &fn = *it->second;
+ Kernel *kernel = GBE_NEW(Kernel, name);
+ brw_compile *p = (brw_compile*) GBE_MALLOC(sizeof(brw_compile));
+ std::memset(p, 0, sizeof(*p));
+ brw_EOT(p, 127);
+ kernel->insnNum = p->nr_insn;
+ kernel->insns = GBE_NEW_ARRAY(brw_instruction, kernel->insnNum);
+ std::memcpy(kernel->insns, p->store, kernel->insnNum * sizeof(brw_instruction));
+ GBE_FREE(p);
+ }
+
+ return true;
}
} /* namespace gen */
} /* namespace gbe */
+/////////////////////////////////////////////////////////////////////////////
+// C interface for the Gen Programs
+/////////////////////////////////////////////////////////////////////////////
+GBE_EXPORT_SYMBOL
+GenProgram *GenProgramNewFromSource(const char *source) {
+ NOT_IMPLEMENTED;
+ return NULL;
+}
+
+GBE_EXPORT_SYMBOL
+GenProgram *GenProgramNewFromBinary(const char *binary, size_t size) {
+ NOT_IMPLEMENTED;
+ return NULL;
+}
+
+GBE_EXPORT_SYMBOL
+GenProgram *GenProgramNewFromLLVM(const char *fileName,
+ size_t stringSize,
+ char *err,
+ size_t *errSize)
+{
+ using namespace gbe::gen;
+ Program *program = GBE_NEW(Program);
+ std::string error;
+
+ // Try to compile the program
+ if (program->buildFromLLVMFile(fileName, error) == false) {
+ if (err != NULL && errSize != NULL && stringSize > 0u) {
+ const size_t msgSize = std::min(error.size(), stringSize-1u);
+ std::memcpy(err, error.c_str(), msgSize);
+ *errSize = error.size();
+ }
+ GBE_DELETE(program);
+ return NULL;
+ }
+
+ // Everything run fine
+ return (GenProgram *) program;
+}
+
+GBE_EXPORT_SYMBOL
+void GenProgramDelete(GenProgram *genProgram) {
+ gbe::gen::Program *program = (gbe::gen::Program*)(genProgram);
+ GBE_SAFE_DELETE(program);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// C interface for the Gen Kernels
+/////////////////////////////////////////////////////////////////////////////
+GBE_EXPORT_SYMBOL
+uint32_t GenProgramGetKernelNum(const GenProgram *genProgram) {
+ if (genProgram == NULL) return 0;
+ const gbe::gen::Program *program = (const gbe::gen::Program*) genProgram;
+ return program->getKernelNum();
+}
+
+GBE_EXPORT_SYMBOL
+const GenKernel *GenProgramGetKernel(const GenProgram *genProgram, const char *name) {
+ if (genProgram == NULL) return NULL;
+ const gbe::gen::Program *program = (const gbe::gen::Program*) genProgram;
+ return (GenKernel*) program->getKernel(std::string(name));
+}
+
+GBE_EXPORT_SYMBOL
+const char *GenKernelGetCode(const GenKernel *genKernel) {
+ if (genKernel == NULL) return NULL;
+ const gbe::gen::Kernel *kernel = (const gbe::gen::Kernel*) genKernel;
+ return kernel->getCode();
+}
+
+GBE_EXPORT_SYMBOL
+const size_t GenKernelGetCodeSize(const GenKernel *genKernel) {
+ if (genKernel == NULL) return 0u;
+ const gbe::gen::Kernel *kernel = (const gbe::gen::Kernel*) genKernel;
+ return kernel->getCodeSize();
+}
+
+GBE_EXPORT_SYMBOL
+uint32_t GenKernelGetArgNum(const GenKernel *genKernel) {
+ if (genKernel == NULL) return 0u;
+ const gbe::gen::Kernel *kernel = (const gbe::gen::Kernel*) genKernel;
+ return kernel->getArgNum();
+}
+
+GBE_EXPORT_SYMBOL
+uint32_t GenKernelGetArgSize(const GenKernel *genKernel, uint32_t argID) {
+ if (genKernel == NULL) return 0u;
+ const gbe::gen::Kernel *kernel = (const gbe::gen::Kernel*) genKernel;
+ return kernel->getArgSize(argID);
+}
+
+GBE_EXPORT_SYMBOL
+GenArgType GenKernelGetArgType(const GenKernel *genKernel, uint32_t argID) {
+ if (genKernel == NULL) return GEN_ARG_INVALID;
+ const gbe::gen::Kernel *kernel = (const gbe::gen::Kernel*) genKernel;
+ return kernel->getArgType(argID);
+}
+
GEN_ARG_GLOBAL_PTR = 1, // __global, __constant
GEN_ARG_STRUCTURE = 2, // By value structure
GEN_ARG_IMAGE = 3, // image2d_t, image3d_t
- GEN_ARG_INVALUE = 0xffffffff
+ GEN_ARG_INVALID = 0xffffffff
};
/*! Create a new program from the given source code (zero terminated string) */
/*! Create a new program from the given blob */
GenProgram *GenProgramNewFromBinary(const char *binary, size_t size);
+/*! Create a new program from the given LLVM file */
+GenProgram *GenProgramNewFromLLVM(const char *fileName,
+ size_t stringSize,
+ char *err,
+ size_t *errSize);
+
/*! Destroy and deallocate the given program */
void GenProgramDelete(GenProgram *program);
uint32_t GenProgramGetKernelNum(const GenProgram *program);
/*! Get the kernel from its name */
-const GenKernel GenProgramGetKernel(const GenProgram *program, const char *name);
+const GenKernel *GenProgramGetKernel(const GenProgram *program, const char *name);
/*! Get the Gen ISA source code */
const char *GenKernelGetCode(const GenKernel *kernel);
uint32_t GenKernelGetArgSize(const GenKernel *kernel, uint32_t argID);
/*! Get the type of the given argument */
-GenArgType GenKernelGetArgType(const GenKernel *kernel, uint32_t argID);
+enum GenArgType GenKernelGetArgType(const GenKernel *kernel, uint32_t argID);
#ifdef __cplusplus
}
namespace gbe {
namespace gen {
- struct KernelArgument
- {
+ struct KernelArgument {
GenArgType type; //!< Pointer, structure, regular value?
size_t size; //!< Size of each argument
};
struct Kernel : public NonCopyable
{
/*! Create an empty kernel with the given name */
- Kernel(void);
+ Kernel(const std::string &name);
/*! Destroy it */
~Kernel(void);
-
+ /*! Return the instruction stream */
+ INLINE const char *getCode(void) const { return (const char*) insns; }
+ /*! Return the instruction stream size */
+ INLINE size_t getCodeSize(void) const {
+ return insnNum * sizeof(brw_instruction);
+ }
+ /*! Return the number of arguments for the kernel call */
+ INLINE uint32_t getArgNum(void) const { return argNum; }
+ /*! Return the size of the given argument */
+ INLINE uint32_t getArgSize(uint32_t argID) const {
+ if (argID >= argNum)
+ return 0u;
+ else
+ return args[argID].size;
+ }
+ /*! Return the type of the given argument */
+ INLINE GenArgType getArgType(uint32_t argID) const {
+ if (argID >= argNum)
+ return GEN_ARG_INVALID;
+ else
+ return args[argID].type;
+ }
+ private:
+ friend class Program; //!< Owns the kernels
std::string name; //!< Kernel name
KernelArgument *args; //!< Each argument
brw_instruction *insns; //!< Instruction stream
Program(void);
/*! Destroy the program */
~Program(void);
+ /*! Get the number of kernels in the program */
+ uint32_t getKernelNum(void) const { return kernels.size(); }
+ /*! Get the kernel from its name */
+ Kernel *getKernel(const std::string &name) const {
+ auto it = kernels.find(name);
+ if (it == kernels.end())
+ return NULL;
+ else
+ return it->second;
+ }
/*! Build a program from a ir::Unit */
bool buildFromUnit(const ir::Unit &unit, std::string &error);
/*! Buils a program from a LLVM source code */
bool buildFromLLVMFile(const char *fileName, std::string &error);
/*! Buils a program from a OCL string */
bool buildFromSource(const char *source, std::string &error);
+ private:
/*! Kernels sorted by their name */
hash_map<std::string, Kernel*> kernels;
};
class Unit : public NonCopyable
{
public:
+ typedef hash_map<std::string, Function*> FunctionSet;
/*! Create an empty unit */
Unit(PointerSize pointerSize = POINTER_32_BITS);
/*! Release everything (*including* the function pointers) */
~Unit(void);
+ /*! Get the set of functions defined in the unit */
+ const FunctionSet &getFunctionSet(void) const { return functions; }
/*! Retrieve the function by its name */
Function *getFunction(const std::string &name) const;
/*! Return NULL if the function already exists */
static MemDebugger *memDebugger = NULL;
/*! Monitor maximum memory requirement in the compiler */
- static MutexSys sizeMutex;
+ static MutexSys *sizeMutex = NULL;
+ static bool isMutexInitializing = true;
static size_t memDebuggerCurrSize(0u);
static size_t memDebuggerMaxSize(0u);
+ static void SizeMutexDeallocate(void) { if (sizeMutex) delete sizeMutex; }
+ static void SizeMutexAllocate(void) {
+ if (sizeMutex == NULL && isMutexInitializing == false) {
+ isMutexInitializing = true;
+ sizeMutex = new MutexSys;
+ atexit(SizeMutexDeallocate);
+ }
+ }
/*! Stop the memory debugger */
static void MemDebuggerEnd(void) {
void *ptr = std::malloc(size + sizeof(size_t));
*(size_t *) ptr = size;
MemDebuggerInitializeMem((char*) ptr + sizeof(size_t), size);
- sizeMutex.lock();
+ SizeMutexAllocate();
+ if (sizeMutex) sizeMutex->lock();
memDebuggerCurrSize += size;
memDebuggerMaxSize = std::max(memDebuggerCurrSize, memDebuggerMaxSize);
- sizeMutex.unlock();
+ if (sizeMutex) sizeMutex->unlock();
return (char *) ptr + sizeof(size_t);
}
void memFree(void *ptr) {
char *toFree = (char*) ptr - sizeof(size_t);
const size_t size = *(size_t *) toFree;
MemDebuggerInitializeMem(ptr, size);
- sizeMutex.lock();
+ SizeMutexAllocate();
+ if (sizeMutex) sizeMutex->lock();
memDebuggerCurrSize -= size;
- sizeMutex.unlock();
+ if (sizeMutex) sizeMutex->unlock();
std::free(toFree);
}
}
((void**)aligned)[-1] = mem;
((uintptr_t*)aligned)[-2] = uintptr_t(size);
MemDebuggerInitializeMem(aligned, size);
- sizeMutex.lock();
+ SizeMutexAllocate();
+ if (sizeMutex) sizeMutex->lock();
memDebuggerCurrSize += size;
memDebuggerMaxSize = std::max(memDebuggerCurrSize, memDebuggerMaxSize);
- sizeMutex.unlock();
+ if (sizeMutex) sizeMutex->unlock();
return aligned;
}
const size_t size = ((uintptr_t*)ptr)[-2];
MemDebuggerInitializeMem(ptr, size);
free(((void**)ptr)[-1]);
- sizeMutex.lock();
+ SizeMutexAllocate();
+ if (sizeMutex) sizeMutex->lock();
memDebuggerCurrSize -= size;
- sizeMutex.unlock();
+ if (sizeMutex) sizeMutex->unlock();
}
}
} /* namespace gbe */
/*! Declare a structure with custom allocators */
#define GBE_STRUCT(TYPE) \
+public: \
void* operator new(size_t size) { \
if (AlignOf<TYPE>::value > sizeof(uintptr_t)) \
return gbe::alignedMalloc(size, AlignOf<TYPE>::value); \
/*! Declare a class with custom allocators */
#define GBE_CLASS(TYPE) \
-public: \
GBE_STRUCT(TYPE) \
private: