Fix the mutex diagnostics, and other targets of opportunity.
Three changes for the price of one:
1. Fix the mutex diagnostics so they work right during startup and shutdown.
2. Fix a memory leak in common_test.
3. Fix memory corruption in the compiler; we were calling memset(3) on a struct
with non-POD members.
Thanks, as usual, to valgrind(1) for the latter two (and several bugs in
earlier attempts at the former).
Change-Id: I15e1ffb01e73e4c56a5bbdcaa7233a4b5221e08a
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index 4b4e83d..6d62f29 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -111,8 +111,6 @@
kNumBitMapKinds
};
-extern uint32_t compilerOptimizerDisableFlags;
-
/* Force code generation paths for testing */
enum debugControlVector {
kDebugDisplayMissingTargets,
@@ -131,14 +129,6 @@
kDebugCountOpcodes,
};
-extern uint32_t compilerDebugFlags;
-
-/* If non-empty, apply optimizer/debug flags only to matching methods */
-extern std::string compilerMethodMatch;
-
-/* Flips sense of compilerMethodMatch - apply flags if doesn't match */
-extern bool compilerFlipMatch;
-
enum OatMethodAttributes {
kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */
kIsHot, /* Code is part of a hot trace */
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 621cccc..0fc26de 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -290,7 +290,100 @@
#define NOTVISITED (-1)
struct CompilationUnit {
- int numInsts;
+ CompilationUnit()
+ : numBlocks(0),
+ compiler(NULL),
+ class_linker(NULL),
+ dex_file(NULL),
+ dex_cache(NULL),
+ class_loader(NULL),
+ method_idx(0),
+ code_item(NULL),
+ access_flags(0),
+ shorty(NULL),
+ firstLIRInsn(NULL),
+ lastLIRInsn(NULL),
+ literalList(NULL),
+ methodLiteralList(NULL),
+ codeLiteralList(NULL),
+ classPointerList(NULL),
+ numClassPointers(0),
+ chainCellOffsetLIR(NULL),
+ disableOpt(0),
+ enableDebug(0),
+ headerSize(0),
+ dataOffset(0),
+ totalSize(0),
+ assemblerStatus(kSuccess),
+ assemblerRetries(0),
+ genDebugger(false),
+ printMe(false),
+ hasClassLiterals(false),
+ hasLoop(false),
+ hasInvoke(false),
+ heapMemOp(false),
+ qdMode(false),
+ usesLinkRegister(false),
+ methodTraceSupport(false),
+ regPool(NULL),
+ optRound(0),
+ instructionSet(kNone),
+ numSSARegs(0),
+ ssaBaseVRegs(NULL),
+ ssaSubscripts(NULL),
+ vRegToSSAMap(NULL),
+ SSALastDefs(NULL),
+ isConstantV(NULL),
+ constantValues(NULL),
+ phiAliasMap(NULL),
+ phiList(NULL),
+ regLocation(NULL),
+ sequenceNumber(0),
+ promotionMap(NULL),
+ methodSReg(0),
+ switchOverflowPad(NULL),
+ numReachableBlocks(0),
+ numDalvikRegisters(0),
+ entryBlock(NULL),
+ exitBlock(NULL),
+ curBlock(NULL),
+ nextCodegenBlock(NULL),
+ iDomList(NULL),
+ tryBlockAddr(NULL),
+ defBlockMatrix(NULL),
+ tempBlockV(NULL),
+ tempDalvikRegisterV(NULL),
+ tempSSARegisterV(NULL),
+ printSSANames(false),
+ blockLabelList(NULL),
+ quitLoopMode(false),
+ preservedRegsUsed(0),
+ numIns(0),
+ numOuts(0),
+ numRegs(0),
+ numCoreSpills(0),
+ numFPSpills(0),
+ numCompilerTemps(0),
+ frameSize(0),
+ coreSpillMask(0U),
+ fpSpillMask(0U),
+ attrs(0U),
+ currentDalvikOffset(0),
+ insns(NULL),
+ insnsSize(0U),
+ disableDataflow(false),
+ defCount(0),
+ compilerFlipMatch(false),
+ arenaHead(NULL),
+ currentArena(NULL),
+ numArenaBlocks(0),
+ mstats(NULL),
+ opcodeCount(NULL) {
+#if !defined(NDEBUG)
+ liveSReg = 0;
+#endif
+ }
+
int numBlocks;
GrowableList blockList;
Compiler* compiler; // Compiler driving this compiler
@@ -420,22 +513,25 @@
* The low-level LIR creation utilites will pull it from here. Should
* be rewritten.
*/
- int currentDalvikOffset;
- GrowableList switchTables;
- GrowableList fillArrayData;
- const u2* insns;
- u4 insnsSize;
- bool disableDataflow; // Skip dataflow analysis if possible
- std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
- std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
- int defCount; // Used to estimate number of SSA names
- std::string* compilerMethodMatch;
- bool compilerFlipMatch;
- struct ArenaMemBlock* arenaHead;
- struct ArenaMemBlock* currentArena;
- int numArenaBlocks;
- struct Memstats* mstats;
- int* opcodeCount; // Count Dalvik opcodes for tuning
+ int currentDalvikOffset;
+ GrowableList switchTables;
+ GrowableList fillArrayData;
+ const u2* insns;
+ u4 insnsSize;
+ bool disableDataflow; // Skip dataflow analysis if possible
+ std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
+ std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
+ int defCount; // Used to estimate number of SSA names
+
+ // If non-empty, apply optimizer/debug flags only to matching methods.
+ std::string compilerMethodMatch;
+ // Flips sense of compilerMethodMatch - apply flags if doesn't match.
+ bool compilerFlipMatch;
+ struct ArenaMemBlock* arenaHead;
+ struct ArenaMemBlock* currentArena;
+ int numArenaBlocks;
+ struct Memstats* mstats;
+ int* opcodeCount; // Count Dalvik opcodes for tuning
#ifndef NDEBUG
/*
* Sanity checking for the register temp tracking. The same ssa
diff --git a/src/compiler/CompilerUtility.h b/src/compiler/CompilerUtility.h
index 41f6cf1..f7b9b0e 100644
--- a/src/compiler/CompilerUtility.h
+++ b/src/compiler/CompilerUtility.h
@@ -43,11 +43,14 @@
void oatArenaReset(CompilationUnit *cUnit);
struct GrowableList {
- size_t numAllocated;
- size_t numUsed;
- intptr_t *elemList;
+ GrowableList() : numAllocated(0), numUsed(0), elemList(NULL) {
+ }
+
+ size_t numAllocated;
+ size_t numUsed;
+ intptr_t* elemList;
#ifdef WITH_MEMSTATS
- oatListKind kind;
+ oatListKind kind;
#endif
};
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 74c13d4..309bcf8 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -24,7 +24,7 @@
namespace art {
/* Default optimizer/debug setting for the compiler. */
-uint32_t compilerOptimizerDisableFlags = 0 | // Disable specific optimizations
+static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
//(1 << kLoadStoreElimination) |
//(1 << kLoadHoisting) |
//(1 << kSuppressLoads) |
@@ -38,7 +38,7 @@
//(1 << kPromoteCompilerTemps) |
0;
-uint32_t compilerDebugFlags = 0 | // Enable debug/testing modes
+static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
//(1 << kDebugDisplayMissingTargets) |
//(1 << kDebugVerbose) |
//(1 << kDebugDumpCFG) |
@@ -751,7 +751,6 @@
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
UniquePtr<CompilationUnit> cUnit(new CompilationUnit);
- memset(cUnit.get(), 0, sizeof(*cUnit));
oatInit(cUnit.get(), compiler);
@@ -771,20 +770,14 @@
cUnit->numOuts = code_item->outs_size_;
/* Adjust this value accordingly once inlining is performed */
cUnit->numDalvikRegisters = code_item->registers_size_;
- cUnit->blockMap = std::map<unsigned int, BasicBlock*>();
- cUnit->blockMap.clear();
- cUnit->boundaryMap = std::map<unsigned int, LIR*>();
- cUnit->boundaryMap.clear();
- // TODO: set these from command line
- cUnit->compilerMethodMatch = new std::string("");
+ // TODO: set this from command line
cUnit->compilerFlipMatch = false;
- bool useMatch = cUnit->compilerMethodMatch->length() != 0;
+ bool useMatch = !cUnit->compilerMethodMatch.empty();
bool match = useMatch && (cUnit->compilerFlipMatch ^
- (PrettyMethod(method_idx, dex_file).find(*cUnit->compilerMethodMatch)
- != std::string::npos));
+ (PrettyMethod(method_idx, dex_file).find(cUnit->compilerMethodMatch) != std::string::npos));
if (!useMatch || match) {
- cUnit->disableOpt = compilerOptimizerDisableFlags;
- cUnit->enableDebug = compilerDebugFlags;
+ cUnit->disableOpt = kCompilerOptimizerDisableFlags;
+ cUnit->enableDebug = kCompilerDebugFlags;
cUnit->printMe = VLOG_IS_ON(compiler) || (cUnit->enableDebug & (1 << kDebugVerbose));
}
if (cUnit->instructionSet == kX86) {
@@ -806,7 +799,7 @@
}
/* Gathering opcode stats? */
- if (compilerDebugFlags & (1 << kDebugCountOpcodes)) {
+ if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
cUnit->opcodeCount = (int*)oatNew(cUnit.get(),
kNumPackedOpcodes * sizeof(int), true, kAllocMisc);
}