Yet more work on eng::malloc

This commit is contained in:
2022-03-02 14:52:51 -05:00
parent 7cd8eb0a43
commit cf102a6250
25 changed files with 114 additions and 59 deletions

View File

@@ -9,8 +9,6 @@ grep std::unordered_set cpp/*
grep std::deque cpp/* grep std::deque cpp/*
grep std::ostringstream cpp/* grep std::ostringstream cpp/*
grep std::ostream cpp/* grep std::ostream cpp/*
grep std::unique_ptr cpp/*
grep std::shared_ptr cpp/*
grep std::cerr cpp/* grep std::cerr cpp/*
grep std::cout cpp/* grep std::cout cpp/*

View File

@@ -57,7 +57,7 @@
#include <cassert> #include <cassert>
#include <ostream> #include <ostream>
class AnimStep { class AnimStep : public eng::nevernew {
friend class AnimQueue; friend class AnimQueue;
public: public:
enum { enum {
@@ -166,7 +166,7 @@ private:
}; };
class AnimQueue { class AnimQueue : public eng::nevernew {
public: public:
// World type determines whether versions increment or autozero // World type determines whether versions increment or autozero
AnimQueue(util::WorldType wt); AnimQueue(util::WorldType wt);

View File

@@ -8,7 +8,7 @@
#include <ostream> #include <ostream>
#include <memory> #include <memory>
class DebugCollector { class DebugCollector : public eng::nevernew {
private: private:
// At any given time, the stringstream may contain one // At any given time, the stringstream may contain one
// extra line that hasn't yet been appended to the list of lines. // extra line that hasn't yet been appended to the list of lines.
@@ -33,7 +33,7 @@ public:
friend class DebugBlock; friend class DebugBlock;
}; };
class DebugBlock { class DebugBlock : public eng::nevernew {
private: private:
DebugCollector *dbc_; DebugCollector *dbc_;
int n_regular_; int n_regular_;

View File

@@ -106,7 +106,7 @@ class DrivenEngine;
using UniqueDrivenEngine = std::unique_ptr<DrivenEngine>; using UniqueDrivenEngine = std::unique_ptr<DrivenEngine>;
using DrivenEngineMaker = UniqueDrivenEngine (*)(); using DrivenEngineMaker = UniqueDrivenEngine (*)();
class Channel { class Channel : public eng::opnew {
public: public:
// Get the buffers associated with this channel. // Get the buffers associated with this channel.
// //
@@ -190,7 +190,7 @@ private:
using SharedChannel = std::shared_ptr<Channel>; using SharedChannel = std::shared_ptr<Channel>;
class DrivenEngine { class DrivenEngine : public eng::opnew {
public: public:
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// //

View File

@@ -13,27 +13,27 @@
// In order to get all engine data structures into the eng::malloc heap, you // In order to get all engine data structures into the eng::malloc heap, you
// need to jump through quite a few hoops: // need to jump through quite a few hoops:
// //
// * When using STL classes, you need to use the 'eng' variant of those classes: // * When writing a class, always derive from eng::opnew. This adds a
// custom operator new to your class, which causes your class to be
// allocated using eng::malloc.
// //
// - eng::string instead of std::string (include "wrap-string.hpp") // * When using STL containers, you need to use the eng variant:
// - eng::vector instead of std::vector (include "wrap-vector.hpp") // eng::map, eng::set, eng::vector, eng::unordered_map, eng::unordered_set,
// - eng::map instead of std::map (include "wrap-map.hpp") // and eng::deque. These classes derive from eng::opnew, and they also
// - etc. // use eng::malloc for their internal nodes.
// //
// These eng classes allocate memory using eng::malloc instead of malloc. // * Use eng::string instead of std::string. Use eng::ostringstream
// // instead of std::ostringstream.
// * All your classes must derive from eng::opnew. This adds a custom operator
// new and operator delete to your class, which allocate using eng::malloc.
//
// * Use eng::make_shared and eng::make_unique instead of std::make_shared and
// std::make_unique.
// //
// * Simple classes like std::pair, std::string_view, std::less, std::hash, and // * Simple classes like std::pair, std::string_view, std::less, std::hash, and
// so forth don't allocate memory. Those classes are not wrapped. There is // so forth are not wrapped. Do not use operator new or delete on
// no eng::pair, eng::less, etc. // these classes.
//
// * Instead of std::make_shared, use eng::make_shared. You need this
// because std::make_shared doesn't respect your custom operator new.
// //
// * Be aware that most C++ streams use the system malloc heap, and there's no // * Be aware that most C++ streams use the system malloc heap, and there's no
// way to change that. Fortunately, eng::ostringstream uses the dlmalloc // way to change that. Fortunately, eng::ostringstream uses the eng::malloc
// heap. // heap.
// //
// * Failing to jump through all these hoops won't break your code in any // * Failing to jump through all these hoops won't break your code in any
@@ -46,6 +46,7 @@
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
#include <cassert>
namespace eng { namespace eng {
#ifdef __linux__ #ifdef __linux__
@@ -126,21 +127,60 @@ namespace eng {
{ {
return ::eng::free(p); return ::eng::free(p);
} }
void *operator new[](size_t size)
{
return ::eng::malloc(size);
}
void operator delete[](void *p, size_t size)
{
return ::eng::free(p);
}
}; };
} // namespace eng } // namespace eng
// eng::nevernew. A class containing private operator new and
// operator delete, making it impossible to 'new' the class.
namespace eng {
class nevernew {
private:
void *operator new(size_t size)
{
assert(false && "not supposed to 'new' this class");
return NULL;
}
void operator delete(void *p, size_t size)
{
assert(false && "not supposed to 'delete' this class");
}
void *operator new[](size_t size)
{
assert(false && "not supposed to 'new' this class");
return NULL;
}
void operator delete[](void *p, size_t size)
{
assert(false && "not supposed to 'delete' this class");
}
};
} // namespace eng
// eng::make_shared allocates shared objects using eng::malloc. // eng::make_shared allocates shared objects using eng::malloc.
namespace eng { namespace eng {
template<class T, class... Args> template<class T, class... Args>
inline ::std::shared_ptr<T> make_shared(Args&&... args) { inline ::std::shared_ptr<T> make_shared(Args&&... args) {
static eng::allocator<T> alloc; return std::allocate_shared<T>(eng::allocator<T>(), args...);
return std::allocate_shared<T>(alloc, args...);
}
} }
} // namespace eng
// eng::make_unique doesn't do anything different than std::make_unique: // eng::make_unique doesn't do anything different than std::make_unique: they
// they both use operator new and delete. You must // both use operator new and delete. You must derive from eng::opnew to change
// derive from eng::opnew to change operator new and delete. // operator new and delete.
namespace eng { namespace eng {
template<class T, class... Args> template<class T, class... Args>
inline ::std::unique_ptr<T> make_unique(Args&&... args) { inline ::std::unique_ptr<T> make_unique(Args&&... args) {

View File

@@ -8,7 +8,7 @@
#include "luastack.hpp" #include "luastack.hpp"
#include "streambuffer.hpp" #include "streambuffer.hpp"
class GuiElt { class GuiElt : public eng::nevernew {
friend class Gui; friend class Gui;
public: public:
enum Type { enum Type {
@@ -27,7 +27,7 @@ public:
const eng::string &label() const { return label_; } const eng::string &label() const { return label_; }
}; };
class Gui { class Gui : public eng::nevernew {
public: public:
using EltVec = eng::vector<GuiElt>; using EltVec = eng::vector<GuiElt>;
private: private:

View File

@@ -75,7 +75,7 @@
#include <cstdint> #include <cstdint>
#include <ostream> #include <ostream>
class IdGlobalPool { class IdGlobalPool : public eng::nevernew {
public: public:
// Construct and destroy global pools. Note that after constructing // Construct and destroy global pools. Note that after constructing
// a global pool, it is generally also necessary to initialize it // a global pool, it is generally also necessary to initialize it
@@ -119,7 +119,7 @@ private:
friend int unittests_idalloc(lua_State *L); friend int unittests_idalloc(lua_State *L);
}; };
class IdPlayerPool { class IdPlayerPool : public eng::nevernew {
public: public:
// Construct a player pool. // Construct a player pool.
// //

View File

@@ -16,7 +16,7 @@ public:
void deserialize(StreamBuffer *sb); void deserialize(StreamBuffer *sb);
}; };
class Invocation { class Invocation : public eng::nevernew {
public: public:
enum Kind { enum Kind {
KIND_INVALID, KIND_INVALID,

View File

@@ -47,7 +47,7 @@
#include "luastack.hpp" #include "luastack.hpp"
class LuaConsole { class LuaConsole : public eng::nevernew {
public: public:
using StringVec = eng::vector<eng::string>; using StringVec = eng::vector<eng::string>;

View File

@@ -17,7 +17,7 @@
#include "streambuffer.hpp" #include "streambuffer.hpp"
#include "luastack.hpp" #include "luastack.hpp"
class LuaSnap { class LuaSnap : public eng::nevernew {
private: private:
lua_State *state_; lua_State *state_;

View File

@@ -163,7 +163,7 @@ extern "C" {
#include "eris.h" #include "eris.h"
} }
class LuaSlot { class LuaSlot : public eng::nevernew {
protected: protected:
int index_; int index_;
private: private:
@@ -226,7 +226,7 @@ int LuaTypeTagValue(lua_State *L) { return 0; }
#define LUA_TT_GLOBALDB 22 #define LUA_TT_GLOBALDB 22
#define LUA_TT_CLASS 23 #define LUA_TT_CLASS 23
class LuaStack { class LuaStack : public eng::nevernew {
private: private:
int narg_; int narg_;
int ngap_; int ngap_;
@@ -470,7 +470,7 @@ public:
}; };
class LuaFunctionReg { class LuaFunctionReg : public eng::nevernew {
private: private:
const char *name_; const char *name_;
const char *args_; const char *args_;

View File

@@ -83,7 +83,7 @@
class PlaneMap; class PlaneMap;
class PlaneItem { class PlaneItem : public eng::nevernew {
friend class PlaneMap; friend class PlaneMap;
private: private:
@@ -112,7 +112,7 @@ public:
void set_xyz(float x, float y, float z) { set_pos(plane_, x, y, z); } void set_xyz(float x, float y, float z) { set_pos(plane_, x, y, z); }
}; };
class PlaneMap { class PlaneMap : public eng::nevernew {
friend class PlaneItem; friend class PlaneItem;
private: private:
using EltVec = eng::vector<PlaneItem *>; using EltVec = eng::vector<PlaneItem *>;

View File

@@ -89,7 +89,7 @@
struct PrintBufferCore; struct PrintBufferCore;
class PrintBuffer : public eng::opnew { class PrintBuffer : public eng::nevernew {
private: private:
PrintBufferCore *core_; PrintBufferCore *core_;
@@ -138,7 +138,7 @@ public:
}; };
class PrintChanneler : public eng::opnew { class PrintChanneler : public eng::nevernew {
private: private:
int64_t line_; int64_t line_;
public: public:

View File

@@ -7,7 +7,7 @@
#include <cstdint> #include <cstdint>
class SchedEntry { class SchedEntry : public eng::nevernew {
private: private:
friend class Schedule; friend class Schedule;
int64_t clock_; int64_t clock_;
@@ -30,7 +30,7 @@ public:
eng::string debug_string() const; eng::string debug_string() const;
}; };
class Schedule { class Schedule : public eng::nevernew {
private: private:
eng::set<SchedEntry> schedule_; eng::set<SchedEntry> schedule_;
public: public:

View File

@@ -127,7 +127,7 @@
#include "streambuffer.hpp" #include "streambuffer.hpp"
#include "debugcollector.hpp" #include "debugcollector.hpp"
class SourceDB { class SourceDB : public eng::nevernew {
private: private:
lua_State *lua_state_; lua_State *lua_state_;

View File

@@ -490,7 +490,7 @@ void *StreamBuffer::lua_reader_ud(int64_t size) {
return this; return this;
} }
class StreamBufferWriter : public std::streambuf { class StreamBufferWriter : public std::streambuf, public eng::opnew {
private: private:
StreamBuffer *target_; StreamBuffer *target_;
public: public:
@@ -504,7 +504,7 @@ public:
} }
}; };
class StreamBufferOStream : public std::ostream { class StreamBufferOStream : public std::ostream, public eng::opnew {
private: private:
StreamBufferWriter writer_; StreamBufferWriter writer_;
public: public:

View File

@@ -222,7 +222,7 @@
#include "luastack.hpp" #include "luastack.hpp"
#include "util.hpp" #include "util.hpp"
class StreamException class StreamException : public eng::nevernew
{ {
public: public:
virtual char const *what() const { return "General stream exception"; } virtual char const *what() const { return "General stream exception"; }
@@ -240,7 +240,7 @@ public:
virtual char const *what() const { return "Stream contained invalid data"; } virtual char const *what() const { return "Stream contained invalid data"; }
}; };
class StreamBuffer { class StreamBuffer : public eng::nevernew {
public: public:
// Construct an empty buffer. // Construct an empty buffer.
StreamBuffer(); StreamBuffer();

View File

@@ -24,7 +24,7 @@
class World; class World;
class Tangible { class Tangible : public eng::opnew {
private: private:
friend class World; friend class World;
@@ -90,7 +90,7 @@ public:
using UniqueTangible = std::unique_ptr<Tangible>; using UniqueTangible = std::unique_ptr<Tangible>;
class World { class World : public eng::opnew {
public: public:
using IdVector = util::IdVector; using IdVector = util::IdVector;
using TanVector = eng::vector<const Tangible*>; using TanVector = eng::vector<const Tangible*>;

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class T> template<class T>
using deque = std::deque<T, eng::allocator<T>>; class deque : public std::deque<T, eng::allocator<T>>, public eng::opnew {
using std::deque<T, eng::allocator<T>>::deque;
};
} // namespace eng } // namespace eng
#endif // WRAP_DEQUE_HPP #endif // WRAP_DEQUE_HPP

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class K, class V, class C=std::less<K>> template<class K, class V, class C=std::less<K>>
using map = std::map<K, V, C, eng::allocator<std::pair<const K, V>>>; class map : public std::map<K, V, C, eng::allocator<std::pair<const K, V>>>, eng::opnew {
using std::map<K, V, C, eng::allocator<std::pair<const K, V>>>::map;
};
} // namespace eng } // namespace eng
#endif // WRAP_MAP_HPP #endif // WRAP_MAP_HPP

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class K, class C=std::less<K>> template<class K, class C=std::less<K>>
using set = std::set<K, C, eng::allocator<K>>; class set : public std::set<K, C, eng::allocator<K>>, public eng::opnew {
using std::set<K, C, eng::allocator<K>>::set;
};
} // namespace eng } // namespace eng
#endif // WRAP_SET_HPP #endif // WRAP_SET_HPP

View File

@@ -2,11 +2,16 @@
#define WRAP_SSTREAM_HPP #define WRAP_SSTREAM_HPP
#include "eng-malloc.hpp" #include "eng-malloc.hpp"
#include "wrap-string.hpp"
#include <sstream> #include <sstream>
#include <string_view>
namespace eng { namespace eng {
template<class C, class T=std::char_traits<C>> template<class C, class T=std::char_traits<C>>
using basic_ostringstream = std::basic_ostringstream<C, T, eng::allocator<C>>; class basic_ostringstream : public std::basic_ostringstream<C, T, eng::allocator<C>>, public eng::opnew {
using underlying = std::basic_ostringstream<C, T, eng::allocator<C>>;
using underlying::basic_ostringstream;
};
using ostringstream = basic_ostringstream<char>; using ostringstream = basic_ostringstream<char>;
} // namespace eng } // namespace eng

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class K, class V, class H=std::hash<K>, class E=std::equal_to<K>> template<class K, class V, class H=std::hash<K>, class E=std::equal_to<K>>
using unordered_map = std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>; class unordered_map : public std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>, public eng::opnew {
using std::unordered_map<K, V, H, E, eng::allocator<std::pair<const K, V>>>::unordered_map;
};
} // namespace eng } // namespace eng
#endif // WRAP_UNORDERED_MAP_HPP #endif // WRAP_UNORDERED_MAP_HPP

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class K, class H=std::hash<K>, class E=std::equal_to<K>> template<class K, class H=std::hash<K>, class E=std::equal_to<K>>
using unordered_set = std::unordered_set<K, H, E, eng::allocator<K>>; class unordered_set : public std::unordered_set<K, H, E, eng::allocator<K>>, public eng::opnew {
using std::unordered_set<K, H, E, eng::allocator<K>>::unordered_set;
};
} // namespace eng } // namespace eng
#endif // WRAP_UNORDERED_SET_HPP #endif // WRAP_UNORDERED_SET_HPP

View File

@@ -6,7 +6,9 @@
namespace eng { namespace eng {
template<class T> template<class T>
using vector = std::vector<T, eng::allocator<T>>; class vector : public std::vector<T, eng::allocator<T>>, public eng::opnew {
using std::vector<T, eng::allocator<T>>::vector;
};
} // namespace eng } // namespace eng
#endif // WRAP_VECTOR_HPP #endif // WRAP_VECTOR_HPP