diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 645946380534ef3a3be7e099bf1858066df552a5..149d26fd005fe5b32434f5e7c80a9ac2203337b2 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index ffcac8b010aeef129a5a80f81c0ff629b8318ebd..271525d7734c3c5d2a7a729109740e199928f9ad 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/deplibs/libmplphase.a b/src/deplibs/libmplphase.a index 3fc9d67f5773208fe21a545d469fc67aaa2d11eb..5b221deccacc159835074b6aceb35262063a7186 100644 Binary files a/src/deplibs/libmplphase.a and b/src/deplibs/libmplphase.a differ diff --git a/src/deplibs/libmplutil.a b/src/deplibs/libmplutil.a index 290717c1fa09514939724c735844a3b9ab509677..859285c74cf1ec3b363b973a26b24f203d42565f 100644 Binary files a/src/deplibs/libmplutil.a and b/src/deplibs/libmplutil.a differ diff --git a/src/maple_ir/include/intrinsics.def b/src/maple_ir/include/intrinsics.def index 5bb44c353218a73019335e5bdd3aab30aafe7d8c..80e95079597c165a6b4173509cc6be615ba8f122 100644 --- a/src/maple_ir/include/intrinsics.def +++ b/src/maple_ir/include/intrinsics.def @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. @@ -18,7 +18,7 @@ DEF_MIR_INTRINSIC(UNDEFINED,\ DEF_MIR_INTRINSIC(MPL_ATOMIC_EXCHANGE_PTR,\ "__mpl_atomic_exchange_ptr", kIntrnIsAtomic, kArgTyPtr, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLINIT_CHECK,\ - "__mpl_clinit_check", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) + "__mpl_clinit_check", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyVoid, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLEAR_STACK,\ "__mpl_clear_stack", kIntrnUndef, kArgTyVoid, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_GET_VTAB_FUNC,\ @@ -53,6 +53,8 @@ DEF_MIR_INTRINSIC(MCCSetObjectPermanent,\ "MCC_SetObjectPermanent", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef) // start of RC Intrinsics with two parameters +DEF_MIR_INTRINSIC(MCCCheckArrayStore,\ + "MCC_Reflect_Check_Arraystore", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MCCIncDecRef,\ "MCC_IncDecRef_NaiveRCFast", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MCCIncDecRefReset,\ @@ -109,19 +111,20 @@ DEF_MIR_INTRINSIC(MCCWriteWeak,\ "MCC_WriteWeakField", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_CLEANUP_LOCALREFVARS,\ - "__mpl_cleanup_localrefvars", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) + "__mpl_cleanup_localrefvars", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_CLEANUP_LOCALREFVARS_SKIP,\ - "__mpl_cleanup_localrefvars_skip", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) + "__mpl_cleanup_localrefvars_skip", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_MEMSET_LOCALVAR,\ "", kIntrnUndef, kArgTyPtr, kArgTyU32, kArgTyU8, kArgTyU32, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_SET_CLASS,\ "", kIntrnUndef, kArgTyPtr, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLEANUP_NORETESCOBJS,\ - "__mpl_cleanup_noretescobjs", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef,\ + "__mpl_cleanup_noretescobjs", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef,\ kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) // start of GC Intrinsics #include "intrinsic_java.def" +#include "simplifyintrinsics.def" DEF_MIR_INTRINSIC(LAST,\ nullptr, kIntrnUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/src/maple_ir/include/intrinsics.h b/src/maple_ir/include/intrinsics.h index d9c3ae5ceac66b6ba3a5a28f74ae1d9f3b2ac1ff..780e4d4a9352482be30f9888109fe789c50c3a21 100644 --- a/src/maple_ir/include/intrinsics.h +++ b/src/maple_ir/include/intrinsics.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. @@ -32,7 +32,8 @@ enum IntrinProperty { kIntrnIsPure, kIntrnNeverReturn, kIntrnIsAtomic, - kIntrnIsRC + kIntrnIsRC, + kIntrnIsSpecial }; enum IntrinArgType { @@ -85,6 +86,7 @@ constexpr uint32 INTRNISPURE = 1U << kIntrnIsPure; constexpr uint32 INTRNNEVERRETURN = 1U << kIntrnNeverReturn; constexpr uint32 INTRNATOMIC = 1U << kIntrnIsAtomic; constexpr uint32 INTRNISRC = 1U << kIntrnIsRC; +constexpr uint32 INTRNISSPECIAL = 1U << kIntrnIsSpecial; class MIRType; // circular dependency exists, no other choice class MIRModule; // circular dependency exists, no other choice struct IntrinDesc { @@ -136,6 +138,10 @@ struct IntrinDesc { return properties & INTRNISRC; } + bool IsSpecial() const { + return properties & INTRNISSPECIAL; + } + bool HasNoSideEffect() const { return properties & INTRNNOSIDEEFFECT; } diff --git a/src/maple_ir/include/option.h b/src/maple_ir/include/option.h index 102d7e4f438ca451e259b32a72ee2bf736124571..cd3c1de0f56d527869d7bb9ab43bdcfaa2829675 100644 --- a/src/maple_ir/include/option.h +++ b/src/maple_ir/include/option.h @@ -82,6 +82,7 @@ class Options { #if MIR_JAVA static bool skipVirtualMethod; #endif + static bool checkArrayStore; private: MapleAllocator optionAlloc; std::vector phaseSeq; diff --git a/src/maple_ir/include/simplifyintrinsics.def b/src/maple_ir/include/simplifyintrinsics.def new file mode 100644 index 0000000000000000000000000000000000000000..30c04a7c4576da4d1562a9e3f4ff346b3b3ad804 --- /dev/null +++ b/src/maple_ir/include/simplifyintrinsics.def @@ -0,0 +1,31 @@ +/* + * Copyright (c) [2019-2020] 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. + */ + +/* INTRINSIC(STR, NAME) */ +DEF_MIR_INTRINSIC(GET_AND_ADDI, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddInt_7C_28Ljava_2Flang_2FObject_3BJI_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32) +DEF_MIR_INTRINSIC(GET_AND_ADDL, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI64, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(GET_AND_SETI, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetInt_7C_28Ljava_2Flang_2FObject_3BJI_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32) +DEF_MIR_INTRINSIC(GET_AND_SETL, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI64, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(COMP_AND_SWAPI, "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapInt_7C_28Ljava_2Flang_2FObject_3BJII_29Z",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyU1, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32, kArgTyI32) +DEF_MIR_INTRINSIC(COMP_AND_SWAPL, "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapLong_7C_28Ljava_2Flang_2FObject_3BJJJ_29Z",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyU1, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(STR_INDEXOF, "Ljava_2Flang_2FString_3B_7CindexOf_7C_28Ljava_2Flang_2FString_3B_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef) + diff --git a/src/maple_ir/src/mir_nodes.cpp b/src/maple_ir/src/mir_nodes.cpp index c8097141b9b99cc69413926dbd9f000e8e83726f..bdba14e39f5b984df042f101c25f68ad65c28274 100644 --- a/src/maple_ir/src/mir_nodes.cpp +++ b/src/maple_ir/src/mir_nodes.cpp @@ -20,6 +20,7 @@ #include "maple_string.h" #include "opcode_info.h" #include "name_mangler.h" +#include "utils.h" namespace maple { MIRModule *theMIRModule = nullptr; @@ -1236,8 +1237,8 @@ enum PTYGroup { kPTYGOthers }; -uint8 GetCompGroupID(const BaseNode &opnd) { - switch (opnd.GetPrimType()) { +uint8 GetPTYGroup(PrimType primType) { + switch (primType) { case PTY_i32: case PTY_u32: case PTY_a32: @@ -1271,6 +1272,10 @@ uint8 GetCompGroupID(const BaseNode &opnd) { } } +uint8 GetCompGroupID(const BaseNode &opnd) { + return GetPTYGroup(opnd.GetPrimType()); +} + /* Refer to C11 Language Specification. $ 6.3.1.8 Usual arithmetic conversions @@ -1474,6 +1479,7 @@ bool TypeCvtNode::Verify() const { return opndTypeVerf && opndSizeVerf && opndExprVerf; } + bool IreadNode::Verify() const { bool addrExprVerf = Opnd(0)->Verify(); bool pTypeVerf = ReadTypeVerify(*this); diff --git a/src/maple_ir/src/option.cpp b/src/maple_ir/src/option.cpp index e6eeda9c9388eabf6825852c186d6b42aae663b1..813d18839e115e161e2b3669159de42f24352c0d 100644 --- a/src/maple_ir/src/option.cpp +++ b/src/maple_ir/src/option.cpp @@ -55,6 +55,7 @@ bool Options::emitVtableImpl = false; #if MIR_JAVA bool Options::skipVirtualMethod = false; #endif +bool Options::checkArrayStore = false; enum OptionIndex { kUnknown, kHelp, @@ -89,6 +90,7 @@ enum OptionIndex { kMapleLinker, kMplnkDumpMuid, kEmitVtableImpl, + kCheckArrayStore, }; const Descriptor kUsage[] = { @@ -163,6 +165,8 @@ const Descriptor kUsage[] = { #if MIR_JAVA { kSkipVirtual, 0, "", "skipvirtual", kBuildTypeAll, kArgCheckPolicyNone, " --skipvirtual" }, #endif + { kCheckArrayStore, 0, "", "check-array-store", kBuildTypeAll, kArgCheckPolicyNone, + " --check-array-store Check array store[default off]" }, { 0, 0, nullptr, nullptr, kBuildTypeAll, kArgCheckPolicyNone, nullptr } }; @@ -278,6 +282,9 @@ bool Options::ParseOptions(int argc, char **argv, std::string &fileName) const { Options::skipVirtualMethod = true; break; #endif + case kCheckArrayStore: + Options::checkArrayStore = true; + break; default: result = false; ASSERT(false, "unhandled case in Options"); diff --git a/src/maple_me/include/me_inequality_graph.h b/src/maple_me/include/me_inequality_graph.h index 6a4903a154ff8a166011d4fd002400935d1efb8c..f76b97b7dc62f9a5e999220599e5dcbed3db0a50 100644 --- a/src/maple_me/include/me_inequality_graph.h +++ b/src/maple_me/include/me_inequality_graph.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. diff --git a/src/maple_me/include/me_rc_lowering.h b/src/maple_me/include/me_rc_lowering.h index 6a58eae885f524576b3912362bc4a1939c1119d1..58d996fa5e8b666de0f096b5d9e09c0a411f9631 100644 --- a/src/maple_me/include/me_rc_lowering.h +++ b/src/maple_me/include/me_rc_lowering.h @@ -89,6 +89,8 @@ class RCLowering { void HandleReturnStmt(); void HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec); MIRIntrinsicID SelectWriteBarrier(const MeStmt &stmt); + MIRType *GetArrayNodeType(VarMeExpr &var); + void CheckArrayStore(IntrinsiccallMeStmt &writeRefCall); MeFunction &func; MIRModule &mirModule; IRMap &irMap; diff --git a/src/maple_me/src/me_inequality_graph.cpp b/src/maple_me/src/me_inequality_graph.cpp index 5eea6597c15a86cbb64748a2ea75f1dff9b73995..506d9ec9b8d194edab173cad1f0d821f7544aae0 100644 --- a/src/maple_me/src/me_inequality_graph.cpp +++ b/src/maple_me/src/me_inequality_graph.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. diff --git a/src/maple_me/src/me_rc_lowering.cpp b/src/maple_me/src/me_rc_lowering.cpp index d5467bab225bf3c72b68b75159bfd6aebc41eab1..8abc62b3dd1c3a3b8bbfe395e21c25266245515d 100644 --- a/src/maple_me/src/me_rc_lowering.cpp +++ b/src/maple_me/src/me_rc_lowering.cpp @@ -342,6 +342,66 @@ void RCLowering::HandleAssignMeStmtVarLHS(MeStmt &stmt, MeExpr *pendingDec) { assignedPtrSym.insert(lsym); } +MIRType *RCLowering::GetArrayNodeType(VarMeExpr &var) { + const MIRSymbol *arrayElemSym = ssaTab.GetMIRSymbolFromID(var.GetOStIdx()); + MIRType *baseType = arrayElemSym->GetType(); + MIRType *arrayElemType = nullptr; + if (baseType != nullptr) { + MIRType *stType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(baseType)->GetPointedTyIdx()); + while (kTypeJArray == stType->GetKind()) { + MIRJarrayType *baseType1 = static_cast(stType); + MIRType *elemType = baseType1->GetElemType(); + if (elemType->GetKind() == kTypePointer) { + const TyIdx &index = static_cast(elemType)->GetPointedTyIdx(); + stType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(index); + } else { + stType = elemType; + } + } + arrayElemType = stType; + } + return arrayElemType; +} + +void RCLowering::CheckArrayStore(IntrinsiccallMeStmt &writeRefCall) { + if (!Options::checkArrayStore) { + return; + } + MIRIntrinsicID intrnID = writeRefCall.GetIntrinsic(); + if (!((INTRN_MCCWriteVolNoInc <= intrnID) && (intrnID <= INTRN_MCCWrite))) { + return; + } + if (writeRefCall.GetOpnd(1)->GetOp() != OP_iaddrof) { + return; + } + OpMeExpr *opExpr = static_cast(writeRefCall.GetOpnd(1)); + if (opExpr->GetOpnd(0)->GetOp() != OP_array) { + return; + } + MeExpr *arrayNode = writeRefCall.GetOpnd(0); + if (arrayNode->GetMeOp() != kMeOpVar) { + return; + } + VarMeExpr *arrayVar = static_cast(arrayNode); + MeExpr *valueNode = writeRefCall.GetOpnd(2); + if (valueNode->GetMeOp() != kMeOpVar) { + return; + } + MIRType *arrayElemType = GetArrayNodeType(*arrayVar); + MIRType *valueRealType = GetArrayNodeType(*(static_cast(valueNode))); + if ((arrayElemType != nullptr) && (arrayElemType->GetKind() == kTypeClass) && + static_cast(arrayElemType)->IsFinal() && + (valueRealType != nullptr) && (valueRealType->GetKind() == kTypeClass) && + static_cast(valueRealType)->IsFinal() && + (valueRealType->GetTypeIndex() == arrayElemType->GetTypeIndex())) { + return; + } + std::vector opnds = { arrayNode, valueNode }; + IntrinsiccallMeStmt *checkStmt = irMap.CreateIntrinsicCallMeStmt(INTRN_MCCCheckArrayStore, opnds); + writeRefCall.GetBB()->InsertMeStmtBefore(&writeRefCall, checkStmt); +} + void RCLowering::HandleAssignToGlobalVar(MeStmt &stmt) { MeExpr *lhs = stmt.GetLHS(); CHECK_FATAL(lhs != nullptr, "null ptr check"); @@ -353,6 +413,7 @@ void RCLowering::HandleAssignToGlobalVar(MeStmt &stmt) { std::vector opnds = { irMap.CreateAddrofMeExpr(*lhs), rhs }; IntrinsiccallMeStmt *writeRefCall = CreateRCIntrinsic(SelectWriteBarrier(stmt), stmt, opnds); bb->ReplaceMeStmt(&stmt, writeRefCall); + CheckArrayStore(*writeRefCall); } void RCLowering::HandleAssignToLocalVar(MeStmt &stmt, MeExpr *pendingDec) { @@ -436,6 +497,7 @@ void RCLowering::HandleAssignMeStmtIvarLHS(MeStmt &stmt) { { &lhsInner->GetBase()->GetAddrExprBase(), irMap.CreateAddrofMeExpr(*lhsInner), rhsInner }; IntrinsiccallMeStmt *writeRefCall = CreateRCIntrinsic(intrinsicID, stmt, opnds); stmt.GetBB()->ReplaceMeStmt(&stmt, writeRefCall); + CheckArrayStore(*writeRefCall); } void RCLowering::HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec) { @@ -654,6 +716,10 @@ void RCLowering::HandleReturnRegread(RetMeStmt &ret) { opnds->erase(iter); opnds->push_back(retVar); // pin it to end of std::vector cleanup->SetIntrinsic(INTRN_MPL_CLEANUP_LOCALREFVARS_SKIP); + MIRSymbol *sym = ssaTab.GetMIRSymbolFromID(retVar->GetOStIdx()); + if (sym->GetAttr(ATTR_localrefvar)) { + func.GetMirFunc()->InsertMIRSymbol(sym); + } break; } } diff --git a/src/maple_util/include/name_mangler.h b/src/maple_util/include/name_mangler.h index 041ed35999d00d7f8f5d5e1a9fbdbc01c9cad73f..221f90a1b04bd66718f4364d9e9ffb5498d1fab4 100644 --- a/src/maple_util/include/name_mangler.h +++ b/src/maple_util/include/name_mangler.h @@ -148,6 +148,8 @@ static constexpr const char kFunctionLayoutStr[] = "__func_layout__"; static constexpr const char kFunctionProfileTabPrefixStr[] = "__muid_profile_func_tab"; +static constexpr const char kBBProfileTabPrefixStr[] = "__bb_profile_tab"; + static constexpr const char kBindingProtectedRegionStr[] = "__BindingProtectRegion__"; static constexpr const char kClassNamePrefixStr[] = "L"; diff --git a/src/mpl2mpl/include/class_hierarchy.h b/src/mpl2mpl/include/class_hierarchy.h index f69effbb4f504cf4bf64a4dd0209d81a88e8e04b..612291a161eaef57a8ae5c17a2ded7a1d5586552 100644 --- a/src/mpl2mpl/include/class_hierarchy.h +++ b/src/mpl2mpl/include/class_hierarchy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. @@ -39,6 +39,9 @@ constexpr uint32 kClassRuntimeVerify = 0x8000; // True if need verifier in runti constexpr char kJavaLangNoMethodStr[] = "Ljava_2Flang_2FNoSuchMethodException_3B"; constexpr uint32 kClassReference = (kClassSoftreference | kClassWeakreference | kClassCleaner | kClassFinalizereference | kClassPhantomreference); + +bool IsSystemPreloadedClass(const std::string &className); + // Klass is the basic node for building class hierarchy class Klass { public: diff --git a/src/mpl2mpl/include/class_init.h b/src/mpl2mpl/include/class_init.h index f68b963233937af795d90d2db1de017fddfdb6b9..ae3bf0e4308b46fb9747b07ff9354718cd1a163f 100644 --- a/src/mpl2mpl/include/class_init.h +++ b/src/mpl2mpl/include/class_init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. @@ -21,7 +21,7 @@ namespace maple { class ClassInit : public FuncOptimizeImpl { public: - ClassInit(MIRModule *mod, KlassHierarchy *kh, bool dump); + ClassInit(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} ~ClassInit() = default; FuncOptimizeImpl *Clone() override { diff --git a/src/mpl2mpl/include/vtable_impl.h b/src/mpl2mpl/include/vtable_impl.h index afbf28acf9f47cf512bf7cfc2c9224c0decf829c..d3d63eeba90f09aeba67e7d25d951451a66fb541 100644 --- a/src/mpl2mpl/include/vtable_impl.h +++ b/src/mpl2mpl/include/vtable_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] 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. @@ -37,6 +37,7 @@ class VtableImpl : public FuncOptimizeImpl { private: void ReplaceResolveInterface(StmtNode &stmt, const ResolveFuncNode &resolveNode); + void Intrinsify(MIRFunction &func, CallNode &cnode); MIRModule *mirModule; MIRFunction *mccItabFunc; }; diff --git a/src/mpl2mpl/src/class_hierarchy.cpp b/src/mpl2mpl/src/class_hierarchy.cpp index 4272534aea1db2a2dc4af91b28b3375128831b15..40b7fafe08d3e0d6a284b013e6807bdbd3e2a4eb 100644 --- a/src/mpl2mpl/src/class_hierarchy.cpp +++ b/src/mpl2mpl/src/class_hierarchy.cpp @@ -39,6 +39,10 @@ namespace maple { bool KlassHierarchy::traceFlag = false; +bool IsSystemPreloadedClass(const std::string &className) { + return false; +} + Klass::Klass(MIRStructType *type, MapleAllocator *alc) : structType(type), alloc(alc), @@ -324,7 +328,7 @@ Klass *KlassHierarchy::GetKlassFromLiteral(const std::string &name) const { bool KlassHierarchy::IsSuperKlass(const Klass *super, const Klass *base) const { - if (super == nullptr || base == nullptr) { + if (super == nullptr || base == nullptr || base->IsInterface()) { return false; } while (base != nullptr) { diff --git a/src/mpl2mpl/src/class_init.cpp b/src/mpl2mpl/src/class_init.cpp index ff7b31e31074a5db4632210a74576dc7c9277df7..b621f7892033d57f5f60362f1ed98eff472eb027 100644 --- a/src/mpl2mpl/src/class_init.cpp +++ b/src/mpl2mpl/src/class_init.cpp @@ -19,7 +19,6 @@ namespace { constexpr char kMCCPreClinitCheck[] = "MCC_PreClinitCheck"; constexpr char kMCCPostClinitCheck[] = "MCC_PostClinitCheck"; - } // namespace // This phase does two things. @@ -28,10 +27,6 @@ constexpr char kMCCPostClinitCheck[] = "MCC_PostClinitCheck"; // Insert clinit check for static native methods which are not private. // 2. Lower JAVA_CLINIT_CHECK to MPL_CLINIT_CHECK. namespace maple { -ClassInit::ClassInit(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { -} - - bool ClassInit::CanRemoveClinitCheck(const std::string &clinitClassname) const { return false; } diff --git a/src/mpl2mpl/src/vtable_impl.cpp b/src/mpl2mpl/src/vtable_impl.cpp index 99de42f21740f26bd630a46748e941d1f5350528..7dfa1c750b257375a51603b808fa2bb375b6ce74 100644 --- a/src/mpl2mpl/src/vtable_impl.cpp +++ b/src/mpl2mpl/src/vtable_impl.cpp @@ -32,7 +32,43 @@ VtableImpl::VtableImpl(MIRModule *mod, KlassHierarchy *kh, bool dump) mccItabFunc = builder->GetOrCreateFunction(kInterfaceMethod, TyIdx(PTY_ptr)); mccItabFunc->SetAttr(FUNCATTR_nosideeffect); } - +#if TARGARM || TARGAARCH64 +void VtableImpl::Intrinsify(MIRFunction &func, CallNode &cnode) { + MIRFunction *calleeFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(cnode.GetPUIdx()); + const std::string funcName = calleeFunc->GetName(); + MIRIntrinsicID intrnId = INTRN_UNDEFINED; + if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddInt_7C_28Ljava_2Flang_2FObject_3BJI_29I") { + intrnId = INTRN_GET_AND_ADDI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J") { + intrnId = INTRN_GET_AND_ADDL; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetInt_7C_28Ljava_2Flang_2FObject_3BJI_29I") { + intrnId = INTRN_GET_AND_SETI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J") { + intrnId = INTRN_GET_AND_SETL; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapInt_7C_28Ljava_2Flang_2FObject_3BJII_29Z") { + intrnId = INTRN_COMP_AND_SWAPI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapLong_7C_28Ljava_2Flang_2FObject_3BJJJ_29Z") { + intrnId = INTRN_COMP_AND_SWAPL; + } + if (intrnId == INTRN_UNDEFINED) { + return; + } + CallReturnVector retvs = cnode.GetReturnVec(); + if (!retvs.empty()) { + StIdx stidx = retvs.begin()->first; + StmtNode *intrnCallStmt = nullptr; + if (stidx.Idx() != 0) { + MIRSymbol *retSt = currFunc->GetLocalOrGlobalSymbol(stidx); + intrnCallStmt = builder->CreateStmtIntrinsicCallAssigned(intrnId, cnode.GetNopnd(), retSt); + } else { + ASSERT (retvs.begin()->second.IsReg(), "return value must be preg"); + PregIdx pregIdx = retvs.begin()->second.GetPregIdx(); + intrnCallStmt = builder->CreateStmtIntrinsicCallAssigned(intrnId, cnode.GetNopnd(), pregIdx); + } + func.GetBody()->ReplaceStmt1WithStmt2(&cnode, intrnCallStmt); + } +} +#endif void VtableImpl::ProcessFunc(MIRFunction *func) { if (func->IsEmpty()) { return; @@ -43,6 +79,27 @@ void VtableImpl::ProcessFunc(MIRFunction *func) { while (stmt != nullptr) { next = stmt->GetNext(); Opcode opcode = stmt->GetOpCode(); +#if TARGARM || TARGAARCH64 + if (kOpcodeInfo.IsCallAssigned(opcode)) { + CallNode *cnode = static_cast(stmt); + MIRFunction *calleefunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(cnode->GetPUIdx()); + const std::set intrisicsList { +#define DEF_MIR_INTRINSIC(X, NAME, INTRN_CLASS, RETURN_TYPE, ...) NAME, +#include "simplifyintrinsics.def" +#undef DEF_MIR_INTRINSIC + }; + const std::string funcName = calleefunc->GetName(); + if (funcName == "Ljava_2Flang_2FString_3B_7CindexOf_7C_28Ljava_2Flang_2FString_3B_29I") { + stmt = next; + continue; + } + if (Options::O2 && intrisicsList.find(funcName) != intrisicsList.end()) { + Intrinsify(*func, *cnode); + stmt = next; + continue; + } + } +#endif switch (opcode) { case OP_regassign: { auto *regassign = static_cast(stmt);