gem5  v20.1.0.0
proxy_ptr.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef __SIM_PROXY_PTR_HH__
30 #define __SIM_PROXY_PTR_HH__
31 
32 #include <cstdint>
33 #include <memory>
34 #include <type_traits>
35 
36 #include "base/logging.hh"
37 #include "base/types.hh"
38 #include "sim/guest_abi.hh"
39 
40 template <typename Proxy>
42 {
43  private:
44  std::shared_ptr<Proxy> proxy;
45 
47  size_t size;
48  std::unique_ptr<uint8_t[]> data;
49 
50  bool dirty = false;
51 
52  void markClean() { dirty = false; }
53 
54  public:
55 
56  std::shared_ptr<Proxy> getProxy() const { return proxy; }
57 
58  void markDirty() { dirty = true; }
59  bool isDirty() { return dirty; }
60 
61  template <typename T>
62  T &
63  as()
64  {
65  assert(sizeof(T) <= size);
66  markDirty();
67  return *reinterpret_cast<T *>(data.get());
68  }
69 
70  template <typename T>
71  const T &
72  asConst() const
73  {
74  assert(sizeof(T) <= size);
75  return *reinterpret_cast<T *>(data.get());
76  }
77 
78  void
79  flush(bool force=false)
80  {
81  if (force || isDirty()) {
82  proxy->writeBlob(ptr, data.get(), size);
83  markClean();
84  }
85  }
86 
87  void
88  load()
89  {
90  panic_if(isDirty(), "Overwriting dirty ProxyPtr.");
91  proxy->readBlob(ptr, data.get(), size);
92  }
93 
94  Addr addr() const { return ptr; }
95 
96  ProxyPtrBuffer(std::shared_ptr<Proxy> _proxy, Addr _ptr, size_t _size) :
97  proxy(_proxy), ptr(_ptr), size(_size), data(new uint8_t[_size])
98  {
99  load();
100  }
101 
103 };
104 
105 template <typename T, typename Proxy>
107 {
108  protected:
109  std::shared_ptr<Proxy> proxy;
110  std::shared_ptr<ProxyPtrBuffer<Proxy>> buffer;
111 
112  template <typename O, typename P>
113  friend class ProxyPtr;
114 
115  void nullCheck() const { panic_if(!buffer, "Accessing null ProxyPtr."); }
116 
117  void
119  {
120  if (ptr)
121  buffer.reset(new ProxyPtrBuffer<Proxy>(proxy, ptr, sizeof(T)));
122  else
123  buffer.reset((ProxyPtrBuffer<Proxy> *)nullptr);
124  }
125 
126  ConstProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : proxy(_proxy)
127  {
128  setAddr(_ptr);
129  }
130 
132 
133  public:
134  using Type = T;
135 
136  template <typename ...Args,
137  typename std::enable_if<std::is_constructible<
138  Proxy, Args&&...>::value, int>::type = 0>
139  explicit ConstProxyPtr(Addr _ptr, Args&&... args) :
140  proxy(std::make_shared<Proxy>(args...))
141  {
142  setAddr(_ptr);
143  }
144  template <typename ...Args,
145  typename std::enable_if<std::is_constructible<
146  Proxy, Args&&...>::value, int>::type = 0>
147  explicit ConstProxyPtr(Args&&... args) :
148  proxy(std::make_shared<Proxy>(args...))
149  {
150  setAddr(0);
151  }
152 
153  template <typename O, typename Enabled=
154  typename std::enable_if<std::is_assignable<T *, O *>::value>::type>
156  proxy(other.proxy), buffer(other.buffer)
157  {}
158 
159  ConstProxyPtr(const CPP &other) :
160  proxy(other.proxy), buffer(other.buffer)
161  {}
162 
163  void
165  {
166  nullCheck();
167  buffer->load();
168  }
169 
170  Addr addr() const { return buffer ? buffer->addr() : 0; }
171  operator bool() const { return (bool)buffer; }
172 
173  template <typename A>
174  typename std::enable_if<std::is_integral<A>::value, CPP>::type
175  operator + (A a) const
176  {
177  return CPP(addr() + a * sizeof(T), proxy);
178  }
179 
180  template <typename A>
181  typename std::enable_if<std::is_integral<A>::value, CPP>::type
182  operator - (A a) const
183  {
184  return CPP(addr() - a * sizeof(T), proxy);
185  }
186 
187  ptrdiff_t
188  operator - (const CPP &other) const
189  {
190  return (addr() - other.addr()) / sizeof(T);
191  }
192 
193  CPP &
194  operator = (const CPP &other)
195  {
196  proxy = other.proxy;
197  buffer = other.buffer;
198  return *this;
199  }
200 
201  CPP &
203  {
204  setAddr(a);
205  return *this;
206  }
207 
208  operator const T *() const
209  {
210  return buffer ? &buffer->template asConst<T>() : nullptr;
211  }
212 
213  const T &
214  operator *() const
215  {
216  nullCheck();
217  return buffer->template asConst<T>();
218  }
219  const T *
220  operator ->() const
221  {
222  nullCheck();
223  return &buffer->template asConst<T>();
224  }
225 };
226 
227 template <typename T, typename Proxy, typename A>
228 typename std::enable_if<std::is_integral<A>::value,
231 {
232  return other + a;
233 }
234 
235 template <typename T, typename Proxy>
236 class ProxyPtr : public ConstProxyPtr<T, Proxy>
237 {
238  protected:
241 
242  ProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : CPP(_ptr, _proxy) {}
243 
244  public:
245  template <typename ...Args,
246  typename std::enable_if<std::is_constructible<
247  Proxy, Args&&...>::value, int>::type = 0>
248  explicit ProxyPtr(Addr _ptr, Args&&... args) : CPP(_ptr, args...) {}
249  template <typename ...Args,
250  typename std::enable_if<std::is_constructible<
251  Proxy, Args&&...>::value, int>::type = 0>
252  explicit ProxyPtr(Args&&... args) : CPP(0, args...) {}
253 
254  template <typename O, typename Enabled=
255  typename std::enable_if<std::is_assignable<T *, O *>::value>::type>
256  ProxyPtr(const ProxyPtr<O, Proxy> &other) : CPP(other) {}
257 
258  ProxyPtr(const PP &other) : CPP(other) {}
259  operator bool() const { return (bool)this->buffer; }
260 
261  void
262  flush(bool force=false)
263  {
264  this->nullCheck();
265  this->buffer->flush(force);
266  }
267 
268  template <typename A>
269  typename std::enable_if<std::is_integral<A>::value, PP>::type
270  operator + (A a) const
271  {
272  return PP(this->addr() + a * sizeof(T), this->proxy);
273  }
274 
275  template <typename A>
276  typename std::enable_if<std::is_integral<A>::value, PP>::type
277  operator - (A a) const
278  {
279  return PP(this->addr() - a * sizeof(T), this->proxy);
280  }
281 
282  ptrdiff_t
283  operator - (const PP &other) const
284  {
285  return (this->addr() - other.addr()) / sizeof(T);
286  }
287 
288  PP &
289  operator = (const PP &other)
290  {
291  this->proxy = other.proxy;
292  this->buffer = other.buffer;
293  return *this;
294  }
295 
296  PP &
298  {
299  this->setAddr(a);
300  return *this;
301  }
302 
303  using CPP::operator const T *;
304  operator T *() const
305  {
306  return this->buffer ? &this->buffer->template as<T>() : nullptr;
307  }
308 
309  using CPP::operator *;
310  T &
311  operator *() const
312  {
313  this->nullCheck();
314  return this->buffer->template as<T>();
315  }
316 
317  using CPP::operator ->;
318  T *
319  operator ->() const
320  {
321  this->nullCheck();
322  return &this->buffer->template as<T>();
323  }
324 };
325 
326 template <typename T, typename Proxy, typename A>
327 typename std::enable_if<std::is_integral<A>::value, ProxyPtr<T, Proxy>>::type
329 {
330  return other + a;
331 }
332 
333 namespace GuestABI
334 {
335 
336 template <typename ABI, typename T, typename Proxy>
337 struct Argument<ABI, ProxyPtr<T, Proxy>>
338 {
339  static ProxyPtr<T, Proxy>
340  get(ThreadContext *tc, typename ABI::State &state)
341  {
342  return ProxyPtr<T, Proxy>(Argument<ABI, Addr>::get(tc, state), tc);
343  }
344 };
345 
346 template <typename ABI, typename T, typename Proxy>
347 struct Argument<ABI, ConstProxyPtr<T, Proxy>>
348 {
350  get(ThreadContext *tc, typename ABI::State &state)
351  {
353  Argument<ABI, Addr>::get(tc, state), tc);
354  }
355 };
356 
357 } // namespace GuestABI
358 
359 template <typename T, typename Proxy>
360 std::ostream &
361 operator << (std::ostream &os, const ConstProxyPtr<T, Proxy> &vptr)
362 {
363  ccprintf(os, "%#x", vptr.addr());
364  return os;
365 }
366 
368 
369 template <typename T>
371 template <typename T>
373 
374 #endif // __SIM_PROXY_PTR_HH__
ConstProxyPtr::ConstProxyPtr
ConstProxyPtr(Args &&... args)
Definition: proxy_ptr.hh:147
ProxyPtrBuffer::ptr
Addr ptr
Definition: proxy_ptr.hh:46
ConstProxyPtr::proxy
std::shared_ptr< Proxy > proxy
Definition: proxy_ptr.hh:109
X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:803
ProxyPtr::ProxyPtr
ProxyPtr(Addr _ptr, std::shared_ptr< Proxy > _proxy)
Definition: proxy_ptr.hh:242
ProxyPtrBuffer::data
std::unique_ptr< uint8_t[]> data
Definition: proxy_ptr.hh:48
SETranslatingPortProxy
Definition: se_translating_port_proxy.hh:46
ProxyPtr::ProxyPtr
ProxyPtr(Addr _ptr, Args &&... args)
Definition: proxy_ptr.hh:248
ProxyPtr::ProxyPtr
ProxyPtr(Args &&... args)
Definition: proxy_ptr.hh:252
ProxyPtr::operator=
PP & operator=(const PP &other)
Definition: proxy_ptr.hh:289
ConstProxyPtr::ConstProxyPtr
ConstProxyPtr(const ConstProxyPtr< O, Proxy > &other)
Definition: proxy_ptr.hh:155
ConstProxyPtr
Definition: proxy_ptr.hh:106
ProxyPtrBuffer::load
void load()
Definition: proxy_ptr.hh:88
ConstProxyPtr::nullCheck
void nullCheck() const
Definition: proxy_ptr.hh:115
ProxyPtrBuffer::isDirty
bool isDirty()
Definition: proxy_ptr.hh:59
ProxyPtr
Definition: proxy_ptr.hh:236
type
uint8_t type
Definition: inet.hh:421
ConstProxyPtr::ConstProxyPtr
ConstProxyPtr(Addr _ptr, std::shared_ptr< Proxy > _proxy)
Definition: proxy_ptr.hh:126
ProxyPtr::flush
void flush(bool force=false)
Definition: proxy_ptr.hh:262
ConstProxyPtr::CPP
ConstProxyPtr< T, Proxy > CPP
Definition: proxy_ptr.hh:131
ProxyPtr::operator*
T & operator*() const
Definition: proxy_ptr.hh:311
ProxyPtrBuffer::proxy
std::shared_ptr< Proxy > proxy
Definition: proxy_ptr.hh:44
ProxyPtrBuffer::as
T & as()
Definition: proxy_ptr.hh:63
ProxyPtr::operator-
std::enable_if< std::is_integral< A >::value, PP >::type operator-(A a) const
Definition: proxy_ptr.hh:277
GuestABI::Argument< ABI, ProxyPtr< T, Proxy > >::get
static ProxyPtr< T, Proxy > get(ThreadContext *tc, typename ABI::State &state)
Definition: proxy_ptr.hh:340
ProxyPtrBuffer::markClean
void markClean()
Definition: proxy_ptr.hh:52
ConstProxyPtr::load
void load()
Definition: proxy_ptr.hh:164
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
ProxyPtr::ProxyPtr
ProxyPtr(const ProxyPtr< O, Proxy > &other)
Definition: proxy_ptr.hh:256
GuestABI
Definition: aapcs32.hh:66
ConstProxyPtr::buffer
std::shared_ptr< ProxyPtrBuffer< Proxy > > buffer
Definition: proxy_ptr.hh:110
ProxyPtrBuffer::markDirty
void markDirty()
Definition: proxy_ptr.hh:58
GuestABI::Argument
Definition: definition.hh:93
ConstProxyPtr::operator->
const T * operator->() const
Definition: proxy_ptr.hh:220
ConstProxyPtr::operator+
std::enable_if< std::is_integral< A >::value, CPP >::type operator+(A a) const
Definition: proxy_ptr.hh:175
ProxyPtr::operator->
T * operator->() const
Definition: proxy_ptr.hh:319
GuestABI::Argument< ABI, ConstProxyPtr< T, Proxy > >::get
static ConstProxyPtr< T, Proxy > get(ThreadContext *tc, typename ABI::State &state)
Definition: proxy_ptr.hh:350
ConstProxyPtr::setAddr
void setAddr(Addr ptr)
Definition: proxy_ptr.hh:118
ConstProxyPtr::operator-
std::enable_if< std::is_integral< A >::value, CPP >::type operator-(A a) const
Definition: proxy_ptr.hh:182
ConstProxyPtr::operator*
const T & operator*() const
Definition: proxy_ptr.hh:214
ConstProxyPtr::addr
Addr addr() const
Definition: proxy_ptr.hh:170
operator+
std::enable_if< std::is_integral< A >::value, ConstProxyPtr< T, Proxy > >::type operator+(A a, const ConstProxyPtr< T, Proxy > &other)
Definition: proxy_ptr.hh:230
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
ProxyPtrBuffer::getProxy
std::shared_ptr< Proxy > getProxy() const
Definition: proxy_ptr.hh:56
ProxyPtrBuffer::flush
void flush(bool force=false)
Definition: proxy_ptr.hh:79
ProxyPtr::operator+
std::enable_if< std::is_integral< A >::value, PP >::type operator+(A a) const
Definition: proxy_ptr.hh:270
ProxyPtrBuffer::dirty
bool dirty
Definition: proxy_ptr.hh:50
ConstProxyPtr::operator=
CPP & operator=(const CPP &other)
Definition: proxy_ptr.hh:194
ProxyPtrBuffer::addr
Addr addr() const
Definition: proxy_ptr.hh:94
ProxyPtrBuffer::size
size_t size
Definition: proxy_ptr.hh:47
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
types.hh
guest_abi.hh
ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
logging.hh
ProxyPtrBuffer::~ProxyPtrBuffer
~ProxyPtrBuffer()
Definition: proxy_ptr.hh:102
ConstProxyPtr::ConstProxyPtr
ConstProxyPtr(Addr _ptr, Args &&... args)
Definition: proxy_ptr.hh:139
ProxyPtrBuffer::asConst
const T & asConst() const
Definition: proxy_ptr.hh:72
ProxyPtrBuffer
Definition: proxy_ptr.hh:41
ProxyPtrBuffer::ProxyPtrBuffer
ProxyPtrBuffer(std::shared_ptr< Proxy > _proxy, Addr _ptr, size_t _size)
Definition: proxy_ptr.hh:96
operator<<
std::ostream & operator<<(std::ostream &os, const ConstProxyPtr< T, Proxy > &vptr)
Definition: proxy_ptr.hh:361
ProxyPtr::ProxyPtr
ProxyPtr(const PP &other)
Definition: proxy_ptr.hh:258
ProxyPtr::PP
ProxyPtr< T, Proxy > PP
Definition: proxy_ptr.hh:240
ConstProxyPtr::ConstProxyPtr
ConstProxyPtr(const CPP &other)
Definition: proxy_ptr.hh:159
ConstProxyPtr::Type
T Type
Definition: proxy_ptr.hh:134

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17