diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 7295227c10025196f1ce54907474a2b783c0bfc1..9c12512cf7599ef2e2f09ad27d4714f0b829703e 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 619378d0a46dd04eb3f0b99446b25b0b85d528f9..6f71799a236f2781765114290f9c8b3d793e6be6 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/bin/mplcg b/src/bin/mplcg index 7dabae693b3a4cec2a31d1e4b0c897a5c1237d27..05b2f8d19e5287949009988912240dc3147512f8 100755 Binary files a/src/bin/mplcg and b/src/bin/mplcg differ diff --git a/src/maple_ir/include/intrinsics.def b/src/maple_ir/include/intrinsics.def index 50d370087b0466c9ea52cc24803d3722b0b47dd8..9ea6e762baff687c7026fa51d25fa024973b3d08 100644 --- a/src/maple_ir/include/intrinsics.def +++ b/src/maple_ir/include/intrinsics.def @@ -117,6 +117,9 @@ DEF_MIR_INTRINSIC(MPL_SET_CLASS,\ DEF_MIR_INTRINSIC(MPL_CLEANUP_NORETESCOBJS,\ "__mpl_cleanup_noretescobjs", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef,\ kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) + +// start of GC Intrinsics + #include "intrinsic_java.def" DEF_MIR_INTRINSIC(LAST,\ nullptr, kIntrnUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/src/maple_ir/include/metadata_layout.h b/src/maple_ir/include/metadata_layout.h index 50d776f319778c2ee118166121d5ad2282707901..6d2f2c6551ba90fbb57897170973639f2f40d47c 100644 --- a/src/maple_ir/include/metadata_layout.h +++ b/src/maple_ir/include/metadata_layout.h @@ -60,32 +60,34 @@ static inline void EncodeValueAsRelOffset64(const void *value, int64_t *addr) { } } +// DataRefOffset aims to represent a reference to data in maple file, which is already an offset. +// DataRefOffset is meant to have pointer size and aligned to at least 4 bytes. struct DataRefOffset32 { int32_t refOffset; inline void SetDataRef(void *ref); inline void *GetDataRef() const; }; -// DataRefOffset is meant to have pointer size. struct DataRefOffset { intptr_t refOffset; inline void SetDataRef(void *ref); inline void *GetDataRef() const; }; -/* DataRef aims for reference to data generated by maple compiler. - DataRef field allows 4 formats of value: +/* DataRef aims for reference to data in maple file (generated by maple compiler) and is aligned to at least 4 bytes. + Perhaps MDataRef is more fit, still DataRef is chosen to make it common. + DataRef allows 4 formats of value: 0. "label_name" for direct reference - 1. "label_name - . + 2" for historical compact metadata reference - 2. "label_name - . + 1" for reference in offset format + 1. "label_name - . + 1" for historical compact metadata reference + 2. "label_name - . + 2" for reference in offset format 3. "indirect.label_name - . + 3" for indirect reference this format aims to support lld which does not support expression "global_symbol - ." - DataRef is self-decoded by also encoding the format and is declared for binary compatibility. - If no compatibility problem is involved, is preferred. + DataRef is self-decoded by also encoding the format and is defined for binary compatibility. + If no compatibility problem is involved, DataRefOffset is preferred. */ enum DataRefFormat { - kDataRefIsDirect = 0, + kDataRefIsDirect = 0, // must be 0 kDataRefIsCompact = 1, // read-only kDataRefIsOffset = 2, kDataRefIsIndirect = 3, // read-only @@ -99,13 +101,53 @@ struct DataRef32 { inline void SetDataRef(void *ref, DataRefFormat format = kDataRefIsDirect); }; -// DataRef is meant to have pointer size. struct DataRef { void *refVal; inline void *GetDataRef() const; inline void SetDataRef(void *ref, DataRefFormat format = kDataRefIsDirect); }; +// MByteRef is meant to represent a reference to data defined in maple file. It is a direct reference or an offset. +// MByteRef is self-encoded/decoded and aligned to 1 byte. +// Unlike DataRef, the format of MByteRef is determined by its value. +struct MByteRef { + void* refVal; // initializer prefers this field to be a pointer + enum { + kBiasBitPosition = sizeof(refVal) * 8 - 4, // the most significant 3 bits + }; + + static constexpr uintptr_t FarthestOffset = 256*1024*1024; // according to kDsoLoadedAddessEnd = 0xF0000000 + + static constexpr uintptr_t PositiveOffsetBias = static_cast(6) << kBiasBitPosition; + static constexpr uintptr_t PositiveOffsetMin = 0 + PositiveOffsetBias; + static constexpr uintptr_t PositiveOffsetMax = FarthestOffset + PositiveOffsetBias; + + inline void *GetRef() const; + inline void SetRef(void *ref); + inline bool IsOffset() const; +}; + +struct MByteRef32 { + uint32_t refVal; + static constexpr uint32_t FarthestOffset = 256*1024*1024; // according to kDsoLoadedAddessEnd = 0xF0000000 + + static constexpr uint32_t PositiveOffsetBias = 0x60000000; // the most significant 4 bits 0110 + static constexpr uint32_t PositiveOffsetMin = 0 + PositiveOffsetBias; + static constexpr uint32_t PositiveOffsetMax = FarthestOffset + PositiveOffsetBias; + + static constexpr uint32_t DirectRefMin = 0xC0000000; // according to kDsoLoadedAddessStart = 0xC0000000 + static constexpr uint32_t DirectRefMax = 0xF0000000; // according to kDsoLoadedAddessEnd = 0xF0000000 + + static constexpr int32_t NegativeOffsetMin = - FarthestOffset; + static constexpr int32_t NegativeOffsetMax = 0; + + inline void *GetRef() const; + inline void SetRef(void *ref); + inline bool IsOffset() const; + inline bool IsPositiveOffset() const; + inline bool IsNegativeOffset() const; +}; + // MethodMeta defined in MethodMeta.h // FieldMeta defined in FieldMeta.h @@ -124,7 +166,7 @@ struct MethodDesc { // Note: class init in maplebe and cg is highly dependent on this type. // update aarch64rtsupport.h if you modify this definition. struct ClassMetadataRO { - char *className; + MByteRef className; int64_t fields; // point to info of fields int64_t methods; // point to info of methods union { // Element classinfo of array, others parent classinfo diff --git a/src/maple_ir/include/mir_parser.h b/src/maple_ir/include/mir_parser.h index 6fd6a2b649832d4b26ac82d145ff85cd88640597..336f97d67d30a09a6e4dcc772d9cf29728da4eb6 100644 --- a/src/maple_ir/include/mir_parser.h +++ b/src/maple_ir/include/mir_parser.h @@ -56,7 +56,7 @@ class MIRParser { MIRIntrinsicID GetIntrinsicID(TokenKind tk) const; bool ParseScalarValue(MIRConstPtr&, MIRType&); bool ParseConstAddrLeafExpr(MIRConstPtr&, MIRType&); - bool ParseInitValue(MIRConstPtr&, TyIdx); + bool ParseInitValue(MIRConstPtr&, TyIdx, bool allowEmpty = false); bool ParseDeclaredSt(StIdx&); bool ParseDeclaredFunc(PUIdx&); bool ParseTypeAttrs(TypeAttrs&); diff --git a/src/maple_ir/src/parser.cpp b/src/maple_ir/src/parser.cpp index 6625e5258fa1de31a2e7a5b77cdae256333a2709..1ec6b4f50bfec911cc4533dac6413d368e72d495 100644 --- a/src/maple_ir/src/parser.cpp +++ b/src/maple_ir/src/parser.cpp @@ -714,7 +714,7 @@ bool MIRParser::ParseFields(MIRStructType &type) { tk = lexer.NextToken(); MIRConst *mirConst = nullptr; if (!ParseInitValue(mirConst, fieldTyIdx)) { - Error("wrong initialiaton value at "); + Error("wrong initialization value at "); return false; } GlobalTables::GetConstPool().InsertConstPool(p.first, mirConst); @@ -1674,7 +1674,8 @@ bool MIRParser::ParseDeclareVar(MIRSymbol &symbol) { return false; } } - GStrIdx symbolStrID = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()); + std::string symbolStrName = lexer.GetName(); + GStrIdx symbolStrID = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(symbolStrName); symbol.SetNameStrIdx(symbolStrID); tk = lexer.NextToken(); if (ParseStorageClass(symbol)) { @@ -1721,8 +1722,14 @@ bool MIRParser::ParseDeclareVar(MIRSymbol &symbol) { // parse initialized values MIRConst *mirConst = nullptr; lexer.NextToken(); - if (!ParseInitValue(mirConst, tyIdx)) { - Error("wrong initialiaton value at "); + bool allowEmpty = false; + // allow empty initialization for vtable, itable, vtableOffsetTable and fieldOffsetTable + if (symbolStrName.find(VTAB_PREFIX_STR) == 0 || symbolStrName.find(NameMangler::kVtabOffsetTabStr) == 0 || + symbolStrName.find(ITAB_PREFIX_STR) == 0 || symbolStrName.find(NameMangler::kFieldOffsetTabStr) == 0) { + allowEmpty = true; + } + if (!ParseInitValue(mirConst, tyIdx, allowEmpty)) { + Error("wrong initialization value at "); return false; } symbol.SetKonst(mirConst); @@ -1953,7 +1960,7 @@ bool MIRParser::ParseFunction(uint32 fileIdx) { return true; } -bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx) { +bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmpty) { TokenKind tokenKind = lexer.GetTokenKind(); MIRType &type = *GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); if (tokenKind != kTkLbrack) { // scalar @@ -1982,8 +1989,13 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx) { theConst = newConst; tokenKind = lexer.NextToken(); if (tokenKind == kTkRbrack) { - Error("illegal empty initialization for array at "); - return false; + if (allowEmpty) { + lexer.NextToken(); + return true; + } else { + Error("illegal empty initialization for array at "); + return false; + } } do { // parse single const or another dimension array diff --git a/src/maple_me/include/irmap.h b/src/maple_me/include/irmap.h index b54cf122470b633b5145996520a24958d11d2e67..49da7f158c75cc8b2ca08f757b7e5269a90904b9 100644 --- a/src/maple_me/include/irmap.h +++ b/src/maple_me/include/irmap.h @@ -51,6 +51,7 @@ class IRMap : public AnalysisResult { void BuildBB(BB &bb, std::vector &bbIRMapProcessed); MeExpr *BuildExpr(BaseNode&); IvarMeExpr *BuildLHSIvarFromIassMeStmt(IassignMeStmt &iassignMeStmt); + IvarMeExpr *BuildLHSIvar(MeExpr &baseAddr, IassignMeStmt &iassignMeStmt, FieldID fieldID); RegMeExpr *CreateRegRefMeExpr(MeExpr&); RegMeExpr *CreateRegRefMeExpr(MIRType&); VarMeExpr *CreateVarMeExprVersion(const VarMeExpr&); @@ -197,7 +198,6 @@ class IRMap : public AnalysisResult { MeStmt *BuildMeStmtWithNoSSAPart(StmtNode &stmt); MeStmt *BuildMeStmt(StmtNode&); MeExpr *BuildLHSReg(const VersionSt &vst, RegassignMeStmt &defMeStmt, const RegassignNode ®assign); - IvarMeExpr *BuildLHSIvar(MeExpr &baseAddr, IassignMeStmt &iassignMeStmt, FieldID fieldID); RegMeExpr *CreateRefRegMeExpr(const MIRSymbol&); MeExpr *CreateMeExprCompare(Opcode, PrimType, PrimType, MeExpr&, MeExpr&); MeExpr *CreateAddrofMeExprFromNewSymbol(MIRSymbol&, PUIdx); diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index 90dc970406f80ce4bac5e8a73d5088724e4b78f2..f2d83500db52eeea5da157fe7d795a6c81268a16 100644 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -1260,7 +1260,7 @@ uint32 ReflectionAnalysis::GetAnnoCstrIndex(std::map &idxNumMap, const size_t annoNum = idxNumMap.size(); uint32 signatureIdx = 0; if (annoNum == 0) { - std::string subStr = "0!0"; + std::string subStr = "1!0"; signatureIdx = FindOrInsertReflectString(subStr); } else { std::string subStr = std::to_string(annoNum);