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);
     }