protected internal OffHeapNumberArray(long length, int itemSize, long @base, MemoryAllocationTracker allocationTracker) : base(itemSize, @base) { UnsafeUtil.assertHasUnsafe(); this.LengthConflict = length; this.AllocationTracker = allocationTracker; long dataSize = length * itemSize; bool itemSizeIsPowerOfTwo = Integer.bitCount(itemSize) == 1; if (UnsafeUtil.allowUnalignedMemoryAccess || !itemSizeIsPowerOfTwo) { // we can end up here even if we require aligned memory access. Reason is that item size // isn't power of two anyway and so we have to fallback to safer means of accessing the memory, // i.e. byte for byte. _allocatedBytes = dataSize; this._allocatedAddress = this.Address = UnsafeUtil.allocateMemory(_allocatedBytes, allocationTracker); } else { // the item size is a power of two and we're required to access memory aligned // so we can allocate a bit more to ensure we can get an aligned memory address to start from. _allocatedBytes = dataSize + itemSize - 1; this._allocatedAddress = UnsafeUtil.allocateMemory(_allocatedBytes, allocationTracker); this.Address = UnsafeUtil.alignedMemory(_allocatedAddress, itemSize); } }