OSDN Git Service

Fix initializing the allocator before creating empty vector.
authorNicolas Capens <capn@google.com>
Tue, 6 Sep 2016 16:59:58 +0000 (12:59 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 9 Sep 2016 14:14:31 +0000 (14:14 +0000)
MSVC's implementation of the STL allocates memory even for an empty
vector. Since we're using a custom thread-local allocator, it should
be initialized before any STL member containers get initialized.

BUG=swiftshader:7

Change-Id: I4bd977e7ee8eb87006fe08b051cbcfc9bc62342b
Reviewed-on: https://chromium-review.googlesource.com/381531
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
src/IceCfg.cpp
src/IceCfg.h
src/IceMemory.cpp
src/IceMemory.h

index 6e944ac..ef775fe 100644 (file)
@@ -22,8 +22,8 @@
 #include "IceELFObjectWriter.h"
 #include "IceGlobalInits.h"
 #include "IceInst.h"
-#include "IceInstrumentation.h"
 #include "IceInstVarIter.h"
+#include "IceInstrumentation.h"
 #include "IceLiveness.h"
 #include "IceLoopAnalyzer.h"
 #include "IceOperand.h"
@@ -35,9 +35,9 @@
 namespace Ice {
 
 Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
-    : Ctx(Ctx), SequenceNumber(SequenceNumber), VMask(getFlags().getVerbose()),
-      FunctionName(), NextInstNumber(Inst::NumberInitial), Live(nullptr) {
-  Allocator.reset(new ArenaAllocator());
+    : Allocator(createAllocator()), Ctx(Ctx), SequenceNumber(SequenceNumber),
+      VMask(getFlags().getVerbose()), FunctionName(),
+      NextInstNumber(Inst::NumberInitial), Live(nullptr) {
   NodeStrings.reset(new StringPool);
   VarStrings.reset(new StringPool);
   CfgLocalAllocatorScope _(this);
@@ -65,6 +65,15 @@ Cfg::~Cfg() {
   }
 }
 
+// Called in the initalizer list of Cfg's constructor to create the Allocator
+// and set it as TLS before any other member fields are constructed, since they
+// may depend on it.
+ArenaAllocator *Cfg::createAllocator() {
+  ArenaAllocator *Allocator = new ArenaAllocator();
+  CfgAllocatorTraits::set_current(Allocator);
+  return Allocator;
+}
+
 /// Create a string like "foo(i=123:b=9)" indicating the function name, number
 /// of high-level instructions, and number of basic blocks.  This string is only
 /// used for dumping and other diagnostics, and the idea is that given a set of
index 933d64c..3a3dcbf 100644 (file)
@@ -31,6 +31,8 @@ class Cfg {
   Cfg(const Cfg &) = delete;
   Cfg &operator=(const Cfg &) = delete;
 
+  std::unique_ptr<ArenaAllocator> Allocator;
+
 public:
   ~Cfg();
 
@@ -306,6 +308,8 @@ private:
   CfgVector<Inst *>
   findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body);
 
+  static ArenaAllocator *createAllocator();
+
   GlobalContext *Ctx;
   uint32_t SequenceNumber; /// output order for emission
   OptLevel OptimizationLevel = Opt_m1;
@@ -323,7 +327,6 @@ private:
   VarList Variables;
   VarList Args;         /// subset of Variables, in argument order
   VarList ImplicitArgs; /// subset of Variables
-  std::unique_ptr<ArenaAllocator> Allocator;
   // Separate string pools for CfgNode and Variable names, due to a combination
   // of the uniqueness requirement, and assumptions in lit tests.
   std::unique_ptr<StringPool> NodeStrings;
index 57c969e..0026661 100644 (file)
@@ -31,9 +31,17 @@ CfgAllocatorTraits::allocator_type CfgAllocatorTraits::current() {
 void CfgAllocatorTraits::set_current(const manager_type *Manager) {
   ArenaAllocator *Allocator =
       Manager == nullptr ? nullptr : Manager->Allocator.get();
+  set_current(Allocator);
+}
+
+void CfgAllocatorTraits::set_current(ArenaAllocator *Allocator) {
   ICE_TLS_SET_FIELD(CfgAllocator, Allocator);
 }
 
+void CfgAllocatorTraits::set_current(nullptr_t) {
+  ICE_TLS_SET_FIELD(CfgAllocator, nullptr);
+}
+
 ICE_TLS_DEFINE_FIELD(ArenaAllocator *, LivenessAllocatorTraits,
                      LivenessAllocator);
 
index 7fff65c..366c49d 100644 (file)
@@ -143,6 +143,8 @@ public:
 
   static allocator_type current();
   static void set_current(const manager_type *Manager);
+  static void set_current(ArenaAllocator *Allocator);
+  static void set_current(nullptr_t);
 
 private:
   ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator);