diff --git a/src/mapleall/maple_phase/BUILD.gn b/src/mapleall/maple_phase/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..653603ba25016a542ca761beb13236ba94ff695e --- /dev/null +++ b/src/mapleall/maple_phase/BUILD.gn @@ -0,0 +1,24 @@ +include_libmplphase = [ + "${MAPLEALL_ROOT}/maple_me/include", + "${MAPLEALL_ROOT}/maple_ipa/include", + "${MAPLEALL_ROOT}/maple_util/include", + "${MAPLEALL_ROOT}/mempool/include", + "${MAPLEALL_ROOT}/maple_phase/include", + "${MAPLEALL_ROOT}/maple_ir/include", + "${MAPLEALL_ROOT}/mpl2mpl/include", + "${MAPLEALL_ROOT}/huawei_secure_c/include", + "${MAPLEALL_ROOT}/maple_driver/include", +] + +src_libmplphase = [ + "src/phase_impl.cpp", + "src/phase_driver.cpp", +] + +configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] + +static_library("libmplphase") { + sources = src_libmplphase + include_dirs = include_libmplphase + output_dir = "${root_out_dir}/lib/${HOST_ARCH}" +} \ No newline at end of file diff --git a/src/mapleall/maple_phase/src/phase_driver.cpp b/src/mapleall/maple_phase/src/phase_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97b5b35975d3c67f6bd67bb30f2975fbffaacb0c --- /dev/null +++ b/src/mapleall/maple_phase/src/phase_driver.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "phase_driver.h" +#include "mpl_timer.h" + +namespace maple { +constexpr long kAlternateUnits = 1000.0; +thread_local PhaseDriverImpl *PhaseDriver::phaseImplLocal = nullptr; +PhaseDriver::PhaseDriver(const std::string &phaseName) + : MplScheduler(phaseName), module(nullptr), phaseImpl(nullptr), phaseName(phaseName) {} + +void PhaseDriver::RunAll(MIRModule *currModule, int thread, bool bSeq) { + module = currModule; + phaseImpl = NewPhase(); + CHECK_FATAL(phaseImpl != nullptr, "null ptr check"); + phaseImpl->GlobalInit(); + if (thread == 1) { + RunSerial(); + } else { + RunParallel(thread, bSeq); + } + delete phaseImpl; + phaseImpl = nullptr; +} + +void PhaseDriver::RunSerial() { + phaseImplLocal = NewPhase(); + CHECK_FATAL(phaseImplLocal != nullptr, "null ptr check"); + phaseImplLocal->LocalInit(); + MPLTimer timer; + if (dumpTime) { + timer.Start(); + } + RegisterTasks(); + if (dumpTime) { + timer.Stop(); + INFO(kLncInfo, "PhaseDriver::RegisterTasks (%s): %lf ms", + phaseName.c_str(), timer.ElapsedMicroseconds() / kAlternateUnits); + timer.Start(); + } + MplTask *task = GetTaskToRun(); + while (task != nullptr) { + MplTaskParam *paramRun = CallbackGetTaskRunParam(); + task->Run(paramRun); + MplTaskParam *paramFinish = CallbackGetTaskFinishParam(); + task->Run(paramFinish); + } + if (dumpTime) { + timer.Stop(); + INFO(kLncInfo, "PhaseDriver::RunTask (%s): %lf ms", + phaseName.c_str(), timer.ElapsedMicroseconds() / kAlternateUnits); + } +} + +void PhaseDriver::RunParallel(int thread, bool bSeq) { + MPLTimer timer; + if (dumpTime) { + timer.Start(); + } + RegisterTasks(); + if (dumpTime) { + timer.Stop(); + INFO(kLncInfo, "PhaseDriver::RegisterTasks (%s): %lf ms", + phaseName.c_str(), timer.ElapsedMicroseconds() / kAlternateUnits); + } + if (dumpTime) { + timer.Start(); + } + int ret = RunTask(thread, bSeq); + CHECK_FATAL(ret == 0, "RunTask failed"); + if (dumpTime) { + timer.Stop(); + INFO(kLncInfo, "PhaseDriver::RunTask (%s): %lf ms", + phaseName.c_str(), timer.ElapsedMicroseconds() / kAlternateUnits); + } +} + +void PhaseDriver::CallbackThreadMainStart() { + phaseImplLocal = NewPhase(); + CHECK_FATAL(phaseImplLocal != nullptr, "null ptr check"); + phaseImplLocal->LocalInit(); +} + +void PhaseDriver::CallbackThreadMainEnd() { + delete phaseImplLocal; + phaseImplLocal = nullptr; +} +} // namespace maple diff --git a/src/mapleall/maple_phase/src/phase_impl.cpp b/src/mapleall/maple_phase/src/phase_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec21c7033abf6600fc4defb4bb900b793c938efe --- /dev/null +++ b/src/mapleall/maple_phase/src/phase_impl.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "phase_impl.h" +#include +#include "mpl_timer.h" + +namespace maple { +// ========== FuncOptimizeImpl ========== +FuncOptimizeImpl::FuncOptimizeImpl(MIRModule &mod, KlassHierarchy *kh, bool currTrace) + : klassHierarchy(kh), trace(currTrace), module(&mod) { + builder = module->GetMIRBuilder(); +} + +FuncOptimizeImpl::~FuncOptimizeImpl() { + klassHierarchy = nullptr; + currFunc = nullptr; + module = nullptr; +} + + +void FuncOptimizeImpl::ProcessFunc(MIRFunction *func) { + currFunc = func; + builder->SetCurrentFunction(*func); + if (func->GetBody() != nullptr) { + ProcessBlock(*func->GetBody()); + } +} + +void FuncOptimizeImpl::ProcessBlock(StmtNode &stmt) { + switch (stmt.GetOpCode()) { + case OP_if: { + IfStmtNode &ifStmtNode = static_cast(stmt); + if (ifStmtNode.GetThenPart() != nullptr) { + ProcessBlock(*ifStmtNode.GetThenPart()); + } + break; + } + case OP_while: + case OP_dowhile: { + WhileStmtNode &whileStmtNode = static_cast(stmt); + if (whileStmtNode.GetBody() != nullptr) { + ProcessBlock(*whileStmtNode.GetBody()); + } + break; + } + case OP_block: { + BlockNode &block = static_cast(stmt); + for (StmtNode *stmtNode = block.GetFirst(), *next = nullptr; stmtNode != nullptr; stmtNode = next) { + next = stmtNode->GetNext(); + ProcessBlock(*stmtNode); + } + break; + } + default: { + ProcessStmt(stmt); + break; + } + } +} + +FuncOptimizeIterator::FuncOptimizeIterator(const std::string &phaseName, std::unique_ptr phaseImpl) + : phaseImpl(std::move(phaseImpl)) {} + +FuncOptimizeIterator::~FuncOptimizeIterator() = default; + +void FuncOptimizeIterator::Run() { + CHECK_NULL_FATAL(phaseImpl); + for (MIRFunction *func : phaseImpl->GetMIRModule().GetFunctionList()) { + phaseImpl->ProcessFunc(func); + } + phaseImpl->Finish(); +} +} // namespace maple diff --git a/src/mapleall/mempool/BUILD.gn b/src/mapleall/mempool/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..68e5116076162df3e7c14d0a5081b546848d9e85 --- /dev/null +++ b/src/mapleall/mempool/BUILD.gn @@ -0,0 +1,35 @@ +src_libmempool = [ + "src/maple_string.cpp", + "src/mempool.cpp", +] +include_directories = [ + "${MAPLEALL_ROOT}/mempool/include", + "${MAPLEALL_ROOT}/maple_ir/include", + "${MAPLEALL_ROOT}/maple_util/include", + "${MAPLEALL_ROOT}/maple_driver/include", + "${MAPLEALL_ROOT}/huawei_secure_c/include", +] + +configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] + + +static_library("libmempool") { + sources = src_libmempool + include_dirs = include_directories + output_dir = "${root_out_dir}/lib/${HOST_ARCH}" +} + +executable("MemPool") { + sources = [ + "src/MPTest.cpp", + ] + + include_dirs = include_directories + + deps = [ + ":libmempool", + "${MAPLEALL_ROOT}/huawei_secure_c:libHWSecureC", + "${MAPLEALL_ROOT}/maple_driver:liboption_parser", + "${MAPLEALL_ROOT}/maple_util:libmplutil", + ] +} diff --git a/src/mapleall/mempool/src/MPTest.cpp b/src/mapleall/mempool/src/MPTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01794bce94acd34f5f925e8eacec2ab18a0bb70d --- /dev/null +++ b/src/mapleall/mempool/src/MPTest.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include +#include "mempool.h" +#include "mempool_allocator.h" +#include "maple_string.h" +#include "mpl_logging.h" +#include "securec.h" +using namespace maple; +struct Structure { + int id; + float height; +}; + +class MyClass { + public: + MyClass(int currId, const std::string &currName) { + id = currId; + name = currName; + }; + ~MyClass() {}; + int id; + std::string name; +}; + +int main() { + // 1. Create a memory pool controler instance; + MemPoolCtrler mpc; + // 2. Create two memory pools on mpc + MemPool *mp1 = mpc.NewMemPool("Test Memory Pool 1"); + MemPool *mp2 = mpc.NewMemPool("Test Memory Pool 2"); + // 3. Usage of memory pool, Malloc/Call on primitive types + // char string + constexpr int lengthOfHelloWorld = 12; + char *charP = static_cast(mp1->Malloc(lengthOfHelloWorld * sizeof(char))); + errno_t cpyRes = strcpy_s(charP, lengthOfHelloWorld, "Hello world"); + if (cpyRes != 0) { + LogInfo::MapleLogger() << "call strcpy_s failed" << std::endl; + return 0; + } + LogInfo::MapleLogger() << charP << std::endl; + // int, float, double + constexpr int arrayLen = 10; + int *intP = static_cast(mp1->Calloc(arrayLen * sizeof(int))); + CHECK_FATAL(intP, "null ptr check "); + for (int i = 0; i < arrayLen; ++i) { + intP[i] = i * i; + } + for (int i = 0; i < arrayLen - 1; ++i) { + LogInfo::MapleLogger() << intP[i] << " ,"; + } + LogInfo::MapleLogger() << intP[arrayLen - 1] << std::endl; + float *floatP = static_cast(mp1->Malloc(arrayLen * sizeof(float))); + for (int i = 0; i < arrayLen; ++i) { + floatP[i] = 10.0 / (i + 1); // test float num is 10.0 + } + for (int i = 0; i < arrayLen - 1; ++i) { + LogInfo::MapleLogger() << floatP[i] << " ,"; + } + LogInfo::MapleLogger() << floatP[arrayLen - 1] << std::endl; + // 4. Allocate memory on struct + Structure *structP = mp1->New(); + structP->height = 1024; // test num is 1024. + structP->id = 0; + LogInfo::MapleLogger() << "Structure: my_struct height=" << structP->height << " feet," << "id= x" << + structP->id << std::endl; + // 5. Allocate memory on class constructor + MyClass *myClass = mp1->New(1, "class name"); + LogInfo::MapleLogger() << "Class: my_class id=" << myClass->id << " , name=" << myClass->name << std::endl; + // 7. Memory Pool supports std library such list, vector, string, map, set. + // using mempool + MapleAllocator mpAllocator(mp2); + // vector + MapleVector myVector(mpAllocator.Adapter()); + for (int i = 0; i < arrayLen; ++i) { + myVector.push_back(i * i * i); + } + MapleVector::iterator itr; + for (itr = myVector.begin(); itr != myVector.end(); ++itr) { + LogInfo::MapleLogger() << *itr << " ,"; + } + LogInfo::MapleLogger() << std::endl; + // stack + MapleQueue myQueue(mpAllocator.Adapter()); + myQueue.push_back(1); + myQueue.push_back(2); + myQueue.push_back(3); + LogInfo::MapleLogger() << "Queue front is" << myQueue.front() << std::endl; + LogInfo::MapleLogger() << "Queue back is" << myQueue.back() << std::endl; + myQueue.pop_back(); + LogInfo::MapleLogger() << "after pop() vector top is" << myQueue.back() << std::endl; + // String + MapleString myString(mp2); + myString = "Using my mempool"; + myString += " example"; + LogInfo::MapleLogger() << myString << std::endl; + // list + MapleList myList(mpAllocator.Adapter()); + for (int i = 0; i < arrayLen; ++i) { + myList.push_back(1000.0 / (i + 1)); // test float num is 1000.0 + } + MapleList::iterator listItr; + for (listItr = myList.begin(); listItr != myList.end(); ++listItr) { + LogInfo::MapleLogger() << *listItr << " ,"; + } + LogInfo::MapleLogger() << std::endl; + // Map + MapleMap myMap(std::less(), mpAllocator.Adapter()); + for (int i = 0; i < arrayLen; ++i) { + MapleString temp(mp2); + temp += std::to_string(i); + temp += " value"; + myMap.insert(std::pair(i, temp)); + } + MapleMap::iterator mapItr; + for (mapItr = myMap.begin(); mapItr != myMap.end(); ++mapItr) { + LogInfo::MapleLogger() << "key= " << mapItr->first << ", value=" << mapItr->second << std::endl; + } + // Set + MapleSet mySet(std::less(), mpAllocator.Adapter()); + for (int i = 0; i < arrayLen; ++i) { + MapleString temp(mp2); + temp += std::to_string(i * i); + temp.append(" set values"); + mySet.insert(temp); + } + MapleSet::iterator setItr; + for (setItr = mySet.begin(); setItr != mySet.end(); ++setItr) { + LogInfo::MapleLogger() << "set value =" << *setItr << std::endl; + } + // Delete memory pool + mpc.DeleteMemPool(mp1); + mpc.DeleteMemPool(mp2); + return 1; +} diff --git a/src/mapleall/mempool/src/maple_string.cpp b/src/mapleall/mempool/src/maple_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1a35c3828d7bbb47552136a557becd903c416b2e --- /dev/null +++ b/src/mapleall/mempool/src/maple_string.cpp @@ -0,0 +1,416 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "maple_string.h" +#include "securec.h" +namespace maple { +MapleString::MapleString(const char *str, size_t size, MemPool *currMp) + : data(NewData(currMp, str, size)), + memPool(currMp), + dataLength(size) {} + +MapleString::MapleString(const char *str, MemPool *currMp) + : MapleString(str, StrLen(str), currMp) {} + +MapleString::MapleString(size_t size, MemPool *currMp) + : MapleString(nullptr, size, currMp) {} + +MapleString::MapleString(const MapleString &str, MemPool *currMp) + : MapleString(str.data, str.dataLength, currMp) {} + +MapleString::MapleString(const MapleString &str) + : MapleString(str, str.memPool) {} + +MapleString::MapleString(const std::string &str, MemPool *currMp) + : MapleString(str.data(), str.length(), currMp) {} + +char *MapleString::NewData(MemPool *memPool, const char *source, size_t len) { + MIR_ASSERT(memPool != nullptr); + if (source == nullptr && len == 0) { + return nullptr; + } + char *str = static_cast(memPool->Malloc((len + 1) * sizeof(char))); + CHECK_FATAL(str != nullptr, "MemPool::Malloc failed"); + if (source != nullptr && len != 0) { + errno_t err = memcpy_s(str, len, source, len); + CHECK_FATAL(err == EOK, "memcpy_s failed"); + } + str[len] = 0; + return str; +} + +void MapleString::clear() { + data = nullptr; + dataLength = 0; +} + +size_t MapleString::find(const MapleString &str, size_t pos) const { + if ((dataLength - pos) < str.dataLength) { + return std::string::npos; + } + for (size_t i = pos; i < (dataLength - str.dataLength + 1); ++i) { + if (data[i] == str[0]) { + size_t j = 0; + for (; j < str.dataLength; ++j) { + if (data[i + j] == str[j]) { + continue; + } else { + break; + } + } + if (j == str.dataLength) { + return i; + } + } + } + return std::string::npos; +} + +size_t MapleString::find(const char *str, size_t pos) const { + if (str == nullptr) { + return std::string::npos; + } + size_t strLen = strlen(str); + if ((dataLength - pos) < strLen) { + return std::string::npos; + } + for (size_t i = pos; i < (dataLength - strLen + 1); ++i) { + if (data[i] == str[0]) { + size_t j = 0; + for (; j < strLen; ++j) { + if (data[i + j] == str[j]) { + continue; + } else { + break; + } + } + if (j == strLen) { + return i; + } + } + } + return std::string::npos; +} + +size_t MapleString::find_last_of(const char *str, size_t pos) const { + if (str == nullptr) { + return std::string::npos; + } + size_t strLen = strlen(str); + if ((dataLength - pos) < strLen) { + return std::string::npos; + } + for (ssize_t i = (dataLength - strLen); i >= pos; --i) { + if (data[i] == str[0]) { + size_t j = 0; + for (; j < strLen; ++j) { + if (data[i + j] == str[j]) { + continue; + } else { + break; + } + } + if (j == strLen) { + return i; + } + } + } + return std::string::npos; +} + +size_t MapleString::find(const char *str, size_t pos, size_t n) const { + if (str == nullptr) { + return std::string::npos; + } + if ((dataLength - pos) < n) { + return std::string::npos; + } + for (size_t i = pos; i < (dataLength - n + 1); ++i) { + if (data[i] == str[0]) { + size_t j = 0; + for (; j < n; ++j) { + if (data[i + j] == str[j]) { + continue; + } else { + break; + } + } + if (j == n) { + return i; + } + } + } + return std::string::npos; +} + +size_t MapleString::find(char c, size_t pos) const { + if (dataLength == 0 || pos >= dataLength) { + return std::string::npos; + } + size_t i = pos; + for (; i < dataLength; ++i) { + if (data[i] == c) { + return i; + } + } + return std::string::npos; +} + +MapleString MapleString::substr(size_t pos, size_t len) const { + if (len == 0) { + MIR_FATAL("Error: MapleString substr len is 0"); + } + if (pos > dataLength) { + MIR_FATAL("Error: MapleString substr pos is out of boundary"); + } + len = (len + pos) > dataLength ? (dataLength - pos) : len; + MapleString newStr(memPool); + newStr.data = static_cast(newStr.memPool->Malloc((1 + len) * sizeof(char))); + for (size_t i = 0; i < len; ++i) { + newStr[i] = this->data[i + pos]; + } + newStr.dataLength = len; + newStr.data[newStr.dataLength] = '\0'; + return newStr; +} + +MapleString &MapleString::insert(size_t pos, const MapleString &str) { + if (pos > dataLength || str.dataLength == 0) { + return *this; + } + data = static_cast( + memPool->Realloc(data, (1 + dataLength) * sizeof(char), (1 + dataLength + str.dataLength) * sizeof(char))); + CHECK_FATAL(data != nullptr, "null ptr check "); + MapleString temp(memPool); + if (dataLength - pos) { + temp = this->substr(pos, dataLength - pos); + } else { + temp = ""; + } + dataLength += str.dataLength; + for (size_t i = 0; i < str.dataLength; ++i) { + data[pos + i] = str.data[i]; + } + if (temp == nullptr) { + CHECK_FATAL(false, "temp null ptr check"); + } + for (size_t j = 0; j < temp.dataLength; ++j) { + data[pos + str.dataLength + j] = temp.data[j]; + } + data[dataLength] = '\0'; + return *this; +} + +MapleString &MapleString::insert(size_t pos, const MapleString &str, size_t subPos, size_t subLen) { + MapleString subStr = str.substr(subPos, subLen); + this->insert(pos, subStr); + return *this; +} + +MapleString &MapleString::insert(size_t pos, const char *s) { + if (s == nullptr) { + return *this; + } + size_t sLen = strlen(s); + if (pos > dataLength || sLen == 0) { + return *this; + } + MapleString subStr(s, memPool); + this->insert(pos, subStr); + return *this; +} + +MapleString &MapleString::insert(size_t pos, const char *s, size_t n) { + if (s == nullptr) { + return *this; + } + size_t sLen = strlen(s); + if (pos > dataLength || sLen == 0) { + return *this; + } + n = ((n > sLen) ? sLen : n); + MapleString subStr(s, memPool); + subStr = subStr.substr(0, n); + this->insert(pos, subStr); + return *this; +} + +MapleString &MapleString::insert(size_t pos, size_t n, char c) { + if (pos > dataLength) { + return *this; + } + MapleString subStr(n, memPool); + for (size_t i = 0; i < n; ++i) { + subStr[i] = c; + } + this->insert(pos, subStr); + return *this; +} + +MapleString &MapleString::push_back(const char c) { + this->append(1, c); + return *this; +} + +MapleString &MapleString::append(const MapleString &str) { + if (str.empty()) { + return *this; + } + this->insert(dataLength, str); + return *this; +} + +MapleString &MapleString::append(const std::string &str) { + if (str.length() <= 0) { + return *this; + } + this->insert(dataLength, str.c_str()); + return *this; +} + +MapleString &MapleString::append(const MapleString &str, size_t subPos, size_t subLen) { + this->append(str.substr(subPos, subLen)); + return *this; +} + +MapleString &MapleString::append(const char *s) { + if (s == nullptr) { + return *this; + } + MapleString subStr(s, memPool); + this->append(subStr); + return *this; +} + +MapleString &MapleString::append(const char *s, size_t n) { + if (s == nullptr) { + return *this; + } + MapleString subStr(s, memPool); + this->append(subStr, 0, n); + return *this; +} + +MapleString &MapleString::append(size_t n, char c) { + MapleString subStr(n, memPool); + for (size_t i = 0; i < n; ++i) { + subStr[i] = c; + } + this->append(subStr); + return *this; +} + +MapleString &MapleString::assign(const MapleString &str) { + *this = str; + return *this; +} + +MapleString &MapleString::assign(const MapleString &str, size_t subPos, size_t subLen) { + *this = str.substr(subPos, subLen); + return *this; +} + +MapleString &MapleString::assign(const char *s) { + *this = s; + return *this; +} + +MapleString &MapleString::assign(const char *s, size_t n) { + MapleString subStr(s, memPool); + subStr = subStr.substr(0, n); + *this = subStr; + return *this; +} + +MapleString &MapleString::assign(size_t n, char c) { + MapleString subStr(n, memPool); + for (size_t i = 0; i < n; ++i) { + subStr[i] = c; + } + this->assign(subStr); + return *this; +} + +// global operators +bool operator==(const MapleString &str1, const MapleString &str2) { + if (str1.dataLength != str2.dataLength) { + return false; + } + char *tmp1 = str1.data; + char *tmp2 = str2.data; + while (*tmp1 != 0) { + if (*tmp1 != *tmp2) { + return false; + } + ++tmp1; + ++tmp2; + } + return true; +} + +bool operator==(const MapleString &str1, const char *str2) { + if (str2 == nullptr) { + return false; // Should we return str1.dataLength==0 ? + } + size_t size = strlen(str2); + if (str1.dataLength != size) { + return false; + } + char *tmp = str1.data; + CHECK_NULL_FATAL(tmp); + while (*tmp != 0) { + if (*tmp != *str2) { + return false; + } + ++tmp; + ++str2; + } + return true; +} + +bool operator==(const char *str1, const MapleString &str2) { + size_t size = strlen(str1); + if (str2.dataLength != size) { + return false; + } + char *tmp = str2.data; + CHECK_NULL_FATAL(tmp); + while (*tmp != 0) { + if (*tmp != *str1) { + return false; + } + ++tmp; + ++str1; + } + return true; +} + +bool operator!=(const MapleString &str1, const MapleString &str2) { + return !(str1 == str2); +} + +bool operator!=(const MapleString &str1, const char *str2) { + return !(str1 == str2); +} + +bool operator!=(const char *str1, const MapleString &str2) { + return !(str1 == str2); +} + +bool operator<(const MapleString &str1, const MapleString &str2) { + CHECK_FATAL(!str1.empty(), "empty string check"); + CHECK_FATAL(!str2.empty(), "empty string check"); + return (strcmp(str1.c_str(), str2.c_str()) < 0); +} +} // namespace maple diff --git a/src/mapleall/mempool/src/mempool.cpp b/src/mapleall/mempool/src/mempool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..008bb75d1994c5fcc1b4d970970309d97d8fb7b7 --- /dev/null +++ b/src/mapleall/mempool/src/mempool.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "mempool.h" +#include +#include +#include +#include +#include "securec.h" +#include "mpl_logging.h" + +namespace maple { +MemPoolCtrler memPoolCtrler; +bool MemPoolCtrler::freeMemInTime = false; + +// Destructor, free all allocated memory pool and blocks +MemPoolCtrler::~MemPoolCtrler() { + // Delete Memory Pool + for (MemPool *memPool : memPools) { + delete memPool; + } + // Delete all free_memory_block + for (MemBlock *block : freeMemBlocks) { + free(block); + } + for (auto it = largeFreeMemBlocks.begin(); it != largeFreeMemBlocks.end(); ++it) { + for (auto itr = (*it).second.begin(); itr != (*it).second.end(); ++itr) { + free(*itr); + } + } +} + +// Allocate a new memory pool and register it in controller +MemPool *MemPoolCtrler::NewMemPool(const std::string &name) { + auto memPool = new (std::nothrow) MemPool(*this, name); + if (memPool == nullptr) { + CHECK_FATAL(false, "ERROR: Can't allocate new memory pool"); + return nullptr; + } + memPools.insert(memPool); + return memPool; +} + +// Re-cycle all memory blocks allocated on a memory pool to free list +void MemPoolCtrler::DeleteMemPool(MemPool *memPool) { + CHECK_NULL_FATAL(memPool); + // Transfer memory blocks to ctrler->freeMemBlocks stack + while (!memPool->memBlockStack.empty()) { + MemBlock *mb = memPool->memBlockStack.top(); + mb->available = mb->origSize; + mb->ptr = MEM_BLOCK_FIRST_PTR(mb); + freeMemBlocks.push_back(mb); + memPool->memBlockStack.pop(); + } + // Transfer large memory blocks to ctrler->freeMemBlocks stack + while (!memPool->largeMemBlockStack.empty()) { + MemBlock *mb = memPool->largeMemBlockStack.top(); + mb->available = mb->origSize; + mb->ptr = MEM_BLOCK_FIRST_PTR(mb); + size_t key = (mb->available / 0x800) + 1; // Minimum BlockSize is 2K. + if (largeFreeMemBlocks.find(key) == largeFreeMemBlocks.end()) { + largeFreeMemBlocks[key] = std::set(); + } + largeFreeMemBlocks[key].insert(mb); + memPool->largeMemBlockStack.pop(); + } + // Delete entry of this mempool in memPools and delete the mempool node + memPools.erase(memPool); + delete memPool; + if (freeMemInTime) { + FreeMem(); + } +} + +void MemPoolCtrler::FreeMem() { + for (MemBlock *block : freeMemBlocks) { + free(block); + } + for (auto it = largeFreeMemBlocks.begin(); it != largeFreeMemBlocks.end(); ++it) { + for (auto itr = (*it).second.begin(); itr != (*it).second.end(); ++itr) { + free(*itr); + } + } + freeMemBlocks.clear(); + largeFreeMemBlocks.clear(); +} + +MemPool::~MemPool() { + while (!memBlockStack.empty()) { + free(memBlockStack.top()); + memBlockStack.pop(); + } + while (!largeMemBlockStack.empty()) { + free(largeMemBlockStack.top()); + largeMemBlockStack.pop(); + } +} + +// Return a pointer that points to size of memory from memory block +void *MemPool::Malloc(size_t size) { + void *result = nullptr; + MemPoolCtrler::MemBlock *b = nullptr; + // If size is smaller than 2K, fetch size of memory from the last memory block + if (size <= kMinBlockSize) { + // Get the top memory block from the top + b = (memBlockStack.empty() ? nullptr : memBlockStack.top()); + // the last operation was a push + if (b == nullptr || b->available < size) { + b = GetMemBlock(); + } + // Return the pointer that points to the starting point + 8; + } else { + b = GetLargeMemBlock(size); + } + CHECK_FATAL(b != nullptr, "ERROR: Malloc error"); + result = static_cast(b->ptr); + b->ptr = static_cast(static_cast(b->ptr) + size); + // available size decrease + int tmp = b->available - size; + CHECK_FATAL(tmp >= 0, "ERROR: Malloc error"); + b->available = tmp; + return result; +} + +// Malloc size of memory from memory pool, then set 0 +void *MemPool::Calloc(size_t size) { + void *p = Malloc(BITS_ALIGN(size)); + if (p == nullptr) { + CHECK_FATAL(false, "ERROR: Calloc error\n"); + return nullptr; + } + errno_t eNum = memset_s(p, BITS_ALIGN(size), 0, BITS_ALIGN(size)); + if (eNum != EOK) { + CHECK_FATAL(false, "memset_s failed"); + } + return p; +} + +// Realloc new size of memory +void *MemPool::Realloc(const void *ptr, size_t oldSize, size_t newSize) { + void *result = Malloc(newSize); + if (result != nullptr) { + size_t copySize = ((newSize > oldSize) ? oldSize : newSize); + if (copySize != 0 && ptr != nullptr) { + errno_t eNum = memcpy_s(result, copySize, ptr, copySize); + if (eNum != EOK) { + FATAL(kLncFatal, "memcpy_s failed"); + } + } + } else { + CHECK_FATAL(false, "Error Realloc\n"); + } + return result; +} + +void MemPool::ReleaseContainingMem() { + while (!memBlockStack.empty()) { + MemPoolCtrler::MemBlock *block1 = memBlockStack.top(); + block1->available = block1->origSize; + block1->ptr = MEM_BLOCK_FIRST_PTR(block1); + ctrler.freeMemBlocks.push_back(block1); + memBlockStack.pop(); + } + while (!largeMemBlockStack.empty()) { + MemPoolCtrler::MemBlock *block2 = largeMemBlockStack.top(); + block2->available = block2->origSize; + block2->ptr = MEM_BLOCK_FIRST_PTR(block2); + size_t key = (block2->available / 0x800) + 1; // Minimum BlockSize is 2K. + if (ctrler.largeFreeMemBlocks.find(key) == ctrler.largeFreeMemBlocks.end()) { + std::set tmp; + ctrler.largeFreeMemBlocks[key] = tmp; + } + ctrler.largeFreeMemBlocks[key].insert(block2); + largeMemBlockStack.pop(); + } +} + +// Allocate a new memory block +MemPoolCtrler::MemBlock *MemPool::GetMemBlock() { + MemPoolCtrler::MemBlock *block = nullptr; + // Try to fetch one from free_memory_list + if (!ctrler.freeMemBlocks.empty()) { + block = ctrler.freeMemBlocks.front(); + ctrler.freeMemBlocks.erase(ctrler.freeMemBlocks.begin()); + } else { + // Allocate a block of memory, 2K + MemBlock head size + size_t total = kMinBlockSize + kMemBlockOverhead; + block = static_cast(malloc(total)); + if (block == nullptr) { + CHECK_FATAL(false, "ERROR: Allocate memory block failed\n"); + return nullptr; + } + // Available memory size is BlockSize + block->available = kMinBlockSize; + block->origSize = kMinBlockSize; + // Set the pointer points to the first available byte + block->ptr = MEM_BLOCK_FIRST_PTR(block); + } + memBlockStack.push(block); + return block; +} + +// Allocate a large memory block when user allocates memory size > 2K +MemPoolCtrler::MemBlock *MemPool::GetLargeMemBlock(size_t size) { + MemPoolCtrler::MemBlock *block = nullptr; + size_t key = (size / kMinBlockSize) + 1; + if (ctrler.largeFreeMemBlocks.find(key) != ctrler.largeFreeMemBlocks.end() && + ctrler.largeFreeMemBlocks[key].size()) { + block = *(ctrler.largeFreeMemBlocks[key].begin()); + if (block->origSize >= size) { + ctrler.largeFreeMemBlocks[key].erase(ctrler.largeFreeMemBlocks[key].begin()); + } else { + block = nullptr; + } + } + if (block == nullptr) { + // Allocate a large memory block + block = static_cast(malloc(size + kMemBlockOverhead)); + if (block == nullptr) { + CHECK_FATAL(false, "ERROR: Fail to allocate large memory block\n"); + return nullptr; + } + block->origSize = size; + block->available = size; + block->ptr = MEM_BLOCK_FIRST_PTR(block); + } + largeMemBlockStack.push(block); + return block; +} + +} // namespace maple diff --git a/src/mrt/deplibs/libmplandroid.so b/src/mrt/deplibs/libmplandroid.so index b0aed0c0c9bf00aa3565fa06eda50fafaeffa58e..e180f06caba33b87daa42be5aa1484d2396ed480 100755 Binary files a/src/mrt/deplibs/libmplandroid.so and b/src/mrt/deplibs/libmplandroid.so differ