Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: src/assembler.h

Issue 643903006: Subzero: Do class definition cleanups for assembler files too. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceMemoryRegion.cpp ('k') | src/assembler.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/assembler.h - Integrated assembler -----------*- C++ -*-===//
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 // 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 // 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 // BSD-style license that can be found in the LICENSE file.
4 // 5 //
5 // Modified by the Subzero authors. 6 // Modified by the Subzero authors.
6 // 7 //
7 //===- subzero/src/assembler.h - Integrated assembler -----------*- C++ -*-===// 8 //===----------------------------------------------------------------------===//
8 // 9 //
9 // The Subzero Code Generator 10 // The Subzero Code Generator
10 // 11 //
11 // This file is distributed under the University of Illinois Open Source 12 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details. 13 // License. See LICENSE.TXT for details.
13 // 14 //
14 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
15 // 16 //
16 // This file declares the Assembler base class. Instructions are assembled 17 // This file declares the Assembler base class. Instructions are assembled
17 // by architecture-specific assemblers that derive from this base class. 18 // by architecture-specific assemblers that derive from this base class.
(...skipping 15 matching lines...) Expand all
33 class Assembler; 34 class Assembler;
34 class AssemblerFixup; 35 class AssemblerFixup;
35 class AssemblerBuffer; 36 class AssemblerBuffer;
36 class ConstantRelocatable; 37 class ConstantRelocatable;
37 class MemoryRegion; 38 class MemoryRegion;
38 39
39 // Assembler fixups are positions in generated code that hold relocation 40 // Assembler fixups are positions in generated code that hold relocation
40 // information that needs to be processed before finalizing the code 41 // information that needs to be processed before finalizing the code
41 // into executable memory. 42 // into executable memory.
42 class AssemblerFixup { 43 class AssemblerFixup {
44 AssemblerFixup(const AssemblerFixup &) = delete;
45 AssemblerFixup &operator=(const AssemblerFixup &) = delete;
46
43 public: 47 public:
44 virtual void Process(const MemoryRegion &region, intptr_t position) = 0; 48 virtual void Process(const MemoryRegion &region, intptr_t position) = 0;
45 49
46 // It would be ideal if the destructor method could be made private, 50 // It would be ideal if the destructor method could be made private,
47 // but the g++ compiler complains when this is subclassed. 51 // but the g++ compiler complains when this is subclassed.
48 virtual ~AssemblerFixup() { llvm_unreachable("~AssemblerFixup used"); } 52 virtual ~AssemblerFixup() { llvm_unreachable("~AssemblerFixup used"); }
49 53
50 intptr_t position() const { return position_; } 54 intptr_t position() const { return position_; }
51 55
52 FixupKind kind() const { return kind_; } 56 FixupKind kind() const { return kind_; }
53 57
54 const ConstantRelocatable *value() const { return value_; } 58 const ConstantRelocatable *value() const { return value_; }
55 59
56 protected: 60 protected:
57 AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value) 61 AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value)
58 : position_(0), kind_(Kind), value_(Value) {} 62 : position_(0), kind_(Kind), value_(Value) {}
59 63
60 private: 64 private:
61 intptr_t position_; 65 intptr_t position_;
62 FixupKind kind_; 66 FixupKind kind_;
63 const ConstantRelocatable *value_; 67 const ConstantRelocatable *value_;
64 68
65 void set_position(intptr_t position) { position_ = position; } 69 void set_position(intptr_t position) { position_ = position; }
66 70
67 AssemblerFixup(const AssemblerFixup &) = delete;
68 AssemblerFixup &operator=(const AssemblerFixup &) = delete;
69 friend class AssemblerBuffer; 71 friend class AssemblerBuffer;
70 }; 72 };
71 73
72 // Assembler buffers are used to emit binary code. They grow on demand. 74 // Assembler buffers are used to emit binary code. They grow on demand.
73 class AssemblerBuffer { 75 class AssemblerBuffer {
76 AssemblerBuffer(const AssemblerBuffer &) = delete;
77 AssemblerBuffer &operator=(const AssemblerBuffer &) = delete;
78
74 public: 79 public:
75 AssemblerBuffer(Assembler &); 80 AssemblerBuffer(Assembler &);
76 ~AssemblerBuffer(); 81 ~AssemblerBuffer();
77 82
78 // Basic support for emitting, loading, and storing. 83 // Basic support for emitting, loading, and storing.
79 template <typename T> void Emit(T value) { 84 template <typename T> void Emit(T value) {
80 assert(HasEnsuredCapacity()); 85 assert(HasEnsuredCapacity());
81 *reinterpret_cast<T *>(cursor_) = value; 86 *reinterpret_cast<T *>(cursor_) = value;
82 cursor_ += sizeof(T); 87 cursor_ += sizeof(T);
83 } 88 }
(...skipping 27 matching lines...) Expand all
111 void FinalizeInstructions(const MemoryRegion &region); 116 void FinalizeInstructions(const MemoryRegion &region);
112 117
113 // To emit an instruction to the assembler buffer, the EnsureCapacity helper 118 // To emit an instruction to the assembler buffer, the EnsureCapacity helper
114 // must be used to guarantee that the underlying data area is big enough to 119 // must be used to guarantee that the underlying data area is big enough to
115 // hold the emitted instruction. Usage: 120 // hold the emitted instruction. Usage:
116 // 121 //
117 // AssemblerBuffer buffer; 122 // AssemblerBuffer buffer;
118 // AssemblerBuffer::EnsureCapacity ensured(&buffer); 123 // AssemblerBuffer::EnsureCapacity ensured(&buffer);
119 // ... emit bytes for single instruction ... 124 // ... emit bytes for single instruction ...
120 125
121 #if defined(DEBUG) 126 #ifndef NDEBUG
122 class EnsureCapacity { 127 class EnsureCapacity {
128 EnsureCapacity(const EnsureCapacity &) = delete;
129 EnsureCapacity &operator=(const EnsureCapacity &) = delete;
130
123 public: 131 public:
124 explicit EnsureCapacity(AssemblerBuffer *buffer); 132 explicit EnsureCapacity(AssemblerBuffer *buffer);
125 ~EnsureCapacity(); 133 ~EnsureCapacity();
126 134
127 private: 135 private:
128 AssemblerBuffer *buffer_; 136 AssemblerBuffer *buffer_;
129 intptr_t gap_; 137 intptr_t gap_;
130 138
131 intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); } 139 intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); }
132 }; 140 };
133 141
134 bool has_ensured_capacity_; 142 bool has_ensured_capacity_;
135 bool HasEnsuredCapacity() const { return has_ensured_capacity_; } 143 bool HasEnsuredCapacity() const { return has_ensured_capacity_; }
136 #else 144 #else // NDEBUG
137 class EnsureCapacity { 145 class EnsureCapacity {
146 EnsureCapacity(const EnsureCapacity &) = delete;
147 EnsureCapacity &operator=(const EnsureCapacity &) = delete;
148
138 public: 149 public:
139 explicit EnsureCapacity(AssemblerBuffer *buffer) { 150 explicit EnsureCapacity(AssemblerBuffer *buffer) {
140 if (buffer->cursor() >= buffer->limit()) 151 if (buffer->cursor() >= buffer->limit())
141 buffer->ExtendCapacity(); 152 buffer->ExtendCapacity();
142 } 153 }
143 }; 154 };
144 155
145 // When building the C++ tests, assertion code is enabled. To allow 156 // When building the C++ tests, assertion code is enabled. To allow
146 // asserting that the user of the assembler buffer has ensured the 157 // asserting that the user of the assembler buffer has ensured the
147 // capacity needed for emitting, we add a dummy method in non-debug mode. 158 // capacity needed for emitting, we add a dummy method in non-debug mode.
148 bool HasEnsuredCapacity() const { return true; } 159 bool HasEnsuredCapacity() const { return true; }
149 #endif 160 #endif // NDEBUG
150 161
151 // Returns the position in the instruction stream. 162 // Returns the position in the instruction stream.
152 intptr_t GetPosition() const { return cursor_ - contents_; } 163 intptr_t GetPosition() const { return cursor_ - contents_; }
153 164
154 // For bringup only. 165 // For bringup only.
155 AssemblerFixup *GetLatestFixup() const; 166 AssemblerFixup *GetLatestFixup() const;
156 167
157 private: 168 private:
158 // The limit is set to kMinimumGap bytes before the end of the data area. 169 // The limit is set to kMinimumGap bytes before the end of the data area.
159 // This leaves enough space for the longest possible instruction and allows 170 // This leaves enough space for the longest possible instruction and allows
160 // for a single, fast space check per instruction. 171 // for a single, fast space check per instruction.
161 static const intptr_t kMinimumGap = 32; 172 static const intptr_t kMinimumGap = 32;
162 173
163 uintptr_t contents_; 174 uintptr_t contents_;
164 uintptr_t cursor_; 175 uintptr_t cursor_;
165 uintptr_t limit_; 176 uintptr_t limit_;
166 Assembler &assembler_; 177 Assembler &assembler_;
167 std::vector<AssemblerFixup *> fixups_; 178 std::vector<AssemblerFixup *> fixups_;
168 #if defined(DEBUG) 179 #ifndef NDEBUG
169 bool fixups_processed_; 180 bool fixups_processed_;
170 #endif 181 #endif // !NDEBUG
171 182
172 uintptr_t cursor() const { return cursor_; } 183 uintptr_t cursor() const { return cursor_; }
173 uintptr_t limit() const { return limit_; } 184 uintptr_t limit() const { return limit_; }
174 intptr_t Capacity() const { 185 intptr_t Capacity() const {
175 assert(limit_ >= contents_); 186 assert(limit_ >= contents_);
176 return (limit_ - contents_) + kMinimumGap; 187 return (limit_ - contents_) + kMinimumGap;
177 } 188 }
178 189
179 // Process the fixup chain. 190 // Process the fixup chain.
180 void ProcessFixups(const MemoryRegion &region); 191 void ProcessFixups(const MemoryRegion &region);
181 192
182 // Compute the limit based on the data area and the capacity. See 193 // Compute the limit based on the data area and the capacity. See
183 // description of kMinimumGap for the reasoning behind the value. 194 // description of kMinimumGap for the reasoning behind the value.
184 static uintptr_t ComputeLimit(uintptr_t data, intptr_t capacity) { 195 static uintptr_t ComputeLimit(uintptr_t data, intptr_t capacity) {
185 return data + capacity - kMinimumGap; 196 return data + capacity - kMinimumGap;
186 } 197 }
187 198
188 void ExtendCapacity(); 199 void ExtendCapacity();
189 200
190 friend class AssemblerFixup; 201 friend class AssemblerFixup;
191 }; 202 };
192 203
193 class Assembler { 204 class Assembler {
205 Assembler(const Assembler &) = delete;
206 Assembler &operator=(const Assembler &) = delete;
207
194 public: 208 public:
195 Assembler() {} 209 Assembler() {}
196 ~Assembler() {} 210 ~Assembler() {}
197 211
198 // Allocate a chunk of bytes using the per-Assembler allocator. 212 // Allocate a chunk of bytes using the per-Assembler allocator.
199 uintptr_t AllocateBytes(size_t bytes) { 213 uintptr_t AllocateBytes(size_t bytes) {
200 // For now, alignment is not related to NaCl bundle alignment, since 214 // For now, alignment is not related to NaCl bundle alignment, since
201 // the buffer's GetPosition is relative to the base. So NaCl bundle 215 // the buffer's GetPosition is relative to the base. So NaCl bundle
202 // alignment checks can be relative to that base. Later, the buffer 216 // alignment checks can be relative to that base. Later, the buffer
203 // will be copied out to a ".text" section (or an in memory-buffer 217 // will be copied out to a ".text" section (or an in memory-buffer
204 // that can be mprotect'ed with executable permission), and that 218 // that can be mprotect'ed with executable permission), and that
205 // second buffer should be aligned for NaCl. 219 // second buffer should be aligned for NaCl.
206 const size_t Alignment = 16; 220 const size_t Alignment = 16;
207 return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment)); 221 return reinterpret_cast<uintptr_t>(Allocator.Allocate(bytes, Alignment));
208 } 222 }
209 223
210 // Allocate data of type T using the per-Assembler allocator. 224 // Allocate data of type T using the per-Assembler allocator.
211 template <typename T> T *Allocate() { return Allocator.Allocate<T>(); } 225 template <typename T> T *Allocate() { return Allocator.Allocate<T>(); }
212 226
213 private: 227 private:
214 llvm::BumpPtrAllocator Allocator; 228 llvm::BumpPtrAllocator Allocator;
215
216 Assembler(const Assembler &) = delete;
217 Assembler &operator=(const Assembler &) = delete;
218 }; 229 };
219 230
220 } // end of namespace Ice 231 } // end of namespace Ice
221 232
222 #endif // SUBZERO_SRC_ASSEMBLER_H_ 233 #endif // SUBZERO_SRC_ASSEMBLER_H_
OLDNEW
« no previous file with comments | « src/IceMemoryRegion.cpp ('k') | src/assembler.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698