2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
20 #include "hphp/runtime/vm/func.h"
23 ////////////////////////////////////////////////////////////////////////////////
25 // Map which holds a set of PCs and supports reasonably fast addition and
26 // lookup. Used to decide if a given PC falls within an interesting area, e.g.,
27 // for breakpoints and stepping.
29 static constexpr auto PTRMAP_PTR_SIZE
= sizeof(void*) * 8;
30 static constexpr auto PTRMAP_LEVEL_BITS
= 8LL;
31 static constexpr auto PTRMAP_LEVEL_ENTRIES
= 1LL << PTRMAP_LEVEL_BITS
;
32 static constexpr auto PTRMAP_LEVEL_MASK
= PTRMAP_LEVEL_ENTRIES
- 1LL;
34 // Radix-tree implementation of pointer map
37 PtrMapNode
* m_entries
;
40 void clearImpl(unsigned short bits
);
44 static_assert(PTRMAP_PTR_SIZE
% PTRMAP_LEVEL_BITS
== 0,
45 "PTRMAP_PTR_SIZE must be a multiple of PTRMAP_LEVEL_BITS");
46 m_root
.m_entries
= nullptr;
48 ~PtrMap() { clear(); }
49 PtrMap(const PtrMap
&) = delete;
50 PtrMap
& operator=(const PtrMap
&) = delete;
52 static PtrMapNode
makeNode();
53 void setPointer(void* ptr
, void* val
);
54 void* getPointer(void* ptr
) const {
55 if (!m_root
.m_entries
) return nullptr;
56 return getPointerImpl(ptr
);
59 void swap(PtrMap
& other
) {
60 std::swap(m_root
, other
.m_root
);
62 bool isNull() { return m_root
.m_entries
== nullptr; }
64 void* getPointerImpl(void* ptr
) const;
66 TYPE_SCAN_IGNORE_FIELD(m_root
); // points to a malloc'd radix tree node
74 // Filter function to exclude opcodes when adding ranges.
75 using OpcodeFilter
= std::function
<bool(Op
)>;
77 // Add/remove offsets, either individually or by range. By default allow all
79 void addRanges(const OffsetFuncRangeVec
& offsets
,
80 OpcodeFilter isOpcodeAllowed
= [] (Op
) { return true; });
81 void removeRanges(const OffsetFuncRangeVec
& offsets
,
82 OpcodeFilter isOpcodeAllowed
= [] (Op
) { return true; });
83 void removeOffset(const Func
* func
, Offset offset
);
85 // Add/remove/check explicit PCs.
86 void addPC(const unsigned char* pc
) {
87 m_map
.setPointer((void*)pc
, (void*)pc
);
89 void removePC(const unsigned char* pc
) {
90 m_map
.setPointer((void*)pc
, nullptr);
92 bool checkPC(const unsigned char* pc
) {
93 return m_map
.getPointer((void*)pc
) == (void*)pc
;
96 bool isNull() { return m_map
.isNull(); }
98 void swap(PCFilter
& other
) {
99 m_map
.swap(other
.m_map
);
107 ///////////////////////////////////////////////////////////////////////////////