Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: src/IceDefs.h

Issue 1776473007: Subzero. Allocate global initializers from a dedicated arena. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fixes ther llvm2ice converter; fixes the VariableDeclarationList destructor. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceDefs.h
diff --git a/src/IceDefs.h b/src/IceDefs.h
index d9c0c234784e0d569ae6c83ed109bb981d37749f..10350a2f076ceb28d95ef4b202d07fe906b2da35 100644
--- a/src/IceDefs.h
+++ b/src/IceDefs.h
@@ -73,6 +73,11 @@ class Variable;
class VariableDeclaration;
class VariablesMetadata;
+/// SizeT is for holding small-ish limits like number of source operands in an
+/// instruction. It is used instead of size_t (which may be 64-bits wide) when
+/// we want to save space.
+using SizeT = uint32_t;
+
constexpr char GlobalOffsetTable[] = "_GLOBAL_OFFSET_TABLE_";
// makeUnique should be used when memory is expected to be allocated from the
// heap (as opposed to allocated from some Allocator.) It is intended to be
@@ -139,12 +144,126 @@ using NodeList = CfgVector<CfgNode *>;
// Containers that use the default (global) allocator.
using ConstantList = std::vector<Constant *>;
using FunctionDeclarationList = std::vector<FunctionDeclaration *>;
-using VariableDeclarationList = std::vector<VariableDeclaration *>;
-/// SizeT is for holding small-ish limits like number of source operands in an
-/// instruction. It is used instead of size_t (which may be 64-bits wide) when
-/// we want to save space.
-using SizeT = uint32_t;
+/// VariableDeclarationList is a container for holding VariableDeclarations --
Jim Stichnoth 2016/03/14 22:21:31 Can this go somewhere besides IceDefs.h?
John 2016/03/15 15:07:18 It **should**, but because IceDefs moving it to a
Jim Stichnoth 2016/03/15 15:48:29 Ick ick ick, but whatevs. :)
+/// i.e., Global Variables. It is also used to create said variables, and their
+/// initializers in an arena.
+class VariableDeclarationList {
+ VariableDeclarationList(const VariableDeclarationList &) = delete;
+ VariableDeclarationList &operator=(const VariableDeclarationList &) = delete;
+ VariableDeclarationList(VariableDeclarationList &&) = delete;
+ VariableDeclarationList &operator=(VariableDeclarationList &&) = delete;
+
+public:
+ using VariableDeclarationArray = std::vector<VariableDeclaration *>;
+
+ VariableDeclarationList() : Arena(new ArenaAllocator()) {}
+
+ ~VariableDeclarationList() { clearAndPurge(); }
+
+ template <typename T> T *allocate_initializer(SizeT Count = 1) {
+ static_assert(
+ std::is_trivially_destructible<T>::value,
+ "allocate_initializer can only allocate trivially destructible types.");
+ return Arena->Allocate<T>(Count);
+ }
+
+ template <typename T> T *allocate_variable_declaration() {
+ static_assert(!std::is_trivially_destructible<T>::value,
+ "allocate_variable_declaration expects non-trivially "
+ "destructible types.");
+ T *Ret = Arena->Allocate<T>();
+ Dtors.emplace_back([Ret]() { Ret->~T(); });
+ return Ret;
+ }
+
+ // This do nothing method is invoked when a global variable is created, but it
+ // will not be emitted. If we ever need to track the created variabled, having
+ // this hook is handy.
+ void willNotBeEmitted(VariableDeclaration *) {}
+
+ /// Merges Other with this, effectively resetting Other to an empty state.
+ void merge(VariableDeclarationList *Other) {
+ assert(Other != nullptr);
+ addArena(std::move(Other->Arena));
+ for (std::size_t i = 0; i < Other->MergedArenas.size(); ++i) {
+ addArena(std::move(Other->MergedArenas[i]));
+ }
+ Other->MergedArenas.clear();
+
+ Dtors.insert(Dtors.end(), Other->Dtors.begin(), Other->Dtors.end());
+ Other->Dtors.clear();
+
+ Globals.insert(Globals.end(), Other->Globals.begin(), Other->Globals.end());
+ Other->Globals.clear();
+ }
+
+ /// Destroys all GlobalVariables and initializers that this knows about
+ /// (including those merged with it), and releases memory.
+ void clearAndPurge() {
+ if (Arena == nullptr) {
+ // Arena is only null if this was merged, so we ensure there's no state
+ // being held by this.
+ assert(Dtors.empty());
+ assert(Globals.empty());
+ assert(MergedArenas.empty());
+ return;
+ }
+ // Invokes destructors in reverse creation order.
+ for (auto Dtor = Dtors.rbegin(); Dtor != Dtors.rend(); ++Dtor) {
+ (*Dtor)();
+ }
+ Dtors.clear();
+ Globals.clear();
+ MergedArenas.clear();
+ Arena->Reset();
+ }
+
+ /// Vector<VariableDeclaration *> interface.
Jim Stichnoth 2016/03/14 22:21:31 I assume this comment means either "VariableDeclar
John 2016/03/15 15:07:18 Done.
+ /// @{
+ VariableDeclarationArray::iterator begin() { return Globals.begin(); }
+
+ VariableDeclarationArray::iterator end() { return Globals.end(); }
+
+ VariableDeclarationArray::const_iterator begin() const {
+ return Globals.begin();
+ }
+
+ VariableDeclarationArray::const_iterator end() const { return Globals.end(); }
+
+ bool empty() const { return Globals.empty(); }
+
+ VariableDeclarationArray::size_type size() const { return Globals.size(); }
+
+ VariableDeclarationArray::reference
+ at(VariableDeclarationArray::size_type Pos) {
+ return Globals.at(Pos);
+ }
+
+ void push_back(VariableDeclaration *Global) { Globals.push_back(Global); }
+
+ void reserve(VariableDeclarationArray::size_type Capacity) {
+ Globals.reserve(Capacity);
+ }
+
+ void clear() { Globals.clear(); }
+
+ VariableDeclarationArray::reference back() { return Globals.back(); }
+ /// @}
+
+private:
+ using ArenaPtr = std::unique_ptr<ArenaAllocator>;
+ using DestructorsArray = std::vector<std::function<void()>>;
+
+ void addArena(ArenaPtr NewArena) {
+ MergedArenas.emplace_back(std::move(NewArena));
+ }
+
+ ArenaPtr Arena;
+ VariableDeclarationArray Globals;
+ DestructorsArray Dtors;
+ std::vector<ArenaPtr> MergedArenas;
+};
/// InstNumberT is for holding an instruction number. Instruction numbers are
/// used for representing Variable live ranges.
« src/IceCompiler.cpp ('K') | « src/IceConverter.cpp ('k') | src/IceELFObjectWriter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698