• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "class_init.h"
17 #include <iostream>
18 #include <fstream>
19 
20 namespace {
21 constexpr char kINFOFilename[] = "INFO_filename";
22 constexpr char kCoreAll[] = "core-all";
23 constexpr char kMCCPreClinitCheck[] = "MCC_PreClinitCheck";
24 constexpr char kMCCPostClinitCheck[] = "MCC_PostClinitCheck";
25 }  // namespace
26 
27 // This phase does two things.
28 // 1. Insert clinit(class initialization) check, a intrinsic call INTRN_MPL_CLINIT_CHECK
29 //   for place where needed.
30 //   Insert clinit check for static native methods which are not private.
31 namespace maple {
CanRemoveClinitCheck(const std::string & clinitClassname) const32 bool ClassInit::CanRemoveClinitCheck(const std::string &clinitClassname) const
33 {
34     if (!Options::usePreloadedClass) {
35         return false;
36     }
37     if (clinitClassname.empty()) {
38         return false;
39     }
40     uint32 dexNameIdx =
41         GetMIRModule().GetFileinfo(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(kINFOFilename));
42     const std::string &dexName = GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(dexNameIdx));
43     if (dexName.find(kCoreAll) != std::string::npos) {
44         return false;
45     }
46     return IsSystemPreloadedClass(clinitClassname);
47 }
48 
GenClassInitCheckProfile(MIRFunction & func,const MIRSymbol & classInfo,StmtNode * clinit) const49 void ClassInit::GenClassInitCheckProfile(MIRFunction &func, const MIRSymbol &classInfo, StmtNode *clinit) const
50 {
51     GenPreClassInitCheck(func, classInfo, clinit);
52     GenPostClassInitCheck(func, classInfo, clinit);
53 }
54 
GenPreClassInitCheck(MIRFunction & func,const MIRSymbol & classInfo,const StmtNode * clinit) const55 void ClassInit::GenPreClassInitCheck(MIRFunction &func, const MIRSymbol &classInfo, const StmtNode *clinit) const
56 {
57     MIRFunction *preClinit = builder->GetOrCreateFunction(kMCCPreClinitCheck, (TyIdx)(PTY_void));
58     BaseNode *classInfoNode = builder->CreateExprAddrof(0, classInfo);
59     MapleVector<BaseNode *> args(builder->GetCurrentFuncCodeMpAllocator()->Adapter());
60     args.push_back(classInfoNode);
61     CallNode *callPreclinit = builder->CreateStmtCall(preClinit->GetPuidx(), args);
62     func.GetBody()->InsertBefore(clinit, callPreclinit);
63 }
64 
GenPostClassInitCheck(MIRFunction & func,const MIRSymbol & classInfo,const StmtNode * clinit) const65 void ClassInit::GenPostClassInitCheck(MIRFunction &func, const MIRSymbol &classInfo, const StmtNode *clinit) const
66 {
67     MIRFunction *postClinit = builder->GetOrCreateFunction(kMCCPostClinitCheck, (TyIdx)(PTY_void));
68     BaseNode *classInfoNode = builder->CreateExprAddrof(0, classInfo);
69     MapleVector<BaseNode *> args(builder->GetCurrentFuncCodeMpAllocator()->Adapter());
70     args.push_back(classInfoNode);
71     CallNode *callPostClinit = builder->CreateStmtCall(postClinit->GetPuidx(), args);
72     func.GetBody()->InsertAfter(clinit, callPostClinit);
73 }
74 
GetClassInfo(const std::string & classname)75 MIRSymbol *ClassInit::GetClassInfo(const std::string &classname)
76 {
77     const std::string &classInfoName = CLASSINFO_PREFIX_STR + classname;
78     MIRType *classInfoType =
79         GlobalTables::GetTypeTable().GetOrCreateClassType(namemangler::kClassMetadataTypeName, GetMIRModule());
80     MIRSymbol *classInfo = builder->GetOrCreateGlobalDecl(classInfoName, *classInfoType);
81     Klass *klass = klassHierarchy->GetKlassFromName(classname);
82     if (klass == nullptr || !klass->GetMIRStructType()->IsLocal()) {
83         classInfo->SetStorageClass(kScExtern);
84     }
85     return classInfo;
86 }
87 
88 }  // namespace maple
89