diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index f071e5c511b63e3356e24c0a83381256761c3433..4620037a8a26ea73005b3f7961ef254711b5cdee 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 7a2379f40f8ac5c860f6825318d908e28962cbd4..841a8e918b45ff8e7682c27f1a89c626129f3630 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/bin/mplcg b/src/bin/mplcg index 1496426867c6793ab6da140a280ceec6815fc0cd..ce80bbb770a861804e8bf5d123518a810ae46a21 100755 Binary files a/src/bin/mplcg and b/src/bin/mplcg differ diff --git a/src/maple_driver/include/driver_runner.h b/src/maple_driver/include/driver_runner.h index 9b0d2827a1b134c563e4ec6e666ec9bc55d0fd4c..dee25639ec7fa178b13d40119e690d5d68044670 100644 --- a/src/maple_driver/include/driver_runner.h +++ b/src/maple_driver/include/driver_runner.h @@ -32,7 +32,7 @@ class DriverRunner final { DriverRunner(MIRModule *theModule, const std::vector &exeNames, Options *mpl2mplOptions, std::string mpl2mplInput, MeOption *meOptions, const std::string &meInput, std::string actualInput, MemPool *optMp, bool timePhases = false, - bool genMemPl = false) + bool genMeMpl = false) : theModule(theModule), exeNames(exeNames), mpl2mplOptions(mpl2mplOptions), @@ -42,11 +42,11 @@ class DriverRunner final { actualInput(actualInput), optMp(optMp), timePhases(timePhases), - genMemPl(genMemPl) {} + genMeMpl(genMeMpl) {} DriverRunner(MIRModule *theModule, const std::vector &exeNames, std::string actualInput, MemPool *optMp, - bool timePhases = false, bool genVtableImpl = false, bool genMemPl = false) - : DriverRunner(theModule, exeNames, nullptr, "", nullptr, "", actualInput, optMp, timePhases, genMemPl) {} + bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) + : DriverRunner(theModule, exeNames, nullptr, "", nullptr, "", actualInput, optMp, timePhases, genMeMpl) {} ~DriverRunner() = default; @@ -63,7 +63,7 @@ class DriverRunner final { std::string actualInput; MemPool *optMp; bool timePhases = false; - bool genMemPl = false; + bool genMeMpl = false; std::string printOutExe; static bool FuncOrderLessThan(const MIRFunction *left, const MIRFunction *right); diff --git a/src/maple_driver/include/mpl_options.h b/src/maple_driver/include/mpl_options.h index c1963c4f9b230f01413343d959be925803711ea4..5bf29c68ce004ba05b10c3ed5580027b4f03f86a 100644 --- a/src/maple_driver/include/mpl_options.h +++ b/src/maple_driver/include/mpl_options.h @@ -122,7 +122,7 @@ class MplOptions { printCommandStr(""), debugFlag(false), timePhases(false), - genMemPl(false), + genMeMpl(false), genVtableImpl(false), verify(false) {} ~MplOptions() = default; @@ -162,11 +162,11 @@ class MplOptions { return optimizationLevel; } - const bool GetSetDefaultLevel() const { + bool HasSetDefaultLevel() const { return setDefaultLevel; } - const bool GetIsSaveTmps() const { + bool HasSetSaveTmps() const { return isSaveTmps; } @@ -190,23 +190,23 @@ class MplOptions { return printCommandStr; } - const bool GetDebugFlag() const { + bool HasSetDebugFlag() const { return debugFlag; } - const bool GetTimePhases() const { + bool HasSetTimePhases() const { return timePhases; } - const bool GetGenMemPl() const { - return genMemPl; + bool HasSetGenMeMpl() const { + return genMeMpl; } - const bool GetGenVtableImpl() const { + bool HasSetGenVtableImpl() const { return genVtableImpl; } - const bool GetVerify() const { + bool HasSetVerify() const { return verify; } @@ -231,7 +231,7 @@ class MplOptions { std::string printCommandStr; bool debugFlag; bool timePhases; - bool genMemPl; + bool genMeMpl; bool genVtableImpl; bool verify; bool Init(const std::string &inputFile); @@ -239,7 +239,6 @@ class MplOptions { ErrorCode DecideRunType(); ErrorCode DecideRunningPhases(); ErrorCode CheckInputFileValidity(); - ErrorCode CheckRunMode(RunMode mode); ErrorCode CheckFileExits(); void AddOption(const mapleOption::Option &option); ErrorCode UpdatePhaseOption(const std::string &args, const std::string &exeName); diff --git a/src/maple_driver/src/compiler.cpp b/src/maple_driver/src/compiler.cpp index a84f2aff57800829cba3317846ba382f6729d78b..cdc5b3face7726c771d84c965e5d24f8e1e180f1 100644 --- a/src/maple_driver/src/compiler.cpp +++ b/src/maple_driver/src/compiler.cpp @@ -71,13 +71,13 @@ const std::string Compiler::MakeOption(const MplOptions &options) { std::ostringstream strOption; for (auto finalOption : finalOptions) { strOption << " " << finalOption.first << finalOption.second.GetconnectSymbol() << finalOption.second.GetValue(); - if (options.GetDebugFlag()) { + if (options.HasSetDebugFlag()) { LogInfo::MapleLogger() << Compiler::GetName() << " options: " << finalOption.first << " " << finalOption.second.GetValue() << '\n'; } } strOption << " " << this->GetInputFileName(options); - if (options.GetDebugFlag()) { + if (options.HasSetDebugFlag()) { LogInfo::MapleLogger() << Compiler::GetName() << " input files: " << GetInputFileName(options) << '\n'; } return FileUtils::ConvertPathIfNeeded(strOption.str()); diff --git a/src/maple_driver/src/compiler_factory.cpp b/src/maple_driver/src/compiler_factory.cpp index 74bdbac58e025f864d0074c159acee2d79df7303..9242ae4414fd84978a7d50db48dd13abbab556b8 100644 --- a/src/maple_driver/src/compiler_factory.cpp +++ b/src/maple_driver/src/compiler_factory.cpp @@ -100,7 +100,7 @@ ErrorCode CompilerFactory::Compile(const MplOptions &mplOptions) { } } - if (!mplOptions.GetIsSaveTmps() || !mplOptions.GetSaveFiles().empty()) { + if (!mplOptions.HasSetSaveTmps() || !mplOptions.GetSaveFiles().empty()) { auto tmpFiles = std::vector(); for (auto compiler : compilers) { compiler->GetTmpFilesToDelete(mplOptions, tmpFiles); diff --git a/src/maple_driver/src/driver_runner.cpp b/src/maple_driver/src/driver_runner.cpp index 666ad48700e5eba1ef40f283e9d09aed2d6d1936..c720b73133403fbcde7736371e2f2d6f0e8a43d9 100644 --- a/src/maple_driver/src/driver_runner.cpp +++ b/src/maple_driver/src/driver_runner.cpp @@ -191,7 +191,7 @@ void DriverRunner::AddPhases(InterleavedManager &mgr, const std::vectorsecond) { - if (options.GetDebugFlag()) { + if (options.HasSetDebugFlag()) { LogInfo::MapleLogger() << "Me options: " << opt.Index() << " " << opt.OptionKey() << " " << opt.Args() << '\n'; } @@ -172,7 +172,7 @@ Options *MapleCombCompiler::MakeMpl2MplOptions(const MplOptions &options, maple: return mpl2mplOption; } for (auto &opt : inputOptions->second) { - if (options.GetDebugFlag()) { + if (options.HasSetDebugFlag()) { LogInfo::MapleLogger() << "mpl2mpl options: " << opt.Index() << " " << opt.OptionKey() << " " << opt.Args() << '\n'; } @@ -255,7 +255,7 @@ ErrorCode MapleCombCompiler::Compile(const MplOptions &options, MIRModulePtr &th PrintCommand(options); DriverRunner runner(theModule, options.GetRunningExes(), mpl2mplOptions.get(), fileName, meOptions.get(), fileName, fileName, optMp, - options.GetTimePhases(), options.GetGenMemPl()); + options.HasSetTimePhases(), options.HasSetGenMeMpl()); ErrorCode nErr = runner.Run(); memPoolCtrler.DeleteMemPool(optMp); diff --git a/src/maple_driver/src/mpl_options.cpp b/src/maple_driver/src/mpl_options.cpp index 9b5a6257a8b9e692b2d437e62b89cd60eff542e5..d739aab91483a4d5b9042048d20b2fd300b98ae8 100644 --- a/src/maple_driver/src/mpl_options.cpp +++ b/src/maple_driver/src/mpl_options.cpp @@ -107,7 +107,7 @@ ErrorCode MplOptions::HandleGeneralOptions() { this->printCommandStr += " -time-phases"; break; case kGenMeMpl: - this->genMemPl = true; + this->genMeMpl = true; this->printCommandStr += " --genmempl"; break; case kGenVtableImpl: @@ -120,6 +120,8 @@ ErrorCode MplOptions::HandleGeneralOptions() { break; case kSaveTemps: this->isSaveTmps = true; + this->genMeMpl = true; + this->genVtableImpl = true; StringUtils::Split(opt.Args(), this->saveFiles, ','); this->printCommandStr += " --save-temps"; break; @@ -144,23 +146,24 @@ ErrorCode MplOptions::HandleGeneralOptions() { ErrorCode MplOptions::DecideRunType() { ErrorCode ret = ErrorCode::kErrorNoError; + bool runModeConflict = false; for (auto opt : optionParser->GetOptions()) { switch (opt.Index()) { case kOptimization0: - ret = CheckRunMode(RunMode::kCustomRun); // O0 and run should not appear at the same time - if (ret != ErrorCode::kErrorNoError) { - return ErrorCode::kErrorInvalidParameter; + if (runMode == RunMode::kCustomRun) {// O0 and run should not appear at the same time + runModeConflict = true; + } else { + runMode = RunMode::kAutoRun; + optimizationLevel = kO0; } - runMode = RunMode::kAutoRun; - optimizationLevel = kO0; break; case kRun: - ret = CheckRunMode(RunMode::kAutoRun); // O0(O2) and run should not appear at the same time - if (ret != ErrorCode::kErrorNoError) { - return ErrorCode::kErrorInvalidParameter; + if (runMode == RunMode::kAutoRun) {// O0 and run should not appear at the same time + runModeConflict = true; + } else { + runMode = RunMode::kCustomRun; + this->UpdateRunningExe(opt.Args()); } - runMode = RunMode::kCustomRun; - this->UpdateRunningExe(opt.Args()); break; case kInFile: { if (!Init(opt.Args())) { @@ -172,6 +175,10 @@ ErrorCode MplOptions::DecideRunType() { break; } } + if (runModeConflict) { + LogInfo::MapleLogger(kLlErr) << "Cannot set auto mode and run mode at the same time!\n"; + ret = ErrorCode::kErrorInvalidParameter; + } return ret; } @@ -181,6 +188,7 @@ ErrorCode MplOptions::DecideRunningPhases() { bool isNeedMplcg = true; switch (inputFileType) { case InputFileType::kJar: + /* fall-through */ case InputFileType::kClass: this->UpdateRunningExe(kBinNameJbc2mpl); break; @@ -232,14 +240,6 @@ ErrorCode MplOptions::CheckInputFileValidity() { return ret; } -ErrorCode MplOptions::CheckRunMode(RunMode mode) { - if (runMode == mode) { - LogInfo::MapleLogger(kLlErr) << "Cannot set auto mode and run mode at the same time!\n"; - return ErrorCode::kErrorInvalidParameter; - } - return ErrorCode::kErrorNoError; -} - ErrorCode MplOptions::CheckFileExits() { ErrorCode ret = ErrorCode::kErrorNoError; if (inputFiles == "") { diff --git a/src/maple_driver/src/mplcg_compiler.cpp b/src/maple_driver/src/mplcg_compiler.cpp index 591e1845d60cf74cb5d413883f06dc84892df6d9..19174f0f6c9cbb1fe5f3d346d32177cc86163de0 100644 --- a/src/maple_driver/src/mplcg_compiler.cpp +++ b/src/maple_driver/src/mplcg_compiler.cpp @@ -21,7 +21,7 @@ using namespace maple; const DefaultOption MplcgCompiler::GetDefaultOptions(const MplOptions &options) { DefaultOption defaultOptions = { nullptr, 0 }; - if (options.GetOptimizationLevel() == kO0 && options.GetSetDefaultLevel()) { + if (options.GetOptimizationLevel() == kO0 && options.HasSetDefaultLevel()) { defaultOptions.mplOptions = kMplcgDefaultOptionsO0; defaultOptions.length = sizeof(kMplcgDefaultOptionsO0) / sizeof(MplOption); } diff --git a/src/maple_ir/include/mir_symbol.h b/src/maple_ir/include/mir_symbol.h index 2defc694069d4afd7c106402cd3f6337276989cb..8431810c7105e1ddd79d128526a8872ae8bebef3 100644 --- a/src/maple_ir/include/mir_symbol.h +++ b/src/maple_ir/include/mir_symbol.h @@ -338,6 +338,7 @@ class MIRSymbol { bool IsReflectionFieldsInfo() const; bool IsReflectionFieldsInfoCompact() const; bool IsReflectionSuperclassInfo() const; + bool IsReflectionFieldOffsetData() const; bool IsReflectionClassInfo() const; bool IsReflectionArrayClassInfo() const; bool IsReflectionClassInfoPtr() const; diff --git a/src/maple_ir/include/opcodes.h b/src/maple_ir/include/opcodes.h index ce4198361bc9f5cf1dcd4aa1619cff944c39b5c8..d9e81ed192f49dd6808bf192d1b243ffeac74d11 100644 --- a/src/maple_ir/include/opcodes.h +++ b/src/maple_ir/include/opcodes.h @@ -23,5 +23,19 @@ enum Opcode : std::uint8_t { #undef OPCODE kOpLast, }; + +inline constexpr bool IsDAssign(Opcode code) { + return (code == OP_dassign || code == OP_maydassign); +} + +inline constexpr bool IsCallAssigned(Opcode code) { + return (code == OP_callassigned || code == OP_virtualcallassigned || + code == OP_virtualicallassigned || code == OP_superclasscallassigned || + code == OP_interfacecallassigned || code == OP_interfaceicallassigned || + code == OP_customcallassigned || code == OP_polymorphiccallassigned || + code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); + } + } // namespace maple #endif // MAPLE_IR_INCLUDE_OPCODES_H diff --git a/src/maple_ir/src/lexer.cpp b/src/maple_ir/src/lexer.cpp index 730df3534f5fe302848a1b5ffafd074c008946a4..c266b2fcb7ccddd57b1c483de11c5f27a5737c6d 100644 --- a/src/maple_ir/src/lexer.cpp +++ b/src/maple_ir/src/lexer.cpp @@ -19,21 +19,19 @@ #include "mpl_logging.h" #include "mir_module.h" #include "securec.h" -#include "mpl_utils.h" +#include "utils.h" namespace maple { + +int32_t HexCharToDigit(char c) { + int32_t ret = utils::ToDigit<16, int32_t>(c); + return (ret != INT32_MAX ? ret : 0); +} + static uint8 Char2num(char c) { - if (c >= '0' && c <= '9') { - return static_cast(c - '0'); - } - if (c >= 'A' && c <= 'F') { - return static_cast(c - 'A' + 10); - } - if (c >= 'a' && c <= 'f') { - return static_cast(c - 'a' + 10); - } - ASSERT(false, "not a hex value"); - return 0; + uint8 ret = utils::ToDigit<16>(c); + ASSERT(ret != UINT8_MAX, "not a hex value"); + return ret; } /* Read (next) line from the MIR (text) file, and return the read @@ -193,10 +191,10 @@ TokenKind MIRLexer::GetHexConst(uint32 valStart, bool negative) { name = line.substr(valStart, curIdx - valStart); return kTkInvalid; } - uint64 tmp = static_cast(Utils::HexCharToDigit(c)); + uint64 tmp = static_cast(HexCharToDigit(c)); c = GetNextCurrentCharWithUpperCheck(); while (isxdigit(c)) { - tmp = (tmp << 4) + static_cast(Utils::HexCharToDigit(c)); + tmp = (tmp << 4) + static_cast(HexCharToDigit(c)); c = GetNextCurrentCharWithUpperCheck(); } theIntVal = static_cast(static_cast(tmp)); @@ -215,16 +213,16 @@ TokenKind MIRLexer::GetHexConst(uint32 valStart, bool negative) { TokenKind MIRLexer::GetIntConst(uint32 valStart, bool negative) { char c = GetCharAtWithUpperCheck(curIdx); - theIntVal = Utils::HexCharToDigit(c); + theIntVal = HexCharToDigit(c); c = GetNextCurrentCharWithUpperCheck(); if (theIntVal == 0) { // octal while (isdigit(c)) { - theIntVal = ((static_cast(theIntVal)) << 3) + Utils::HexCharToDigit(c); + theIntVal = ((static_cast(theIntVal)) << 3) + HexCharToDigit(c); c = GetNextCurrentCharWithUpperCheck(); } } else { while (isdigit(c)) { - theIntVal = (theIntVal * 10) + Utils::HexCharToDigit(c); + theIntVal = (theIntVal * 10) + HexCharToDigit(c); c = GetNextCurrentCharWithUpperCheck(); } } @@ -336,10 +334,10 @@ TokenKind MIRLexer::GetTokenWithPrefixPercent() { char c = GetCharAtWithUpperCheck(curIdx); if (isdigit(c)) { int valStart = curIdx - 1; - theIntVal = Utils::HexCharToDigit(c); + theIntVal = HexCharToDigit(c); c = GetNextCurrentCharWithUpperCheck(); while (isdigit(c)) { - theIntVal = (theIntVal * 10) + Utils::HexCharToDigit(c); + theIntVal = (theIntVal * 10) + HexCharToDigit(c); c = GetNextCurrentCharWithUpperCheck(); } name = line.substr(valStart, curIdx - valStart); diff --git a/src/maple_ir/src/mir_symbol.cpp b/src/maple_ir/src/mir_symbol.cpp index 40a69516a345d8672812397611174cc2b07476ee..c0891f62cb576a04ce75e054dddaa79f152f9c69 100644 --- a/src/maple_ir/src/mir_symbol.cpp +++ b/src/maple_ir/src/mir_symbol.cpp @@ -171,6 +171,10 @@ bool MIRSymbol::IsReflectionSuperclassInfo() const { return (GetName().find(SUPERCLASSINFO_PREFIX_STR) == 0); } +bool MIRSymbol::IsReflectionFieldOffsetData() const { + return (GetName().find(kFieldOffsetDataPrefixStr) == 0); +} + bool MIRSymbol::IsReflectionClassInfo() const { return (GetName().find(CLASSINFO_PREFIX_STR) == 0); } diff --git a/src/maple_me/include/me_function.h b/src/maple_me/include/me_function.h index a20e53706b5f4492d7cce3182968310c5fdb1d96..5e075099f4de17f21a77ef8b356e1b30d891fb1d 100644 --- a/src/maple_me/include/me_function.h +++ b/src/maple_me/include/me_function.h @@ -298,8 +298,8 @@ class MeFunction : public FuncEmit { void DeleteBasicBlock(const BB &bb); BB *NextBB(const BB *bb); BB *PrevBB(const BB *bb); - /* create label for bb */ - void CreateBBLabel(BB &bb); + /* get or create label for bb */ + LabelIdx GetOrCreateBBLabel(BB &bb); /* clone stmtnodes from orig to newBB */ void CloneBasicBlock(BB &newBB, const BB &orig); BB &SplitBB(BB &bb, StmtNode &splitPoint, BB *newBB = nullptr); @@ -460,7 +460,7 @@ class MeFunction : public FuncEmit { void CreateBasicBlocks(); void SetTryBlockInfo(const StmtNode *nextStmt, StmtNode *tryStmt, BB *lastTryBB, BB *curBB, BB *newBB); void RemoveEhEdgesInSyncRegion(); - MIRFunction *CurFunction(void) const { + MIRFunction *CurFunction() const { return mirModule.CurFunction(); } void SplitBBPhysically(BB &bb, StmtNode &splitPoint, BB &newBB); diff --git a/src/maple_me/include/me_ir.h b/src/maple_me/include/me_ir.h index 04ec78cb049e3f8dd1c3b2e37beb0f003af2dba9..8138a33e70e7bbcaaba39e83bc6647834bfd755f 100644 --- a/src/maple_me/include/me_ir.h +++ b/src/maple_me/include/me_ir.h @@ -2612,5 +2612,11 @@ class DumpOptions { static bool simpleDump; static int dumpVsymNum; }; + } // namespace maple + +#define LOAD_SAFE_CAST_FOR_ME_EXPR +#define LOAD_SAFE_CAST_FOR_ME_STMT +#include "me_safe_cast_traits.def" + #endif // MAPLE_ME_INCLUDE_ME_IR_H diff --git a/src/maple_util/include/mpl_utils.h b/src/maple_me/include/me_safe_cast_traits.def similarity index 39% rename from src/maple_util/include/mpl_utils.h rename to src/maple_me/include/me_safe_cast_traits.def index 51fb71e0aa3ef9427d25de54d20bf4e5cd80c22c..b392d16e2d334341df6aa360815446872f008a64 100644 --- a/src/maple_util/include/mpl_utils.h +++ b/src/maple_me/include/me_safe_cast_traits.def @@ -12,27 +12,48 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v1 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_MPL_UTILS_H -#define MAPLE_UTIL_INCLUDE_MPL_UTILS_H - -namespace { - constexpr int digitIndex = 10; -} - -namespace maple { -class Utils { - public: - static int HexCharToDigit(char c) { - if (c >= '0' && c <= '9') { - return (c - '0'); - } else if (c >= 'A' && c <= 'F') { - return (c - 'A' + digitIndex); - } else if (c >= 'a' && c <= 'f') { - return (c - 'a' + digitIndex); - } else { - return 0; - } - } -}; -} // namespace maple -#endif // MAPLE_UTIL_INCLUDE_MPL_UTILS_H +#include + +namespace maple { +#ifdef LOAD_SAFE_CAST_FOR_ME_EXPR +#undef LOAD_SAFE_CAST_FOR_ME_EXPR +inline MeExprOp safe_cast_traits(const MeExpr &expr) { + return expr.GetMeOp(); +}; + +template <> struct ExtractCode { + enum {value = kMeOpVar}; +}; + +template <> struct ExtractCode { + enum {value = kMeOpOp}; +}; + +template <> struct ExtractCode { + enum {value = kMeOpNary}; +}; + +template <> struct ExtractCode { + enum {value = kMeOpIvar}; +}; +#endif + +#ifdef LOAD_SAFE_CAST_FOR_ME_STMT +#undef LOAD_SAFE_CAST_FOR_ME_STMT +inline Opcode safe_cast_traits(const MeStmt &stmt) { + return stmt.GetOp(); +} + +template <> struct ExtractCode { + enum {value = OP_dassign}; +}; + +template <> struct ExtractCode { + enum {value = OP_maydassign}; +}; + +template <> struct ExtractCode { + enum {value = OP_iassign}; +}; +#endif +} diff --git a/src/maple_me/src/me_bb_layout.cpp b/src/maple_me/src/me_bb_layout.cpp index 913764135c9c9216c5b9a9198178550815cee693..6747c87e599f692b15e0c368fd23ba0930507123 100644 --- a/src/maple_me/src/me_bb_layout.cpp +++ b/src/maple_me/src/me_bb_layout.cpp @@ -35,17 +35,15 @@ // 5. do step 3 for nextBB until all bbs are laid out namespace maple { static void CreateGoto(BB &bb, MeFunction &func, BB &fallthru) { - if (fallthru.GetBBLabel() == 0) { - func.CreateBBLabel(fallthru); - } + LabelIdx label = func.GetOrCreateBBLabel(fallthru); if (func.GetIRMap() != nullptr) { GotoNode stmt(OP_goto); GotoMeStmt *newGoto = func.GetIRMap()->New(&stmt); - newGoto->SetOffset(fallthru.GetBBLabel()); + newGoto->SetOffset(label); bb.AddMeStmtLast(newGoto); } else { GotoNode *newGoto = func.GetMirFunc()->GetCodeMempool()->New(OP_goto); - newGoto->SetOffset(fallthru.GetBBLabel()); + newGoto->SetOffset(label); bb.AddStmtNode(newGoto); } bb.SetKind(kBBGoto); @@ -68,36 +66,33 @@ bool BBLayout::BBEmptyAndFallthru(const BB &bb) { // Return true if bb only has conditonal branch stmt except comment bool BBLayout::BBContainsOnlyCondGoto(const BB &bb) const { - if (bb.GetAttributes(kBBAttrIsTryEnd)) { + if (bb.GetKind() != kBBCondGoto || bb.GetAttributes(kBBAttrIsTryEnd)) { return false; } - if (bb.GetKind() == kBBCondGoto) { - if (func.GetIRMap() != nullptr) { - auto &meStmts = bb.GetMeStmts(); - if (meStmts.empty()) { + + if (func.GetIRMap() != nullptr) { + auto &meStmts = bb.GetMeStmts(); + if (meStmts.empty()) { + return false; + } + for (auto itMeStmt = meStmts.begin(); itMeStmt != meStmts.rbegin().base(); ++itMeStmt) { + if (!itMeStmt->IsCondBr() && itMeStmt->GetOp() != OP_comment) { return false; } - for (auto itMeStmt = meStmts.begin(); itMeStmt != meStmts.rbegin().base(); ++itMeStmt) { - if (!itMeStmt->IsCondBr() && itMeStmt->GetOp() != OP_comment) { - return false; - } - } - return meStmts.back().IsCondBr(); - } else { - StmtNode *stmt = bb.GetStmtNodes().begin().d(); - if (stmt == nullptr) { + } + return meStmts.back().IsCondBr(); + } else { + auto &stmtNodes = bb.GetStmtNodes(); + if (stmtNodes.empty()) { + return false; + } + for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { + if (!itStmt->IsCondBr() && itStmt->GetOpCode() != OP_comment) { return false; } - auto &stmtNodes = bb.GetStmtNodes(); - for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { - if (!itStmt->IsCondBr() && itStmt->GetOpCode() != OP_comment) { - return false; - } - } - return bb.GetStmtNodes().back().IsCondBr(); } + return bb.GetStmtNodes().back().IsCondBr(); } - return false; } // Return the opposite opcode for condition/compare opcode. @@ -135,37 +130,33 @@ static Opcode GetOppositeOp(Opcode opc1) { } bool BBLayout::BBContainsOnlyGoto(const BB &bb) const { - if (bb.GetAttributes(kBBAttrIsTryEnd)) { + if (bb.GetKind() != kBBGoto || bb.GetAttributes(kBBAttrIsTryEnd)) { return false; } - if (bb.GetKind() == kBBGoto) { - if (func.GetIRMap() != nullptr) { - auto &meStmts = bb.GetMeStmts(); - if (meStmts.empty()) { + + if (func.GetIRMap() != nullptr) { + auto &meStmts = bb.GetMeStmts(); + if (meStmts.empty()) { + return false; + } + for (auto itMeStmt = meStmts.begin(); itMeStmt != meStmts.rbegin().base(); ++itMeStmt) { + if (itMeStmt->GetOp() != OP_goto && itMeStmt->GetOp() != OP_comment) { return false; } - for (auto itMeStmt = meStmts.begin(); itMeStmt != meStmts.rbegin().base(); ++itMeStmt) { - if (itMeStmt->GetOp() != OP_goto && itMeStmt->GetOp() != OP_comment) { - return false; - } - } - return meStmts.back().GetOp() == OP_goto; - } else { - StmtNode *stmt = bb.GetStmtNodes().begin().d(); - if (stmt == nullptr) { + } + return meStmts.back().GetOp() == OP_goto; + } else { + auto &stmtNodes = bb.GetStmtNodes(); + if (stmtNodes.empty()) { + return false; + } + for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { + if (itStmt->GetOpCode() != OP_goto && itStmt->GetOpCode() != OP_comment) { return false; } - - auto &stmtNodes = bb.GetStmtNodes(); - for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { - if (itStmt->GetOpCode() != OP_goto && itStmt->GetOpCode() != OP_comment) { - return false; - } - } - return bb.GetStmtNodes().back().GetOpCode() == OP_goto; } + return bb.GetStmtNodes().back().GetOpCode() == OP_goto; } - return false; } // Return true if all the following are satisfied: @@ -197,7 +188,7 @@ bool BBLayout::HasSameBranchCond(BB &bb1, BB &bb2) const { CondGotoMeStmt &meStmt2 = static_cast(bb2.GetMeStmts().back()); MeExpr *expr1 = meStmt1.GetOpnd(); MeExpr *expr2 = meStmt2.GetOpnd(); - // Compare the opcode. + // Compare the opcode: brtrue/brfalse if (!(meStmt1.GetOp() == meStmt2.GetOp() && expr1->GetOp() == expr2->GetOp()) && !(meStmt1.GetOp() == GetOppositeOp(meStmt2.GetOp()) && expr1->GetOp() == GetOppositeOp(expr2->GetOp()))) { return false; @@ -258,69 +249,61 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { } } else { auto &stmtNodes = bb.GetStmtNodes(); - if (stmtNodes.rbegin().base().d() == nullptr) { + if (stmtNodes.empty()) { return; } if (stmtNodes.back().GetOpCode() != OP_goto && !stmtNodes.back().IsCondBr()) { return; } } -start_: - ASSERT(!bb.GetSucc().empty(), "container check"); - BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc(1) : bb.GetSucc(0); - if (brTargetBB->GetAttributes(kBBAttrWontExit)) { - return; - } - if (!BBContainsOnlyGoto(*brTargetBB) && !BBEmptyAndFallthru(*brTargetBB) && - !(bb.GetKind() == kBBCondGoto && brTargetBB->GetKind() == kBBCondGoto && &bb != brTargetBB && - BBContainsOnlyCondGoto(*brTargetBB) && HasSameBranchCond(bb, *brTargetBB))) { - return; - } - // optimize stmt - BB *newTargetBB = brTargetBB->GetSucc().front(); - if (brTargetBB->GetKind() == kBBCondGoto) { - newTargetBB = brTargetBB->GetSucc(1); - } - if (newTargetBB->GetBBLabel() == 0) { - func.CreateBBLabel(*newTargetBB); - } - LabelIdx newTargetLabel = newTargetBB->GetBBLabel(); - if (func.GetIRMap() != nullptr) { - auto &lastStmt = bb.GetMeStmts().back(); - if (lastStmt.GetOp() == OP_goto) { - GotoMeStmt &gotoMeStmt = static_cast(lastStmt); - ASSERT(brTargetBB->GetBBLabel() == gotoMeStmt.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); - gotoMeStmt.SetOffset(newTargetLabel); - } else { - CondGotoMeStmt &gotoMeStmt = static_cast(lastStmt); - ASSERT(brTargetBB->GetBBLabel() == gotoMeStmt.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); - gotoMeStmt.SetOffset(newTargetLabel); + do { + ASSERT(!bb.GetSucc().empty(), "container check"); + BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc(1) : bb.GetSucc(0); + if (brTargetBB->GetAttributes(kBBAttrWontExit)) { + return; } - } else { - StmtNode &lastStmt = bb.GetStmtNodes().back(); - if (lastStmt.GetOpCode() == OP_goto) { - GotoNode &gotoNode = static_cast(lastStmt); - ASSERT(brTargetBB->GetBBLabel() == gotoNode.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); - gotoNode.SetOffset(newTargetLabel); + if (!BBContainsOnlyGoto(*brTargetBB) && !BBEmptyAndFallthru(*brTargetBB) && + !(bb.GetKind() == kBBCondGoto && brTargetBB->GetKind() == kBBCondGoto && &bb != brTargetBB && + BBContainsOnlyCondGoto(*brTargetBB) && HasSameBranchCond(bb, *brTargetBB))) { + return; + } + // optimize stmt + BB *newTargetBB = brTargetBB->GetSucc().front(); + if (brTargetBB->GetKind() == kBBCondGoto) { + newTargetBB = brTargetBB->GetSucc(1); + } + LabelIdx newTargetLabel = func.GetOrCreateBBLabel(*newTargetBB); + if (func.GetIRMap() != nullptr) { + auto &lastStmt = bb.GetMeStmts().back(); + if (lastStmt.GetOp() == OP_goto) { + GotoMeStmt &gotoMeStmt = static_cast(lastStmt); + ASSERT(brTargetBB->GetBBLabel() == gotoMeStmt.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); + gotoMeStmt.SetOffset(newTargetLabel); + } else { + CondGotoMeStmt &gotoMeStmt = static_cast(lastStmt); + ASSERT(brTargetBB->GetBBLabel() == gotoMeStmt.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); + gotoMeStmt.SetOffset(newTargetLabel); + } } else { - CondGotoNode &gotoNode = static_cast(lastStmt); - ASSERT(brTargetBB->GetBBLabel() == gotoNode.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); - gotoNode.SetOffset(newTargetLabel); + StmtNode &lastStmt = bb.GetStmtNodes().back(); + if (lastStmt.GetOpCode() == OP_goto) { + GotoNode &gotoNode = static_cast(lastStmt); + ASSERT(brTargetBB->GetBBLabel() == gotoNode.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); + gotoNode.SetOffset(newTargetLabel); + } else { + CondGotoNode &gotoNode = static_cast(lastStmt); + ASSERT(brTargetBB->GetBBLabel() == gotoNode.GetOffset(), "OptimizeBranchTarget: wrong branch target BB"); + gotoNode.SetOffset(newTargetLabel); + } } - } - // update CFG - if (bb.GetKind() == kBBCondGoto) { - bb.SetSucc(1, newTargetBB); - } else { - bb.SetSucc(0, newTargetBB); - } - newTargetBB->GetPred().push_back(&bb); - bb.RemoveBBFromVector(brTargetBB->GetPred()); - if (brTargetBB->GetPred().empty() && !laidOut[brTargetBB->GetBBId().idx]) { - laidOut[brTargetBB->GetBBId().idx] = true; - brTargetBB->RemoveBBFromVector(newTargetBB->GetPred()); - } - goto start_; // repeat until no more opportunity + // update CFG + bb.ReplaceSucc(brTargetBB, newTargetBB); + bb.RemoveBBFromVector(brTargetBB->GetPred()); + if (brTargetBB->GetPred().empty() && !laidOut[brTargetBB->GetBBId().idx]) { + laidOut[brTargetBB->GetBBId().idx] = true; + brTargetBB->RemoveBBFromVector(newTargetBB->GetPred()); + } + } while (true); } void BBLayout::AddBB(BB &bb) { @@ -378,6 +361,7 @@ BB *BBLayout::GetFallThruBBSkippingEmpty(BB &bb) { BB *oldFallthru = fallthru; fallthru = oldFallthru->GetSucc().front(); bb.ReplaceSucc(oldFallthru, fallthru); + oldFallthru->RemoveBBFromSucc(fallthru); } while (true); } @@ -452,18 +436,16 @@ AnalysisResult *MeDoBBLayout::Run(MeFunction *func, MeFuncResultMgr *funcResMgr, BB *brTargetBB = bb->GetSucc(1); if (brTargetBB != fallthru && fallthru->GetPred().size() > 1 && bbLayout->BBCanBeMoved(*brTargetBB, *bb)) { // flip the sense of the condgoto and lay out brTargetBB right here - if (fallthru->GetBBLabel() == 0) { - func->CreateBBLabel(*fallthru); - } + LabelIdx fallthruLabel = func->GetOrCreateBBLabel(*fallthru); if (func->GetIRMap() != nullptr) { CondGotoMeStmt &condGotoMeStmt = static_cast(bb->GetMeStmts().back()); ASSERT(brTargetBB->GetBBLabel() == condGotoMeStmt.GetOffset(), "bbLayout: wrong branch target BB"); - condGotoMeStmt.SetOffset(fallthru->GetBBLabel()); + condGotoMeStmt.SetOffset(fallthruLabel); condGotoMeStmt.SetOp((condGotoMeStmt.GetOp() == OP_brtrue) ? OP_brfalse : OP_brtrue); } else { CondGotoNode &condGotoNode = static_cast(bb->GetStmtNodes().back()); ASSERT(brTargetBB->GetBBLabel() == condGotoNode.GetOffset(), "bbLayout: wrong branch target BB"); - condGotoNode.SetOffset(fallthru->GetBBLabel()); + condGotoNode.SetOffset(fallthruLabel); condGotoNode.SetOpCode((condGotoNode.GetOpCode() == OP_brtrue) ? OP_brfalse : OP_brtrue); } bbLayout->AddBB(*brTargetBB); @@ -481,18 +463,16 @@ AnalysisResult *MeDoBBLayout::Run(MeFunction *func, MeFuncResultMgr *funcResMgr, bbLayout->AddLaidOut(false); newFallthru->SetKind(kBBGoto); bbLayout->SetNewBBInLayout(); - if (fallthru->GetBBLabel() == 0) { - func->CreateBBLabel(*fallthru); - } + LabelIdx fallthruLabel = func->GetOrCreateBBLabel(*fallthru); if (func->GetIRMap() != nullptr) { GotoNode stmt(OP_goto); GotoMeStmt *newGoto = func->GetIRMap()->New(&stmt); - newGoto->SetOffset(fallthru->GetBBLabel()); + newGoto->SetOffset(fallthruLabel); newFallthru->SetFirstMe(newGoto); newFallthru->SetLastMe(to_ptr(newFallthru->GetMeStmts().begin())); } else { GotoNode *newGoto = func->GetMirFunc()->GetCodeMempool()->New(OP_goto); - newGoto->SetOffset(fallthru->GetBBLabel()); + newGoto->SetOffset(fallthruLabel); newFallthru->SetFirst(newGoto); newFallthru->SetLast(newFallthru->GetStmtNodes().begin().d()); } diff --git a/src/maple_me/src/me_function.cpp b/src/maple_me/src/me_function.cpp index 1b119302fcabaec24e75b76a125a663acba345cf..309836adaf301aa3d6710d5545e02f7791299f8b 100644 --- a/src/maple_me/src/me_function.cpp +++ b/src/maple_me/src/me_function.cpp @@ -562,14 +562,16 @@ BB &MeFunction::SplitBB(BB &bb, StmtNode &splitPoint, BB *newBB) { } /* create label for bb */ -void MeFunction::CreateBBLabel(BB &bb) { - if (bb.GetBBLabel() != 0) { - return; +LabelIdx MeFunction::GetOrCreateBBLabel(BB &bb) { + LabelIdx label = bb.GetBBLabel(); + if (label != 0) { + return label; } - LabelIdx label = mirModule.CurFunction()->GetLabelTab()->CreateLabelWithPrefix('m'); + label = mirModule.CurFunction()->GetLabelTab()->CreateLabelWithPrefix('m'); mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(label); bb.SetBBLabel(label); labelBBIdMap.insert(std::make_pair(label, &bb)); + return label; } // Recognize the following kind of simple pattern and remove corresponding EH edges diff --git a/src/maple_util/include/mpl_logging.h b/src/maple_util/include/mpl_logging.h index 084a7f7f42f54b5d853a3fd6fff29f9757a473cc..7f3532e47e8540609af7b768e1e39774917dba49 100644 --- a/src/maple_util/include/mpl_logging.h +++ b/src/maple_util/include/mpl_logging.h @@ -222,6 +222,8 @@ class LogInfo { } \ } while (0) +#define CHECK_NULL_FATAL(ptr) CHECK_FATAL(ptr != nullptr, "Failed with nullptr.") + #if ENABLE_ASSERT #define ASSERT(cond, fmt, ...) \ do { \ @@ -230,8 +232,11 @@ class LogInfo { abort(); \ } \ } while (0) + +#define ASSERT_NOT_NULL(ptr) ASSERT(ptr != nullptr, "Failed with nullptr.") #else #define ASSERT(cond, fmt, ...) +#define ASSERT_NOT_NULL(ptr) #endif // ENABLE_ASSERT // for user diff --git a/src/maple_util/include/name_mangler.h b/src/maple_util/include/name_mangler.h index 9af40f21fea64375c4698aafa172f216b929bc56..f245df8871daa7d3ba15c89ba44e26340760f3d2 100644 --- a/src/maple_util/include/name_mangler.h +++ b/src/maple_util/include/name_mangler.h @@ -88,6 +88,7 @@ static constexpr const char kMethodsInfoPrefixStr[] = "__methods_info__"; static constexpr const char kMethodsInfoCompactPrefixStr[] = "__methods_infocompact__"; static constexpr const char kFieldsInfoPrefixStr[] = "__fields_info__"; static constexpr const char kFieldsInfoCompactPrefixStr[] = "__fields_infocompact__"; +static constexpr const char kFieldOffsetDataPrefixStr[] = "__fieldOffsetData__"; static constexpr const char kRegJNITabPrefixStr[] = "__reg_jni_tab"; static constexpr const char kRegJNIFuncTabPrefixStr[] = "__reg_jni_func_tab"; static constexpr const char kReflectionStrtabPrefixStr[] = "__reflection_strtab"; diff --git a/src/maple_util/include/safe_cast.h b/src/maple_util/include/safe_cast.h new file mode 100644 index 0000000000000000000000000000000000000000..c17bfd4fabc8025501a3826ce8ed6b71274c4d28 --- /dev/null +++ b/src/maple_util/include/safe_cast.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#ifndef MAPLE_UTIL_INCLUDE_SAFE_CAST_H +#define MAPLE_UTIL_INCLUDE_SAFE_CAST_H + +namespace maple { + +template +struct ExtractCode { +}; + +template::value>> +inline bool instance_of(T &base) { + return safe_cast_traits(base) == ExtractCode::value; +} + +template::value>> +inline bool instance_of(T *base) { + return (base != nullptr && instance_of(*base)); +} + +template::value || std::is_const>::value, + std::add_pointer_t>>, + std::add_pointer_t>>, + typename = std::enable_if_t::value>> +inline RetT safe_cast(T &base) { + return (safe_cast_traits(base) == ExtractCode::value ? static_cast(&base) : nullptr); +} + +template::value || std::is_const>::value, + std::add_pointer_t>>, + std::add_pointer_t>>, + typename = std::enable_if_t::value>> +inline RetT safe_cast(T *base) { + return ((base != nullptr && safe_cast_traits(*base) == ExtractCode::value) ? + static_cast(base) : nullptr); +} + +} + +#endif //MAPLE_UTIL_INCLUDE_SAFE_CAST_H diff --git a/src/maple_util/include/utils.h b/src/maple_util/include/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..4bd45f1af7998127e9166cea5c83a456be494a2c --- /dev/null +++ b/src/maple_util/include/utils.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#ifndef MAPLE_UTIL_INCLUDE_UTILS_H +#define MAPLE_UTIL_INCLUDE_UTILS_H +#include +#include "mpl_logging.h" + +namespace maple { namespace utils { + +// Operations on char +inline constexpr bool IsDigit(char c) { + return (c >= '0' && c <= '9'); +} + +inline constexpr bool IsLower(char c) { + return (c >= 'a' && c <= 'z'); +} + +inline constexpr bool IsUpper(char c) { + return (c >= 'A' && c <= 'Z'); +} + +inline constexpr bool IsAlpha(char c) { + return (IsLower(c) || IsUpper(c)); +} + +inline constexpr bool IsAlnum(char c) { + return (IsAlpha(c) || IsDigit(c)); +} + +namespace __ToDigitImpl { + +template +struct TypeMax {}; + +template <> +struct TypeMax { + enum {value = UINT8_MAX}; +}; + +template <> +struct TypeMax { + enum {value = INT32_MAX}; +}; + +template +struct ToDigitImpl {}; + +template +struct ToDigitImpl<10, T> { + static T DoIt(char c) { + if (utils::IsDigit(c)) { + return c - '0'; + } + return TypeMax::value; + } +}; + +template +struct ToDigitImpl<8, T> { + static T DoIt(char c) { + if (c >= '0' && c < '8') { + return c - '0'; + } + return TypeMax::value; + } +}; + +template +struct ToDigitImpl<16, T> { + static T DoIt(char c) { + if (utils::IsDigit(c)) { + return c - '0'; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + return TypeMax::value; + } +}; +} + +template +inline constexpr T ToDigit(char c) { + return __ToDigitImpl::ToDigitImpl::DoIt(c); +} + +// Operations on pointer +template +inline T &ToRef(T *ptr) { + CHECK_NULL_FATAL(ptr); + return *ptr; +} + +template +inline typename T::element_type &ToRef(T &ptr) { + return ToRef(ptr.get()); +} + +}} // namespace maple::utils +#endif // MAPLE_UTIL_INCLUDE_UTILS_H diff --git a/src/mpl2mpl/include/reflection_analysis.h b/src/mpl2mpl/include/reflection_analysis.h index 5dccf08d193851714d0037bc3b3100ff0c9421af..f1bc1e012b28d8c96f2703546143dad303fd0eed 100644 --- a/src/mpl2mpl/include/reflection_analysis.h +++ b/src/mpl2mpl/include/reflection_analysis.h @@ -62,6 +62,7 @@ static constexpr char kDeclaringclassStr[] = "declaringclass"; static constexpr char kFieldInfoTypeName[] = "__field_info__"; static constexpr char kINFOAccessFlags[] = "INFO_access_flags"; static constexpr char kSuperclassinfoStr[] = "superclassinfo"; +static constexpr char kFieldOffsetDataStr[] = "fieldOffsetData"; static constexpr char kAnnotationvalueStr[] = "annotationvalue"; static constexpr char kMethodInfoTypeName[] = "__method_info__"; static constexpr char kClinitSuffixStr[] = "_3Cclinit_3E_7C_28_29V"; @@ -71,6 +72,7 @@ static constexpr char kClassMetadataRoTypeName[] = "__class_meta_ro__"; static constexpr char kMethodInVtabIndexStr[] = "method_in_vtab_index"; static constexpr char kClassStateInitializedStr[] = "classStateInitialized"; static constexpr char kSuperclassMetadataTypeName[] = "__superclass_meta__"; +static constexpr char kFieldOffsetDataTypeName[] = "__fieldOffsetDataType__"; static constexpr char kFieldInfoCompactTypeName[] = "__field_info_compact__"; static constexpr char kClassInitProtectRegionStr[] = "classInitProtectRegion"; static constexpr char kMethodInfoCompactTypeName[] = "__method_info_compact__"; @@ -146,7 +148,7 @@ enum struct MethodInfoCompact : uint32 { }; enum struct FieldProperty : uint32 { - kOffset, + kPOffset, kMod, kFlag, kIndex, @@ -157,7 +159,7 @@ enum struct FieldProperty : uint32 { }; enum struct FieldPropertyCompact : uint32 { - kOffset, + kPOffset, kMod, kTypeName, kIndex, @@ -174,6 +176,8 @@ static constexpr uint64 kMethodNotVirtual = 0x00000001; static constexpr uint64 kMethodFinalize = 0x00000002; static constexpr uint64 kMethodMetaCompact = 0x00000004; static constexpr uint64 kMethodAbstract = 0x00000010; +static constexpr uint64 kFieldReadOnly = 0x00000001; + #define CASE_CONDITION(ARRAYNAME, ELEM) \ case kValueInt: \ ARRAYNAME += std::to_string(ELEM->GetI32Val()); \ @@ -252,6 +256,7 @@ class ReflectionAnalysis : public AnalysisResult { static TyIdx fieldsInfoTyIdx; static TyIdx fieldsInfoCompactTyIdx; static TyIdx superclassMetadataTyIdx; + static TyIdx fieldOffsetDataTyIdx; static std::string strTab; static std::unordered_map str2IdxMap; static std::string strTabStartHot; @@ -312,6 +317,7 @@ class ReflectionAnalysis : public AnalysisResult { std::string GetArrayValue(MapleVector subElemVector, bool isSN = false); std::string GetAnnotationValue(MapleVector subElemVector, GStrIdx typeStrIdx); MIRSymbol *GenSuperClassMetaData(const Klass &klass, std::list superClassList); + void GenFieldOffsetData(const Klass &klass, std::vector> &fieldOffsetVector); MIRSymbol *GenFieldsMetaData(const Klass &klass); MIRSymbol *GenMethodsMetaData(const Klass &klass); static void GenMetadataType(MIRModule &mirModule); diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index 3064d9b80b2e67e474828bf616527e627e4342b0..abaa1faf65e75c56ac69be77a33ea567fb32b74b 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -310,16 +310,18 @@ void MUIDReplacement::GenericFuncDefTable() { // Create muidIdxTab to store the index in funcDefTab and funcDefMuidTab // With muidIdxTab, we can use index sorted by muid to find the index in funcDefTab and funcDefMuidTab // Use the left 1 bit of muidIdx to mark wether the function is weak or not. 1 is for weak - MIRIntConst *indexConst = nullptr; - if (reflectionList.find(mirFunc->GetName()) != reflectionList.end()) { - constexpr uint32 weakFuncFlag = 0x80000000; // 0b10000000 00000000 00000000 00000000 - indexConst = - GetMIRModule().GetMemPool()->New(weakFuncFlag | idx, *GlobalTables::GetTypeTable().GetUInt32()); - } else { - indexConst = GetMIRModule().GetMemPool()->New(idx, *GlobalTables::GetTypeTable().GetUInt32()); - } uint32 muidIdx = iter->second.second; + constexpr uint32 weakFuncFlag = 0x80000000; // 0b10000000 00000000 00000000 00000000 + MIRIntConst *indexConst = static_cast(muidIdxTabConst->GetConstVecItem(muidIdx)); + uint32 tempIdx = (indexConst->GetValue() & weakFuncFlag) | idx; + indexConst = GetMIRModule().GetMemPool()->New(tempIdx, *GlobalTables::GetTypeTable().GetUInt32()); muidIdxTabConst->SetConstVecItem(muidIdx, *indexConst); + if (reflectionList.find(mirFunc->GetName()) != reflectionList.end()) { + MIRIntConst *tempConst = static_cast(muidIdxTabConst->GetConstVecItem(idx)); + tempIdx = weakFuncFlag | tempConst->GetValue(); + tempConst = GetMIRModule().GetMemPool()->New(tempIdx, *GlobalTables::GetTypeTable().GetUInt32()); + muidIdxTabConst->SetConstVecItem(idx, *tempConst); + } // Store the real idx of funcdefTab, for ReplaceAddroffuncConst->FindIndexFromDefTable defMuidIdxMap[muid] = idx; idx++; diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index 3fe8690214a20077c854d3f810816118da2824ac..4f04d3ce48856abd58c589032b6e78c23e0208f5 100644 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -120,6 +120,7 @@ TyIdx ReflectionAnalysis::methodsInfoCompactTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::fieldsInfoTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::fieldsInfoCompactTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::superclassMetadataTyIdx = TyIdx(0); +TyIdx ReflectionAnalysis::fieldOffsetDataTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::invalidIdx = TyIdx(-1); namespace { constexpr int kModPublic = 1; // 0x00000001 @@ -741,6 +742,50 @@ MIRSymbol *ReflectionAnalysis::GenMethodsMetaData(const Klass &klass) { return methodsArraySt; } +void ReflectionAnalysis::GenFieldOffsetData(const Klass &klass, + std::vector> &fieldOffsetVector) { + size_t size = fieldOffsetVector.size(); + MIRModule &module = *mirModule; + MIRStructType &fieldOffsetType = + static_cast(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldOffsetDataTyIdx)); + MIRArrayType &fieldOffsetArrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(fieldOffsetType, size); + MIRAggConst *aggconst = module.GetMemPool()->New(module, fieldOffsetArrayType); + for (auto &fieldinfo : fieldOffsetVector) { + MIRAggConst *newconst = module.GetMemPool()->New(module, fieldOffsetType); + bool staticfield = (fieldinfo.second == -1); + FieldPair fieldP = fieldinfo.first; + TyIdx fieldTyidx = fieldP.second.first; + std::string originFieldname = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first); + if (staticfield) { + // Offset of the static field, we fill the global var address. + const GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first)); + MIRSymbol *gvarSt = GetSymbol(stridx, fieldTyidx); + if (gvarSt == nullptr) { + // If this static field is not used, the symbol will not be generated, + // so we just generate a weak one here. + gvarSt = CreateSymbol(stridx, fieldTyidx); + gvarSt->SetAttr(ATTR_weak); + gvarSt->SetAttr(ATTR_static); + } + mirBuilder.AddAddrofFieldConst(fieldOffsetType, *newconst, 1, *gvarSt); + } else { + // Offset of the instance field, we fill the index of fields here and let CG to fill in. + MIRClassType *mirClassType = klass.GetMIRClassType(); + ASSERT(mirClassType != nullptr, "GetMIRClassType() returns null"); + FieldID fldid = mirBuilder.GetStructFieldIDFromNameAndTypeParentFirstFoundInChild( + *mirClassType, originFieldname.c_str(), fieldP.second.first); + mirBuilder.AddIntFieldConst(fieldOffsetType, *newconst, 1, fldid); + } + aggconst->GetConstVec().push_back(newconst); + } + MIRSymbol *fieldsOffsetArraySt = GetOrCreateSymbol(NameMangler::kFieldOffsetDataPrefixStr + klass.GetKlassName(), + fieldOffsetArrayType.GetTypeIndex(), true); + // Direct access to fieldoffset is only possible within a .so. + fieldsOffsetArraySt->SetStorageClass(kScFstatic); + fieldsOffsetArraySt->SetKonst(aggconst); +} + MIRSymbol *ReflectionAnalysis::GenSuperClassMetaData(const Klass &klass, std::list superClassList) { MIRModule &module = *mirModule; size_t size = superClassList.size(); @@ -827,6 +872,7 @@ MIRSymbol *ReflectionAnalysis::GenFieldsMetaData(const Klass &klass) { j++; } ASSERT(i == size, "In class %s: %d fields seen, BUT %d fields declared", klass.GetKlassName().c_str(), i, size); + GenFieldOffsetData(klass, fieldinfoVec); int idx = 0; for (auto &fieldinfo : fieldinfoVec) { std::vector fieldsCompactLeb128Vec; @@ -843,28 +889,8 @@ MIRSymbol *ReflectionAnalysis::GenFieldsMetaData(const Klass &klass) { reflectionMuidStr += ty->GetName(); bool staticfield = (fieldinfo.second == -1); // ==== FieldMetadata ==== - // @offset: - if (staticfield) { - // Offset of the static field, we fill the global var address. - const GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( - GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first)); - MIRSymbol *gvarSt = GetSymbol(strIdx, fieldTyidx); - if (gvarSt == nullptr) { - // If this static field is not used, the symbol will not be generated, - // so we just generate a weak one here. - gvarSt = CreateSymbol(strIdx, fieldTyidx); - gvarSt->SetAttr(ATTR_weak); - gvarSt->SetAttr(ATTR_static); - } - mirBuilder.AddAddrofFieldConst(fieldsInfoType, *newconst, fieldID++, *gvarSt); - } else { - // Offset of the instance field, we fill the index of fields here and let CG to fill in. - MIRClassType *mirClassType = klass.GetMIRClassType(); - ASSERT(mirClassType != nullptr, "GetMIRClassType() returns null"); - FieldID fldID = mirBuilder.GetStructFieldIDFromNameAndTypeParentFirstFoundInChild( - *mirClassType, originFieldname.c_str(), fieldP.second.first); - mirBuilder.AddIntFieldConst(fieldsInfoType, *newconst, fieldID++, fldID); - } + // @poffset: + mirBuilder.AddIntFieldConst(fieldsInfoType, *newconst, fieldID++, idx); // @modifier FieldAttrs fa = fieldP.second.second; mirBuilder.AddIntFieldConst(fieldsInfoType, *newconst, fieldID++, GetFieldModifier(fa)); @@ -875,6 +901,7 @@ MIRSymbol *ReflectionAnalysis::GenFieldsMetaData(const Klass &klass) { // @flag uint16 hash = GetFieldHash(fieldHashvec, fieldP); uint16 flag = (hash << kNoHashBits); // Hash 10 bit. + flag |= kFieldReadOnly; mirBuilder.AddIntFieldConst(fieldsInfoType, *newconst, fieldID++, flag); // @index mirBuilder.AddIntFieldConst(fieldsInfoType, *newconst, fieldID++, idx); @@ -1573,6 +1600,11 @@ void ReflectionAnalysis::GenMetadataType(MIRModule &mirModule) { MIRStructType superclassMetadataType(kTypeStruct); GlobalTables::GetTypeTable().AddFieldToStructType(superclassMetadataType, kSuperclassinfoStr, *typeVoidPtr); superclassMetadataTyIdx = GenMetaStructType(mirModule, superclassMetadataType, kSuperclassMetadataTypeName); + // FieldOffsetDataType. + MIRStructType fieldOffsetDataType(kTypeStruct); + GlobalTables::GetTypeTable().AddFieldToStructType(fieldOffsetDataType, kFieldOffsetDataStr, *typeVoidPtr); + fieldOffsetDataTyIdx = GenMetaStructType(mirModule, fieldOffsetDataType, kFieldOffsetDataTypeName); + } void ReflectionAnalysis::GenClassHashMetaData() {