Path: blob/master/runtime/compiler/net/MessageBuffer.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2020, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "net/MessageBuffer.hpp"23#include <cstring>2425namespace JITServer26{27MessageBuffer::MessageBuffer() :28_capacity(INITIAL_BUFFER_SIZE),29_allocator(TR::Compiler->persistentGlobalAllocator())30{31_storage = allocateMemory(_capacity);32if (!_storage)33throw std::bad_alloc();34_curPtr = _storage;35}3637void38MessageBuffer::expandIfNeeded(uint32_t requiredSize)39{40// if the data size becomes larger than buffer capacity,41// expand the storage42if (requiredSize > _capacity)43{44expand(requiredSize, size());45}46}4748void49MessageBuffer::expand(uint32_t requiredSize, uint32_t numBytesToCopy)50{51TR_ASSERT_FATAL((requiredSize > _capacity), "requiredSize %u has to be greater than _capacity %u", requiredSize, _capacity);52TR_ASSERT_FATAL((numBytesToCopy <= _capacity), "numBytesToCopy %u has to be less than _capacity %u", numBytesToCopy, _capacity);5354_capacity = computeRequiredCapacity(requiredSize);55uint32_t curSize = size();5657char *newStorage = allocateMemory(_capacity);58if (!newStorage)59throw std::bad_alloc();6061memcpy(newStorage, _storage, numBytesToCopy);6263freeMemory(_storage);64_storage = newStorage;65_curPtr = _storage + curSize;66}6768uint32_t69MessageBuffer::writeData(const void *dataStart, uint32_t dataSize, uint8_t paddingSize)70{71// write dataSize bytes starting from dataStart address72// into the buffer. Might require buffer expansion.73// Return the offset into the buffer for the beginning of data74uint32_t requiredSize = size() + dataSize + paddingSize;75expandIfNeeded(requiredSize);76char *data = _curPtr;77memcpy(_curPtr, dataStart, dataSize);78_curPtr += dataSize + paddingSize;79return offset(data);80}8182uint8_t83MessageBuffer::alignCurrentPositionOn64Bit()84{85// Compute the amount of padding required to align _curPtr on 64-bit boundary86uintptr_t alignedPtr = ((uintptr_t)_curPtr + 0x7) & (~((uintptr_t)0x7));87uint8_t padding = (uint8_t)(alignedPtr - (uintptr_t)_curPtr); // Guaranteed to fit on a byte8889// Expand the buffer if it's too small to contain the padding90uint32_t requiredSize = size() + padding;91expandIfNeeded(requiredSize);9293// Advance _curPtr to align it on 64-bit94_curPtr += padding;9596return padding;97}9899uint32_t100MessageBuffer::computeRequiredCapacity(uint32_t requiredSize)101{102// Compute the nearest power of 2 that can fit requiredSize bytes103if (requiredSize <= _capacity)104return _capacity;105uint32_t extendedCapacity = _capacity * 2;106while (requiredSize > extendedCapacity)107extendedCapacity *= 2;108return extendedCapacity;109}110};111112113114