OLD | NEW |
---|---|
1 //===- subzero/src/IceAssembler.h - Integrated assembler --------*- C++ -*-===// | 1 //===- subzero/src/IceAssembler.h - Integrated assembler --------*- C++ -*-===// |
2 // 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 |
3 // 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 |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 // | 5 // |
6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // The Subzero Code Generator | 10 // The Subzero Code Generator |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 *reinterpret_cast<T *>(Contents + Position) = Value; | 56 *reinterpret_cast<T *>(Contents + Position) = Value; |
57 } | 57 } |
58 | 58 |
59 // Emit a fixup at the current location. | 59 // Emit a fixup at the current location. |
60 void emitFixup(AssemblerFixup *Fixup) { Fixup->set_position(size()); } | 60 void emitFixup(AssemblerFixup *Fixup) { Fixup->set_position(size()); } |
61 | 61 |
62 // Get the size of the emitted code. | 62 // Get the size of the emitted code. |
63 intptr_t size() const { return Cursor - Contents; } | 63 intptr_t size() const { return Cursor - Contents; } |
64 uintptr_t contents() const { return Contents; } | 64 uintptr_t contents() const { return Contents; } |
65 | 65 |
66 // To emit an instruction to the assembler buffer, the EnsureCapacity helper | 66 // To emit an instruction to the assembler buffer, the EnsureCapacity helper |
67 // must be used to guarantee that the underlying data area is big enough to | 67 // must be used to guarantee that the underlying data area is big enough to |
68 // hold the emitted instruction. Usage: | 68 // hold the emitted instruction. Usage: |
69 // | 69 // |
70 // AssemblerBuffer buffer; | 70 // AssemblerBuffer buffer; |
71 // AssemblerBuffer::EnsureCapacity ensured(&buffer); | 71 // AssemblerBuffer::EnsureCapacity ensured(&buffer); |
72 // ... emit bytes for single instruction ... | 72 // ... emit bytes for single instruction ... |
73 | 73 |
74 #ifndef NDEBUG | |
75 class EnsureCapacity { | 74 class EnsureCapacity { |
76 EnsureCapacity(const EnsureCapacity &) = delete; | 75 EnsureCapacity(const EnsureCapacity &) = delete; |
77 EnsureCapacity &operator=(const EnsureCapacity &) = delete; | 76 EnsureCapacity &operator=(const EnsureCapacity &) = delete; |
78 | 77 |
79 public: | 78 public: |
80 explicit EnsureCapacity(AssemblerBuffer *Buffer); | 79 explicit EnsureCapacity(AssemblerBuffer *Buffer) : Buffer(Buffer), Gap(0) { |
80 if (Buffer->cursor() >= Buffer->limit()) | |
81 Buffer->extendCapacity(); | |
82 #ifdef NDEBUG | |
Karl
2015/06/22 15:41:06
Why not create a boolean (inline) function in IceD
John
2015/06/22 17:13:46
I agree with Karl on this one. Perhaps IceDefs cou
Jim Stichnoth
2015/06/23 21:42:07
Did both, in IceDefs.h:
constexpr bool buildAllo
| |
83 return; | |
84 #endif // NDEBUG | |
85 validate(Buffer); | |
86 } | |
81 ~EnsureCapacity(); | 87 ~EnsureCapacity(); |
82 | 88 |
83 private: | 89 private: |
84 AssemblerBuffer *Buffer; | 90 AssemblerBuffer *Buffer; |
85 intptr_t Gap; | 91 intptr_t Gap; |
86 | 92 |
93 void validate(AssemblerBuffer *Buffer); | |
87 intptr_t computeGap() { return Buffer->capacity() - Buffer->size(); } | 94 intptr_t computeGap() { return Buffer->capacity() - Buffer->size(); } |
88 }; | 95 }; |
89 | 96 |
90 bool HasEnsuredCapacity; | 97 bool HasEnsuredCapacity; |
91 bool hasEnsuredCapacity() const { return HasEnsuredCapacity; } | 98 bool hasEnsuredCapacity() const { |
92 #else // NDEBUG | 99 #ifdef NDEBUG |
Karl
2015/06/22 15:41:06
same here.
John
2015/06/22 17:13:46
This makes me nervous that, with NDEBUG, some comp
| |
93 class EnsureCapacity { | 100 // Disable the actual check in non-debug mode. |
94 EnsureCapacity(const EnsureCapacity &) = delete; | 101 return true; |
95 EnsureCapacity &operator=(const EnsureCapacity &) = delete; | |
96 | |
97 public: | |
98 explicit EnsureCapacity(AssemblerBuffer *Buffer) { | |
99 if (Buffer->cursor() >= Buffer->limit()) | |
100 Buffer->extendCapacity(); | |
101 } | |
102 }; | |
103 | |
104 // When building the C++ tests, assertion code is enabled. To allow | |
105 // asserting that the user of the assembler buffer has ensured the | |
106 // capacity needed for emitting, we add a dummy method in non-debug mode. | |
107 bool hasEnsuredCapacity() const { return true; } | |
108 #endif // NDEBUG | 102 #endif // NDEBUG |
103 return HasEnsuredCapacity; | |
104 } | |
109 | 105 |
110 // Returns the position in the instruction stream. | 106 // Returns the position in the instruction stream. |
111 intptr_t getPosition() const { return Cursor - Contents; } | 107 intptr_t getPosition() const { return Cursor - Contents; } |
112 | 108 |
113 // Create and track a fixup in the current function. | 109 // Create and track a fixup in the current function. |
114 AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value); | 110 AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value); |
115 | 111 |
116 const FixupRefList &fixups() const { return Fixups; } | 112 const FixupRefList &fixups() const { return Fixups; } |
117 | 113 |
118 void setSize(intptr_t NewSize) { | 114 void setSize(intptr_t NewSize) { |
119 assert(NewSize <= size()); | 115 assert(NewSize <= size()); |
120 Cursor = Contents + NewSize; | 116 Cursor = Contents + NewSize; |
121 } | 117 } |
122 | 118 |
123 private: | 119 private: |
124 // The limit is set to kMinimumGap bytes before the end of the data area. | 120 // The limit is set to kMinimumGap bytes before the end of the data area. |
125 // This leaves enough space for the longest possible instruction and allows | 121 // This leaves enough space for the longest possible instruction and allows |
126 // for a single, fast space check per instruction. | 122 // for a single, fast space check per instruction. |
127 static const intptr_t kMinimumGap = 32; | 123 static constexpr intptr_t kMinimumGap = 32; |
128 | 124 |
129 uintptr_t Contents; | 125 uintptr_t Contents; |
130 uintptr_t Cursor; | 126 uintptr_t Cursor; |
131 uintptr_t Limit; | 127 uintptr_t Limit; |
132 // The member variable is named Assemblr to avoid hiding the class Assembler. | 128 // The member variable is named Assemblr to avoid hiding the class Assembler. |
133 Assembler &Assemblr; | 129 Assembler &Assemblr; |
134 // List of pool-allocated fixups relative to the current function. | 130 // List of pool-allocated fixups relative to the current function. |
135 FixupRefList Fixups; | 131 FixupRefList Fixups; |
136 | 132 |
137 uintptr_t cursor() const { return Cursor; } | 133 uintptr_t cursor() const { return Cursor; } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 protected: | 224 protected: |
229 // Buffer's constructor uses the Allocator, so it needs to appear after it. | 225 // Buffer's constructor uses the Allocator, so it needs to appear after it. |
230 // TODO(jpp): dependencies on construction order are a nice way of shooting | 226 // TODO(jpp): dependencies on construction order are a nice way of shooting |
231 // yourself in the foot. Fix this. | 227 // yourself in the foot. Fix this. |
232 AssemblerBuffer Buffer; | 228 AssemblerBuffer Buffer; |
233 }; | 229 }; |
234 | 230 |
235 } // end of namespace Ice | 231 } // end of namespace Ice |
236 | 232 |
237 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ | 233 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ |
OLD | NEW |