1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef _MORKPOOL_
7 #define _MORKPOOL_ 1
8 
9 #ifndef _MORK_
10 #  include "mork.h"
11 #endif
12 
13 #ifndef _MORKDEQUE_
14 #  include "morkDeque.h"
15 #endif
16 
17 #ifndef _MORKNODE_
18 #  include "morkNode.h"
19 #endif
20 
21 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
22 
23 class morkHandle;
24 class morkHandleFrame;
25 class morkHandleFace;  // just an opaque cookie type
26 class morkBigBookAtom;
27 class morkFarBookAtom;
28 
29 #define morkDerived_kPool /*i*/ 0x706C /* ascii 'pl' */
30 
31 /*| morkPool: a place to manage pools of non-node objects that are memory
32 **| managed out of large chunks of space, so that per-object management
33 **| space overhead has no significant cost.
34 |*/
35 class morkPool : public morkNode {
36   // public: // slots inherited from morkNode (meant to inform only)
37   // nsIMdbHeap*       mNode_Heap;
38 
39   // mork_base      mNode_Base;     // must equal morkBase_kNode
40   // mork_derived   mNode_Derived;  // depends on specific node subclass
41 
42   // mork_access    mNode_Access;   // kOpen, kClosing, kShut, or kDead
43   // mork_usage     mNode_Usage;    // kHeap, kStack, kMember, kGlobal, kNone
44   // mork_able      mNode_Mutable;  // can this node be modified?
45   // mork_load      mNode_Load;     // is this node clean or dirty?
46 
47   // mork_uses      mNode_Uses;     // refcount for strong refs
48   // mork_refs      mNode_Refs;     // refcount for strong refs + weak refs
49 
50  public:  // state is public because the entire Mork system is private
51   nsIMdbHeap* mPool_Heap;  // NON-refcounted heap instance
52 
53   morkDeque mPool_Blocks;  // linked list of large blocks from heap
54 
55   // These two lists contain instances of morkHandleFrame:
56   morkDeque mPool_UsedHandleFrames;  // handle frames currently being used
57   morkDeque mPool_FreeHandleFrames;  // handle frames currently in free list
58 
59   mork_count mPool_UsedFramesCount;  // length of mPool_UsedHandleFrames
60   mork_count mPool_FreeFramesCount;  // length of mPool_UsedHandleFrames
61 
62   // { ===== begin morkNode interface =====
63  public:                                    // morkNode virtual methods
64   virtual void CloseMorkNode(morkEnv* ev);  // ClosePool() only if open
65   virtual ~morkPool();  // assert that ClosePool() executed earlier
66 
67  public:  // morkPool construction & destruction
68   morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
69            nsIMdbHeap* ioSlotHeap);
70   morkPool(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
71            nsIMdbHeap* ioSlotHeap);
72   void ClosePool(morkEnv* ev);  // called by CloseMorkNode();
73 
74  private:  // copying is not allowed
75   morkPool(const morkPool& other);
76   morkPool& operator=(const morkPool& other);
77 
78  public:  // dynamic type identification
IsPool()79   mork_bool IsPool() const {
80     return IsNode() && mNode_Derived == morkDerived_kPool;
81   }
82   // } ===== end morkNode methods =====
83 
84  public:  // typing
85   void NonPoolTypeError(morkEnv* ev);
86 
87  public:  // morkNode memory management operators
new(size_t inSize,nsIMdbHeap & ioHeap,morkEnv * ev)88   void* operator new(size_t inSize, nsIMdbHeap& ioHeap,
89                      morkEnv* ev) noexcept(true) {
90     return morkNode::MakeNew(inSize, ioHeap, ev);
91   }
92 
new(size_t inSize)93   void* operator new(size_t inSize) noexcept(true) {
94     return ::operator new(inSize);
95   }
96 
97  public:  // other pool methods
98   // alloc and free individual instances of handles (inside hand frames):
99   morkHandleFace* NewHandle(morkEnv* ev, mork_size inSize, morkZone* ioZone);
100   void ZapHandle(morkEnv* ev, morkHandleFace* ioHandle);
101 
102   // alloc and free individual instances of rows:
103   morkRow* NewRow(morkEnv* ev, morkZone* ioZone);  // alloc new row instance
104   void ZapRow(morkEnv* ev, morkRow* ioRow,
105               morkZone* ioZone);  // free old row instance
106 
107   // alloc and free entire vectors of cells (not just one cell at a time)
108   morkCell* NewCells(morkEnv* ev, mork_size inSize, morkZone* ioZone);
109   void ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize,
110                 morkZone* ioZone);
111 
112   // resize (grow or trim) cell vectors inside a containing row instance
113   mork_bool AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize,
114                         morkZone* ioZone);
115   mork_bool CutRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize,
116                         morkZone* ioZone);
117 
118   // alloc & free individual instances of atoms (lots of atom subclasses):
119   void ZapAtom(morkEnv* ev, morkAtom* ioAtom,
120                morkZone* ioZone);  // any subclass (by kind)
121 
122   morkOidAtom* NewRowOidAtom(morkEnv* ev, const mdbOid& inOid,
123                              morkZone* ioZone);
124   morkOidAtom* NewTableOidAtom(morkEnv* ev, const mdbOid& inOid,
125                                morkZone* ioZone);
126 
127   morkAtom* NewAnonAtom(morkEnv* ev, const morkBuf& inBuf, mork_cscode inForm,
128                         morkZone* ioZone);
129   // if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
130   // anon atom will be created, and otherwise a 'big' anon atom.
131 
132   morkBookAtom* NewBookAtom(morkEnv* ev, const morkBuf& inBuf,
133                             mork_cscode inForm, morkAtomSpace* ioSpace,
134                             mork_aid inAid, morkZone* ioZone);
135   // if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
136   // book atom will be created, and otherwise a 'big' book atom.
137 
138   morkBookAtom* NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom,
139                                 morkZone* ioZone);
140   // make the smallest kind of book atom that can hold content in inAtom.
141   // The inAtom parameter is often expected to be a staged book atom in
142   // the store, which was used to search an atom space for existing atoms.
143 
144   morkBookAtom* NewFarBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom,
145                                    morkZone* ioZone);
146   // make the smallest kind of book atom that can hold content in inAtom.
147   // The inAtom parameter is often expected to be a staged book atom in
148   // the store, which was used to search an atom space for existing atoms.
149 
150  public:  // typesafe refcounting inlines calling inherited morkNode methods
SlotWeakPool(morkPool * me,morkEnv * ev,morkPool ** ioSlot)151   static void SlotWeakPool(morkPool* me, morkEnv* ev, morkPool** ioSlot) {
152     morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
153   }
154 
SlotStrongPool(morkPool * me,morkEnv * ev,morkPool ** ioSlot)155   static void SlotStrongPool(morkPool* me, morkEnv* ev, morkPool** ioSlot) {
156     morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
157   }
158 };
159 
160 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
161 
162 #endif /* _MORKPOOL_ */
163