Add support for HHBC ops with 5 immediates
[hiphop-php.git] / hphp / runtime / base / sweepable.h
blob7ab302d660286a7b55fe093d40bfabba7e4ef13e
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_SWEEPABLE_H_
18 #define incl_HPHP_SWEEPABLE_H_
20 #include "hphp/util/assertions.h"
21 #include "hphp/util/type-scan.h"
23 namespace HPHP {
24 ///////////////////////////////////////////////////////////////////////////////
27 * Objects that need to do special clean up at the end of the request
28 * may register themselves for this by deriving from Sweepable. After
29 * every request, MemoryManager::sweep() called each Sweepable::sweep()
30 * method, allowing objects to clean up resources that are not othewise
31 * owned by the current request, for example malloc'd-memory or file handles.
33 struct Sweepable {
34 Sweepable(const Sweepable&) = delete;
35 Sweepable& operator=(const Sweepable&) = delete;
38 * There is no default behavior. Make sure this function frees all
39 * only non-request-allocated resources.
41 virtual void sweep() = 0;
42 virtual void* owner() = 0; // return ptr to object
45 * Remove this object from the sweepable list, so it won't have
46 * sweep() called at the next SweepAll.
48 void unregister() {
49 delist();
50 init(); // in case destructor runs later.
54 * List manipulation methods; mainly for use by MemoryManager.
56 bool empty() const {
57 assertx((this == m_prev) == (this == m_next)); // both==this or both!=this
58 return this == m_next;
60 void init() { m_prev = m_next = this; }
61 Sweepable* next() const { return m_next; }
63 void delist() {
64 auto n = m_next, p = m_prev;
65 n->m_prev = p;
66 p->m_next = n;
69 void enlist(Sweepable* head) {
70 auto next = head->m_next;
71 m_next = next;
72 m_prev = head;
73 head->m_next = next->m_prev = this;
76 protected:
77 Sweepable();
78 enum class Init {};
79 explicit Sweepable(Init) { init(); }
80 virtual ~Sweepable() { delist(); }
82 private:
83 Sweepable *m_next, *m_prev;
87 * SweepableMember is a Sweepable used as a member of an otherwise nonvirtual
88 * class. The member must be named m_sweepable. If T is a derived class, it
89 * should only have one m_sweepable member. Anything fancier than that voids
90 * your warranty.
92 template<class T>
93 struct SweepableMember : Sweepable {
94 void sweep() override {
95 auto obj = reinterpret_cast<T*>(
96 uintptr_t(this) - offsetof(T, m_sweepable)
98 obj->sweep();
100 void* owner() override {
101 return reinterpret_cast<T*>(
102 uintptr_t(this) - offsetof(T, m_sweepable)
107 ///////////////////////////////////////////////////////////////////////////////
110 #endif