A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#ifndef __MINIZINC_GC_HH__ 13#define __MINIZINC_GC_HH__ 14 15#include <minizinc/config.hh> 16#include <minizinc/timer.hh> 17 18#include <cassert> 19#include <cstdlib> 20#include <new> 21#include <unordered_map> 22 23namespace MiniZinc { 24 25/** 26 * \brief Base class for abstract syntax tree nodes 27 */ 28class ASTNode { 29 friend class GC; 30 31protected: 32 /// Mark for garbage collection 33 mutable unsigned int _gc_mark : 1; 34 /// Id of the node 35 unsigned int _id : 7; 36 /// Secondary id 37 unsigned int _sec_id : 7; 38 /// Flag 39 unsigned int _flag_1 : 1; 40 /// Flag 41 unsigned int _flag_2 : 1; 42 /// Flag 43 unsigned int _flag_3 : 1; 44 /// Flag 45 unsigned int _flag_4 : 1; 46 47 enum BaseNodes { NID_FL, NID_CHUNK, NID_VEC, NID_END = NID_VEC }; 48 49 /// Constructor 50 ASTNode(unsigned int id) : _gc_mark(0), _id(id), _flag_1(0), _flag_2(0), _flag_3(0), _flag_4(0) {} 51 52public: 53 /// Allocate node 54 void* operator new(size_t size); 55 56 /// Placement-new 57 void* operator new(size_t, void* n) throw() { return n; } 58 59 /// Delete node (no-op) 60 void operator delete(void*, size_t) throw() {} 61 /// Delete node (no-op) 62 void operator delete(void*, void*) throw() {} 63 64 /// Delete node (no-op) 65 void operator delete(void*) throw() {} 66 67 /// Return state of first user-defined flag 68 bool user_flag0(void) const { return _flag_3; } 69 /// Set state of first user-defined flag 70 void user_flag0(bool b) { _flag_3 = b; } 71 /// Return state of second user-defined flag 72 bool user_flag1(void) const { return _flag_4; } 73 /// Set state of second user-defined flag 74 void user_flag1(bool b) { _flag_4 = b; } 75}; 76 77/** 78 * \brief Base class for unstructured garbage collected data 79 */ 80class ASTChunk : public ASTNode { 81 friend class GC; 82 83protected: 84 /// Allocated size 85 size_t _size; 86 /// Storage 87 char _data[4]; 88 /// Constructor 89 ASTChunk(size_t size); 90 /// Actual size of object in memory 91 size_t memsize(void) const { 92 size_t s = sizeof(ASTChunk) + (_size <= 4 ? 0 : _size - 4) * sizeof(char); 93 s += ((8 - (s & 7)) & 7); 94 return s; 95 } 96 /// Allocate raw memory 97 static void* alloc(size_t size); 98}; 99 100/** 101 * \brief Base class for structured garbage collected data 102 */ 103class ASTVec : public ASTNode { 104 friend class GC; 105 106protected: 107 /// Allocated size 108 size_t _size; 109 /// Storage 110 void* _data[2]; 111 /// Constructor 112 ASTVec(size_t size); 113 /// Actual size of object in memory 114 size_t memsize(void) const { 115 size_t s = sizeof(ASTVec) + (_size <= 2 ? 0 : _size - 2) * sizeof(void*); 116 s += ((8 - (s & 7)) & 7); 117 return s; 118 } 119 /// Allocate raw memory 120 static void* alloc(size_t size); 121}; 122 123class Model; 124class Expression; 125 126class KeepAlive; 127class WeakRef; 128 129class ASTNodeWeakMap; 130 131/// Garbage collector 132class GC { 133 friend class ASTNode; 134 friend class ASTVec; 135 friend class ASTChunk; 136 friend class KeepAlive; 137 friend class WeakRef; 138 friend class ASTNodeWeakMap; 139 140private: 141 class Heap; 142 /// The memory controlled by the collector 143 Heap* _heap; 144 /// Count how many locks are currently active 145 unsigned int _lock_count; 146 /// Timeout in milliseconds 147 unsigned long long int _timeout; 148 /// Counter for timeout 149 int _timeout_counter; 150 /// Timer for timeout 151 Timer _timeout_timer; 152 /// Return thread-local GC object 153 static GC*& gc(void); 154 /// Constructor 155 GC(void); 156 157 /// Allocate garbage collected memory 158 void* alloc(size_t size); 159 160 static void addKeepAlive(KeepAlive* e); 161 static void removeKeepAlive(KeepAlive* e); 162 static void addWeakRef(WeakRef* e); 163 static void removeWeakRef(WeakRef* e); 164 static void addNodeWeakMap(ASTNodeWeakMap* m); 165 static void removeNodeWeakMap(ASTNodeWeakMap* m); 166 167public: 168 /// Acquire garbage collector lock for this thread 169 static void lock(void); 170 /// Release garbage collector lock for this thread 171 static void unlock(void); 172 /// Manually trigger garbage collector (must be unlocked) 173 static void trigger(void); 174 /// Test if garbage collector is locked 175 static bool locked(void); 176 /// Add model \a m to root set 177 static void add(Model* m); 178 /// Remove model \a m from root set 179 static void remove(Model* m); 180 181 /// Put a mark on the trail 182 static void mark(void); 183 /// Add a trail entry 184 static void trail(Expression**, Expression*); 185 /// Untrail to previous mark 186 static void untrail(void); 187 188 /// Set timeout of \a t milliseconds, 0 means disable 189 static void setTimeout(unsigned long long int t); 190 191 /// Return maximum allocated memory (high water mark) 192 static size_t maxMem(void); 193}; 194 195/// Automatic garbage collection lock 196class GCLock { 197public: 198 /// Acquire lock 199 GCLock(void); 200 /// Release lock upon destruction 201 ~GCLock(void); 202}; 203 204/// Expression wrapper that is a member of the root set 205class KeepAlive { 206 friend class GC; 207 208private: 209 Expression* _e; 210 KeepAlive* _p; 211 KeepAlive* _n; 212 213public: 214 KeepAlive(Expression* e = NULL); 215 ~KeepAlive(void); 216 KeepAlive(const KeepAlive& e); 217 KeepAlive& operator=(const KeepAlive& e); 218 Expression* operator()(void) { return _e; } 219 Expression* operator()(void) const { return _e; } 220 KeepAlive* next(void) const { return _n; } 221}; 222 223/// Expression wrapper that is a member of the root set 224class WeakRef { 225 friend class GC; 226 227private: 228 Expression* _e; 229 WeakRef* _p; 230 WeakRef* _n; 231 bool _valid; 232 233public: 234 WeakRef(Expression* e = NULL); 235 ~WeakRef(void); 236 WeakRef(const WeakRef& e); 237 WeakRef& operator=(const WeakRef& e); 238 Expression* operator()(void) { return _valid ? _e : NULL; } 239 Expression* operator()(void) const { return _valid ? _e : NULL; } 240 WeakRef* next(void) const { return _n; } 241}; 242 243class ASTNodeWeakMap { 244 friend class GC; 245 246private: 247 ASTNodeWeakMap(const WeakRef& e); 248 ASTNodeWeakMap& operator=(const ASTNodeWeakMap& e); 249 250protected: 251 typedef std::unordered_map<ASTNode*, ASTNode*> NodeMap; 252 ASTNodeWeakMap* _p; 253 ASTNodeWeakMap* _n; 254 ASTNodeWeakMap* next(void) const { return _n; } 255 NodeMap _m; 256 257public: 258 ASTNodeWeakMap(void); 259 ~ASTNodeWeakMap(void); 260 void insert(ASTNode* n0, ASTNode* n1); 261 ASTNode* find(ASTNode* n); 262 void clear() { _m.clear(); } 263}; 264} // namespace MiniZinc 265 266#endif