1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_MEMORY_REGION_H_
6#define RUNTIME_VM_MEMORY_REGION_H_
7
8#include "platform/assert.h"
9#include "platform/unaligned.h"
10#include "vm/allocation.h"
11#include "vm/globals.h"
12
13namespace dart {
14
15// Memory regions are useful for accessing memory with bounds check in
16// debug mode. They can be safely passed by value and do not assume ownership
17// of the region.
18class MemoryRegion : public ValueObject {
19 public:
20 MemoryRegion() : pointer_(NULL), size_(0) {}
21 MemoryRegion(void* pointer, uword size) : pointer_(pointer), size_(size) {}
22 MemoryRegion(const MemoryRegion& other) : ValueObject() { *this = other; }
23 MemoryRegion& operator=(const MemoryRegion& other) {
24 pointer_ = other.pointer_;
25 size_ = other.size_;
26 return *this;
27 }
28
29 void* pointer() const { return pointer_; }
30 uword size() const { return size_; }
31 void set_size(uword new_size) { size_ = new_size; }
32
33 uword start() const { return reinterpret_cast<uword>(pointer_); }
34 uword end() const { return start() + size_; }
35
36 template <typename T>
37 T Load(uword offset) const {
38 return *ComputeInternalPointer<T>(offset);
39 }
40
41 template <typename T>
42 void Store(uword offset, T value) const {
43 *ComputeInternalPointer<T>(offset) = value;
44 }
45
46 template <typename T>
47 void StoreUnaligned(uword offset, T value) const {
48 dart::StoreUnaligned(ComputeInternalPointer<T>(offset), value);
49 }
50
51 template <typename T>
52 T* PointerTo(uword offset) const {
53 return ComputeInternalPointer<T>(offset);
54 }
55
56 bool Contains(uword address) const {
57 return (address >= start()) && (address < end());
58 }
59
60 void CopyFrom(uword offset, const MemoryRegion& from) const;
61
62 // Compute a sub memory region based on an existing one.
63 void Subregion(const MemoryRegion& from, uword offset, uword size) {
64 ASSERT(from.size() >= size);
65 ASSERT(offset <= (from.size() - size));
66 pointer_ = reinterpret_cast<void*>(from.start() + offset);
67 size_ = size;
68 }
69
70 // Compute an extended memory region based on an existing one.
71 void Extend(const MemoryRegion& region, uword extra) {
72 pointer_ = region.pointer();
73 size_ = (region.size() + extra);
74 }
75
76 private:
77 template <typename T>
78 T* ComputeInternalPointer(uword offset) const {
79 ASSERT(size() >= sizeof(T));
80 ASSERT(offset <= size() - sizeof(T));
81 return reinterpret_cast<T*>(start() + offset);
82 }
83
84 void* pointer_;
85 uword size_;
86};
87
88} // namespace dart
89
90#endif // RUNTIME_VM_MEMORY_REGION_H_
91