| 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 if (buildAllowsAsserts()) |
| 83 validate(Buffer); |
| 84 } |
| 81 ~EnsureCapacity(); | 85 ~EnsureCapacity(); |
| 82 | 86 |
| 83 private: | 87 private: |
| 84 AssemblerBuffer *Buffer; | 88 AssemblerBuffer *Buffer; |
| 85 intptr_t Gap; | 89 intptr_t Gap; |
| 86 | 90 |
| 91 void validate(AssemblerBuffer *Buffer); |
| 87 intptr_t computeGap() { return Buffer->capacity() - Buffer->size(); } | 92 intptr_t computeGap() { return Buffer->capacity() - Buffer->size(); } |
| 88 }; | 93 }; |
| 89 | 94 |
| 90 bool HasEnsuredCapacity; | 95 bool HasEnsuredCapacity; |
| 91 bool hasEnsuredCapacity() const { return HasEnsuredCapacity; } | 96 bool hasEnsuredCapacity() const { |
| 92 #else // NDEBUG | 97 if (buildAllowsAsserts()) |
| 93 class EnsureCapacity { | 98 return HasEnsuredCapacity; |
| 94 EnsureCapacity(const EnsureCapacity &) = delete; | 99 // Disable the actual check in non-debug mode. |
| 95 EnsureCapacity &operator=(const EnsureCapacity &) = delete; | 100 return true; |
| 96 | 101 } |
| 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 | |
| 109 | 102 |
| 110 // Returns the position in the instruction stream. | 103 // Returns the position in the instruction stream. |
| 111 intptr_t getPosition() const { return Cursor - Contents; } | 104 intptr_t getPosition() const { return Cursor - Contents; } |
| 112 | 105 |
| 113 // Create and track a fixup in the current function. | 106 // Create and track a fixup in the current function. |
| 114 AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value); | 107 AssemblerFixup *createFixup(FixupKind Kind, const Constant *Value); |
| 115 | 108 |
| 116 const FixupRefList &fixups() const { return Fixups; } | 109 const FixupRefList &fixups() const { return Fixups; } |
| 117 | 110 |
| 118 void setSize(intptr_t NewSize) { | 111 void setSize(intptr_t NewSize) { |
| 119 assert(NewSize <= size()); | 112 assert(NewSize <= size()); |
| 120 Cursor = Contents + NewSize; | 113 Cursor = Contents + NewSize; |
| 121 } | 114 } |
| 122 | 115 |
| 123 private: | 116 private: |
| 124 // The limit is set to kMinimumGap bytes before the end of the data area. | 117 // 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 | 118 // This leaves enough space for the longest possible instruction and allows |
| 126 // for a single, fast space check per instruction. | 119 // for a single, fast space check per instruction. |
| 127 static const intptr_t kMinimumGap = 32; | 120 static constexpr intptr_t kMinimumGap = 32; |
| 128 | 121 |
| 129 uintptr_t Contents; | 122 uintptr_t Contents; |
| 130 uintptr_t Cursor; | 123 uintptr_t Cursor; |
| 131 uintptr_t Limit; | 124 uintptr_t Limit; |
| 132 // The member variable is named Assemblr to avoid hiding the class Assembler. | 125 // The member variable is named Assemblr to avoid hiding the class Assembler. |
| 133 Assembler &Assemblr; | 126 Assembler &Assemblr; |
| 134 // List of pool-allocated fixups relative to the current function. | 127 // List of pool-allocated fixups relative to the current function. |
| 135 FixupRefList Fixups; | 128 FixupRefList Fixups; |
| 136 | 129 |
| 137 uintptr_t cursor() const { return Cursor; } | 130 uintptr_t cursor() const { return Cursor; } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 protected: | 219 protected: |
| 227 // Buffer's constructor uses the Allocator, so it needs to appear after it. | 220 // Buffer's constructor uses the Allocator, so it needs to appear after it. |
| 228 // TODO(jpp): dependencies on construction order are a nice way of shooting | 221 // TODO(jpp): dependencies on construction order are a nice way of shooting |
| 229 // yourself in the foot. Fix this. | 222 // yourself in the foot. Fix this. |
| 230 AssemblerBuffer Buffer; | 223 AssemblerBuffer Buffer; |
| 231 }; | 224 }; |
| 232 | 225 |
| 233 } // end of namespace Ice | 226 } // end of namespace Ice |
| 234 | 227 |
| 235 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ | 228 #endif // SUBZERO_SRC_ICEASSEMBLER_H_ |
| OLD | NEW |