| 213 | } |
| 214 | |
| 215 | Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept { |
| 216 | size_t treeIndex; |
| 217 | |
| 218 | if (size == 32) |
| 219 | treeIndex = kIndex32; |
| 220 | else if (size == 16) |
| 221 | treeIndex = kIndex16; |
| 222 | else if (size == 8) |
| 223 | treeIndex = kIndex8; |
| 224 | else if (size == 4) |
| 225 | treeIndex = kIndex4; |
| 226 | else if (size == 2) |
| 227 | treeIndex = kIndex2; |
| 228 | else if (size == 1) |
| 229 | treeIndex = kIndex1; |
| 230 | else |
| 231 | return DebugUtils::errored(kErrorInvalidArgument); |
| 232 | |
| 233 | ConstPool::Node* node = _tree[treeIndex].get(data); |
| 234 | if (node) { |
| 235 | dstOffset = node->_offset; |
| 236 | return kErrorOk; |
| 237 | } |
| 238 | |
| 239 | // Before incrementing the current offset try if there is a gap that can |
| 240 | // be used for the requested data. |
| 241 | size_t offset = ~static_cast<size_t>(0); |
| 242 | size_t gapIndex = treeIndex; |
| 243 | |
| 244 | while (gapIndex != kIndexCount - 1) { |
| 245 | ConstPool::Gap* gap = _gaps[treeIndex]; |
| 246 | |
| 247 | // Check if there is a gap. |
| 248 | if (gap) { |
| 249 | size_t gapOffset = gap->_offset; |
| 250 | size_t gapLength = gap->_length; |
| 251 | |
| 252 | // Destroy the gap for now. |
| 253 | _gaps[treeIndex] = gap->_next; |
| 254 | ConstPool_freeGap(this, gap); |
| 255 | |
| 256 | offset = gapOffset; |
| 257 | ASMJIT_ASSERT(Utils::isAligned<size_t>(offset, size)); |
| 258 | |
| 259 | gapLength -= size; |
| 260 | if (gapLength > 0) |
| 261 | ConstPool_addGap(this, gapOffset, gapLength); |
| 262 | } |
| 263 | |
| 264 | gapIndex++; |
| 265 | } |
| 266 | |
| 267 | if (offset == ~static_cast<size_t>(0)) { |
| 268 | // Get how many bytes have to be skipped so the address is aligned accordingly |
| 269 | // to the 'size'. |
| 270 | size_t diff = Utils::alignDiff<size_t>(_size, size); |
| 271 | |
| 272 | if (diff != 0) { |
no test coverage detected