已合并
语境信息表内存优化 #14937
语境信息表内存优化 #14937
已合并
王哈哈创建于 7月14日
15 个文件变更+1200-170
Mcommon_components/base/config.h+1-0
@@ -35,6 +35,7 @@ namespace common {
35 35 
36#define ECMASCRIPT_ENABLE_TRACE_STRING_TABLE 036#define ECMASCRIPT_ENABLE_TRACE_STRING_TABLE 0
37 37 
38+#define ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION 1
38} // namespace common39} // namespace common
39 40 
40#endif // COMMON_COMPONENTS_BASE_CONFIG_H41#endif // COMMON_COMPONENTS_BASE_CONFIG_H
Mecmascript/ecma_vm.cpp+211-0
@@ -1759,13 +1759,173 @@ bool EcmaVM::IsHmsModule(const CString &moduleStr) const
1759 return true;1759 return true;
1760}1760}
1761 1761 
1762+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1763+bool EcmaVM::IsNormalizedOhmUrlPack()
1764+{
1765+ if (IsFormThread()) {
1766+ ReadLockHolder lock(pkgContextInfoLock_);
1767+ return !pkgContextInfoList_.empty();
1768+ }
1769+ return Runtime::GetInstance()->GetPkgContextStore().IsNormalizedOhmUrlPack();
1770+}
1771+ 
1772+void EcmaVM::SetPkgNameList(const CMap<CString, CString> &list)
1773+{
1774+ if (IsFormThread()) {
1775+ WriteLockHolder lock(pkgNameListLock_);
1776+ pkgNameList_ = list;
1777+ return;
1778+ }
1779+ Runtime::GetInstance()->GetPkgContextStore().SetPkgNameList(list);
1780+}
1781+ 
1782+void EcmaVM::UpdatePkgNameList(const CMap<CString, CString> &list)
1783+{
1784+ if (IsFormThread()) {
1785+ WriteLockHolder lock(pkgNameListLock_);
1786+ pkgNameList_.insert(list.begin(), list.end());
1787+ return;
1788+ }
1789+ Runtime::GetInstance()->GetPkgContextStore().UpdatePkgNameList(list);
1790+}
1791+ 
1792+CMap<CString, CString> EcmaVM::GetPkgNameList()
1793+{
1794+ if (IsFormThread()) {
1795+ ReadLockHolder lock(pkgNameListLock_);
1796+ return pkgNameList_;
1797+ }
1798+ return Runtime::GetInstance()->GetPkgContextStore().GetPkgNameList();
1799+}
1800+ 
1801+CString EcmaVM::GetPkgName(const CString &moduleName)
1802+{
1803+ if (IsFormThread()) {
1804+ ReadLockHolder lock(pkgNameListLock_);
1805+ auto it = pkgNameList_.find(moduleName);
1806+ if (it == pkgNameList_.end()) {
1807+ LOG_ECMA(INFO) << " Get Pkg Name failed";
1808+ return moduleName;
1809+ }
1810+ return it->second;
1811+ }
1812+ return Runtime::GetInstance()->GetPkgContextStore().GetPkgName(moduleName);
1813+}
1814+ 
1815+void EcmaVM::UpdatePkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list)
1816+{
1817+ if (IsFormThread()) {
1818+ WriteLockHolder lock(pkgContextInfoLock_);
1819+ pkgContextInfoList_.insert(list.begin(), list.end());
1820+ return;
1821+ }
1822+ Runtime::GetInstance()->GetPkgContextStore().UpdatePkgContextInfoList(list);
1823+}
1824+ 
1825+CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> EcmaVM::GetPkgContextInfoList()
1826+{
1827+ if (IsFormThread()) {
1828+ ReadLockHolder lock(pkgContextInfoLock_);
1829+ return pkgContextInfoList_;
1830+ }
1831+ return Runtime::GetInstance()->GetPkgContextStore().GetPkgContextInfoList();
1832+}
1833+ 
1834+CString EcmaVM::GetPkgNameWithAlias(const CString &alias)
1835+{
1836+ if (IsFormThread()) {
1837+ ReadLockHolder lock(pkgAliasListLock_);
1838+ auto it = pkgAliasList_.find(alias);
1839+ if (it == pkgAliasList_.end()) {
1840+ return alias;
1841+ }
1842+ return it->second;
1843+ }
1844+ return Runtime::GetInstance()->GetPkgContextStore().GetPkgNameWithAlias(alias);
1845+}
1846+ 
1847+void EcmaVM::SetPkgAliasList(const CMap<CString, CString> &list)
1848+{
1849+ if (IsFormThread()) {
1850+ WriteLockHolder lock(pkgAliasListLock_);
1851+ pkgAliasList_ = list;
1852+ return;
1853+ }
1854+ Runtime::GetInstance()->GetPkgContextStore().SetPkgAliasList(list);
1855+}
1856+ 
1857+void EcmaVM::UpdatePkgAliasList(const CMap<CString, CString> &list)
1858+{
1859+ if (IsFormThread()) {
1860+ WriteLockHolder lock(pkgAliasListLock_);
1861+ pkgAliasList_.insert(list.begin(), list.end());
1862+ return;
1863+ }
1864+ Runtime::GetInstance()->GetPkgContextStore().UpdatePkgAliasList(list);
1865+}
1866+ 
1867+CMap<CString, CString> EcmaVM::GetPkgAliasList()
1868+{
1869+ if (IsFormThread()) {
1870+ ReadLockHolder lock(pkgAliasListLock_);
1871+ return pkgAliasList_;
1872+ }
1873+ return Runtime::GetInstance()->GetPkgContextStore().GetPkgAliasList();
1874+}
1875+ 
1876+CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> EcmaVM::GetOhExportList()
1877+{
1878+ if (IsFormThread()) {
1879+ ReadLockHolder lock(ohExportListLock_);
1880+ return ohExportsList_;
1881+ }
1882+ return Runtime::GetInstance()->GetPkgContextStore().GetOhExportList();
1883+}
1884+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1885+ 
1886+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1887+void EcmaVM::SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list)
1888+{
1889+ if (IsFormThread()) {
1890+ WriteLockHolder lock(pkgContextInfoLock_);
1891+ pkgContextInfoList_ = list;
1892+ return;
1893+ }
1894+ Runtime::GetInstance()->GetPkgContextStore().SetPkgContextInfoList(list);
1895+}
1896+#else
1762void EcmaVM::SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list)1897void EcmaVM::SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list)
1763{1898{
1764 WriteLockHolder lock(pkgContextInfoLock_);1899 WriteLockHolder lock(pkgContextInfoLock_);
1765 pkgContextInfoList_ = list;1900 pkgContextInfoList_ = list;
1766}1901}
1902+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1767 1903 
1768#if ENABLE_LATEST_OPTIMIZATION1904#if ENABLE_LATEST_OPTIMIZATION
1905+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1906+void EcmaVM::GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,
1907+ CVector<std::pair<CString, CString>> &resultList)
1908+{
1909+ if (IsFormThread()) {
1910+ ReadLockHolder lock(pkgContextInfoLock_);
1911+ if (packageName.empty()) {
1912+ return;
1913+ }
1914+ auto pkgContextIt = pkgContextInfoList_.find(moduleName);
1915+ if (pkgContextIt == pkgContextInfoList_.end()) {
1916+ return;
1917+ }
1918+ const CMap<CString, CVector<std::pair<CString, CString>>> &pkgList = pkgContextIt->second;
1919+ auto pkgIt = pkgList.find(packageName);
1920+ if (pkgIt == pkgList.end()) {
1921+ return;
1922+ }
1923+ resultList = pkgIt->second;
1924+ return;
1925+ }
1926+ Runtime::GetInstance()->GetPkgContextStore().GetPkgContextInfoListElements(moduleName, packageName, resultList);
1927+}
1928+#else
1769void EcmaVM::GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,1929void EcmaVM::GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,
1770 CVector<CString> &resultList)1930 CVector<CString> &resultList)
1771{1931{
@@ -1784,6 +1944,7 @@ void EcmaVM::GetPkgContextInfoListElements(const CString &moduleName, const CStr
1784 }1944 }
1785 resultList = pkgIt->second;1945 resultList = pkgIt->second;
1786}1946}
1947+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1787#endif1948#endif
1788 1949 
1789void EcmaVM::StopPreLoadSoOrAbc()1950void EcmaVM::StopPreLoadSoOrAbc()
@@ -1798,20 +1959,69 @@ void EcmaVM::StopPreLoadSoOrAbc()
1798 }1959 }
1799}1960}
1800 1961 
1962+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1963+void EcmaVM::SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
1964+ CUnorderedSet<CString>>> &ohExportsMap)
1965+{
1966+ if (IsFormThread()) {
1967+ WriteLockHolder lock(ohExportListLock_);
1968+ ohExportsList_ = ohExportsMap;
1969+ return;
1970+ }
1971+ Runtime::GetInstance()->GetPkgContextStore().SetOhExportsList(ohExportsMap);
1972+}
1973+#else
1801void EcmaVM::SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,1974void EcmaVM::SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
1802 CUnorderedSet<CString>>> &ohExportsMap)1975 CUnorderedSet<CString>>> &ohExportsMap)
1803{1976{
1804 WriteLockHolder lock(ohExportListLock_);1977 WriteLockHolder lock(ohExportListLock_);
1805 ohExportsList_ = ohExportsMap;1978 ohExportsList_ = ohExportsMap;
1806}1979}
1980+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1807 1981 
1982+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1983+void EcmaVM::UpdateOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
1984+ CUnorderedSet<CString>>> &ohExportsMap)
1985+{
1986+ if (IsFormThread()) {
1987+ WriteLockHolder lock(ohExportListLock_);
1988+ ohExportsList_.insert(ohExportsMap.begin(), ohExportsMap.end());
1989+ return;
1990+ }
1991+ Runtime::GetInstance()->GetPkgContextStore().UpdateOhExportsList(ohExportsMap);
1992+}
1993+#else
1808void EcmaVM::UpdateOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,1994void EcmaVM::UpdateOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
1809 CUnorderedSet<CString>>> &ohExportsMap)1995 CUnorderedSet<CString>>> &ohExportsMap)
1810{1996{
1811 WriteLockHolder lock(ohExportListLock_);1997 WriteLockHolder lock(ohExportListLock_);
1812 ohExportsList_.insert(ohExportsMap.begin(), ohExportsMap.end());1998 ohExportsList_.insert(ohExportsMap.begin(), ohExportsMap.end());
1813}1999}
2000+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1814 2001 
2002+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2003+bool EcmaVM::CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName, const CString &ohmurl)
2004+{
2005+ if (IsFormThread()) {
2006+ ReadLockHolder lock(ohExportListLock_);
2007+ if (packageName.empty()) {
2008+ return true;
2009+ }
2010+ auto moduleIt = ohExportsList_.find(moduleName);
2011+ if (moduleIt == ohExportsList_.end()) {
2012+ return true;
2013+ }
2014+ const CUnorderedMap<CString, CUnorderedSet<CString>> &moduleExportsList = moduleIt->second;
2015+ auto packageIt = moduleExportsList.find(packageName);
2016+ if (packageIt == moduleExportsList.end()) {
2017+ return true;
2018+ }
2019+ const CUnorderedSet<CString> &packageExportsList = packageIt->second;
2020+ return (packageExportsList.find(ohmurl) != packageExportsList.end());
2021+ }
2022+ return Runtime::GetInstance()->GetPkgContextStore().CheckOhExportsWithOhmurl(moduleName, packageName, ohmurl);
2023+}
2024+#else
1815bool EcmaVM::CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName, const CString &ohmurl)2025bool EcmaVM::CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName, const CString &ohmurl)
1816{2026{
1817 ReadLockHolder lock(ohExportListLock_);2027 ReadLockHolder lock(ohExportListLock_);
@@ -1830,6 +2040,7 @@ bool EcmaVM::CheckOhExportsWithOhmurl(const CString &moduleName, const CString &
1830 const CUnorderedSet<CString> &packageExportsList = packageIt->second;2040 const CUnorderedSet<CString> &packageExportsList = packageIt->second;
1831 return (packageExportsList.find(ohmurl) != packageExportsList.end());2041 return (packageExportsList.find(ohmurl) != packageExportsList.end());
1832}2042}
2043+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1833 2044 
1834// Initialize IcuData Path2045// Initialize IcuData Path
1835void EcmaVM::InitializeIcuData(const JSRuntimeOptions &options)2046void EcmaVM::InitializeIcuData(const JSRuntimeOptions &options)
Mecmascript/ecma_vm.h+48-0
@@ -740,6 +740,16 @@ public:
740 return options_.IsRestrictedWorker();740 return options_.IsRestrictedWorker();
741 }741 }
742 742 
743+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
744+ // The form (card) thread keeps thread-local pkg-context copies; others share the Runtime store.
745+ // Set once at thread creation via JSRuntimeOptions (same path as IsWorkerThread), so the
746+ // demux in every pkg-context accessor is set before any access and never changes.
747+ bool IsFormThread() const
748+ {
749+ return options_.IsFormThread();
750+ }
751+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
752+ 
743 bool IsBundlePack() const753 bool IsBundlePack() const
744 {754 {
745 return isBundlePack_;755 return isBundlePack_;
@@ -750,6 +760,26 @@ public:
750 isBundlePack_ = value;760 isBundlePack_ = value;
751 }761 }
752 762 
763+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
764+ // UnifiedOhmUrlPack means app compiles ohmurl using old format like "@bundle:",
765+ // or new unified rules like "@normalize:"
766+ // if pkgContextInfoList is empty, means use old ohmurl packing.
767+ // Demux: form VM -> per-VM local store; non-form VM -> Runtime shared store.
768+ bool IsNormalizedOhmUrlPack();
769+ 
770+ void SetPkgNameList(const CMap<CString, CString> &list);
771+ void UpdatePkgNameList(const CMap<CString, CString> &list);
772+ CMap<CString, CString> GetPkgNameList();
773+ CString GetPkgName(const CString &moduleName);
774+ 
775+ void UpdatePkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list);
776+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> GetPkgContextInfoList();
777+ CString GetPkgNameWithAlias(const CString &alias);
778+ 
779+ void SetPkgAliasList(const CMap<CString, CString> &list);
780+ void UpdatePkgAliasList(const CMap<CString, CString> &list);
781+ CMap<CString, CString> GetPkgAliasList();
782+#else
753 // UnifiedOhmUrlPack means app compiles ohmurl using old format like "@bundle:",783 // UnifiedOhmUrlPack means app compiles ohmurl using old format like "@bundle:",
754 // or new unified rules like "@normalize:"784 // or new unified rules like "@normalize:"
755 // if pkgContextInfoList is empty, means use old ohmurl packing.785 // if pkgContextInfoList is empty, means use old ohmurl packing.
@@ -827,6 +857,7 @@ public:
827 ReadLockHolder lock(pkgAliasListLock_);857 ReadLockHolder lock(pkgAliasListLock_);
828 return pkgAliasList_;858 return pkgAliasList_;
829 }859 }
860+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
830 861 
831 void SetMockModuleList(const std::map<std::string, std::string> &list)862 void SetMockModuleList(const std::map<std::string, std::string> &list)
832 {863 {
@@ -912,11 +943,20 @@ public:
912 return hmsModuleList_;943 return hmsModuleList_;
913 }944 }
914 945 
946+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
947+ void SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list);
948+#else
915 void SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list);949 void SetpkgContextInfoList(const CMap<CString, CMap<CString, CVector<CString>>> &list);
950+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
916 951 
917#if ENABLE_LATEST_OPTIMIZATION952#if ENABLE_LATEST_OPTIMIZATION
953+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
954+ void GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,
955+ CVector<std::pair<CString, CString>> &resultList);
956+#else
918 void GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,957 void GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,
919 CVector<CString> &resultList);958 CVector<CString> &resultList);
959+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
920#endif960#endif
921 961 
922 void SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap);962 void SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap);
@@ -924,11 +964,15 @@ public:
924 CUnorderedSet<CString>>> &ohExportsMap);964 CUnorderedSet<CString>>> &ohExportsMap);
925 bool CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName, const CString &ohmurl);965 bool CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName, const CString &ohmurl);
926 966 
967+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
968+ CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> GetOhExportList();
969+#else
927 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> GetOhExportList()970 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> GetOhExportList()
928 {971 {
929 ReadLockHolder lock(ohExportListLock_);972 ReadLockHolder lock(ohExportListLock_);
930 return ohExportsList_;973 return ohExportsList_;
931 }974 }
975+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
932#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)976#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
933 CpuProfiler *GetProfiler() const977 CpuProfiler *GetProfiler() const
934 {978 {
@@ -1841,7 +1885,11 @@ private:
1841 CMap<CString, CString> mockModuleList_;1885 CMap<CString, CString> mockModuleList_;
1842 std::map<CString, HmsMap> hmsModuleList_;1886 std::map<CString, HmsMap> hmsModuleList_;
1843 CMap<CString, CString> pkgNameList_;1887 CMap<CString, CString> pkgNameList_;
1888+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1889+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextInfoList_;
1890+#else
1844 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList_;1891 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList_;
1892+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1845 CMap<CString, CString> pkgAliasList_;1893 CMap<CString, CString> pkgAliasList_;
1846 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsList_;1894 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsList_;
1847 RWLock pkgContextInfoLock_;1895 RWLock pkgContextInfoLock_;
Mecmascript/js_runtime_options.h+17-0
@@ -1032,6 +1032,20 @@ public:
1032 return isRestrictedWorker_;1032 return isRestrictedWorker_;
1033 }1033 }
1034 1034 
1035+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1036+ // True for the form (card) thread: pkg-context accessors demux to thread-local storage
1037+ // instead of the process-level Runtime shared store. Set once at thread creation.
1038+ void SetIsFormThread(bool isFormThread)
1039+ {
1040+ isFormThread_ = isFormThread;
1041+ }
1042+ 
1043+ bool IsFormThread() const
1044+ {
1045+ return isFormThread_;
1046+ }
1047+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1048+ 
1035 bool EnableIC() const1049 bool EnableIC() const
1036 {1050 {
1037 return enableIC_;1051 return enableIC_;
@@ -2696,6 +2710,9 @@ private:
2696 bool enableRuntimeStat_ {false};2710 bool enableRuntimeStat_ {false};
2697 bool isWorker_ {false};2711 bool isWorker_ {false};
2698 bool isRestrictedWorker_ {false};2712 bool isRestrictedWorker_ {false};
2713+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2714+ bool isFormThread_ {false};
2715+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2699 bool traceBc_ {false};2716 bool traceBc_ {false};
2700 std::string logLevel_ {"error"};2717 std::string logLevel_ {"error"};
2701 arg_list_t logDebug_ {{"all"}};2718 arg_list_t logDebug_ {{"all"}};
Mecmascript/module/module_path_helper.cpp+105-18
@@ -242,6 +242,40 @@ CString ModulePathHelper::ThrowInvalidOhmurlError(EcmaVM *vm, const CString &old
242 oldEntryPoint);242 oldEntryPoint);
243}243}
244 244 
245+namespace {
246+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
247+CString BuildNormalizedOhmUrlFromData(const CVector<std::pair<CString, CString>> &data, const CString &pkgname,
248+ const CString &path, const CString &oldEntryPoint, size_t pathPos)
249+#else
250+CString BuildNormalizedOhmUrlFromData(const CVector<CString> &data, const CString &pkgname,
251+ const CString &path, const CString &oldEntryPoint, size_t pathPos)
252+#endif
253+{
254+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
255+ CString entryPath = ModulePathHelper::GetPkgInfoValueOrEmpty(data, ModulePathHelper::PKGINFO_ENTRY_PATH);
256+ CString version = ModulePathHelper::GetPkgInfoValueOrEmpty(data, ModulePathHelper::PKGINFO_VERSION);
257+ CString bundleName = ModulePathHelper::GetPkgInfoValueOrEmpty(data, ModulePathHelper::PKGINFO_BUNDLE_NAME);
258+#else
259+ const CString &entryPath = data[ModulePathHelper::PKGINFO_ENTRY_PATH_INDEX];
260+ const CString &version = data[ModulePathHelper::PKGINFO_VERSION_INDEX];
261+ const CString &bundleName = data[ModulePathHelper::PKGINFO_BUDNLE_NAME_INDEX];
262+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
263+ // If the subPath starts with '.test', it is a preview test, no need to splice the entry path.
264+ CString subPath = oldEntryPoint.substr(pathPos + 1);
265+ if (StringHelper::StringStartWith(subPath, ModulePathHelper::PREVIER_TEST_DIR)) {
266+ return ModulePathHelper::ConcatPreviewTestUnifiedOhmUrl(bundleName, pkgname, path, version);
267+ }
268+ // When the entry path ends with a slash (/), use the entry path to concatenate ohmurl.
269+ if (!entryPath.empty() && StringHelper::StringEndWith(entryPath, PathHelper::SLASH_TAG)) {
270+ size_t endPos = entryPath.rfind(PathHelper::SLASH_TAG);
271+ CString subEntryPath = entryPath.substr(0, endPos);
272+ return ModulePathHelper::ConcatUnifiedOhmUrl(bundleName, pkgname, subEntryPath, path, version);
273+ }
274+ // entryPath is empty.
275+ return ModulePathHelper::ConcatUnifiedOhmUrl(bundleName, pkgname, "", path, version);
276+}
277+} // namespace
278+ 
245CString ModulePathHelper::TransformToNormalizedOhmUrl(EcmaVM *vm, const CString &inputFileName,279CString ModulePathHelper::TransformToNormalizedOhmUrl(EcmaVM *vm, const CString &inputFileName,
246 const CString &baseFileName, const CString &oldEntryPoint)280 const CString &baseFileName, const CString &oldEntryPoint)
247{281{
@@ -270,31 +304,24 @@ CString ModulePathHelper::TransformToNormalizedOhmUrl(EcmaVM *vm, const CString
270 currentModuleName = moduleName;304 currentModuleName = moduleName;
271 }305 }
272#if ENABLE_LATEST_OPTIMIZATION306#if ENABLE_LATEST_OPTIMIZATION
307+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
308+ CVector<std::pair<CString, CString>> data {};
309+#else
273 CVector<CString> data {};310 CVector<CString> data {};
311+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
274 vm->GetPkgContextInfoListElements(currentModuleName, pkgname, data);312 vm->GetPkgContextInfoListElements(currentModuleName, pkgname, data);
313+#else
314+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
315+ CVector<std::pair<CString, CString>> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgname);
275#else316#else
276 CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgname);317 CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgname);
318+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
277#endif319#endif
278 if (data.empty()) {320 if (data.empty()) {
279 LOG_ECMA(WARN) << "The PkgContextInfo is empty: " << pkgname << " , currentModuleName:" << currentModuleName;321 LOG_ECMA(WARN) << "The PkgContextInfo is empty: " << pkgname << " , currentModuleName:" << currentModuleName;
280 return oldEntryPoint;322 return oldEntryPoint;
281 }323 }
282- const CString &entryPath = data[PKGINFO_ENTRY_PATH_INDEX];324+ return BuildNormalizedOhmUrlFromData(data, pkgname, path, oldEntryPoint, pathPos);
283- const CString &version = data[PKGINFO_VERSION_INDEX];
284- const CString &bundleName = data[PKGINFO_BUDNLE_NAME_INDEX];
285- // If the subPath starts with '.test', it is a preview test, no need to splice the entry path.
286- CString subPath = oldEntryPoint.substr(pathPos + 1);
287- if (StringHelper::StringStartWith(subPath, PREVIER_TEST_DIR)) {
288- return ConcatPreviewTestUnifiedOhmUrl(bundleName, pkgname, path, version);
289- }
290- // When the entry path ends with a slash (/), use the entry path to concatenate ohmurl.
291- if (!entryPath.empty() && StringHelper::StringEndWith(entryPath, PathHelper::SLASH_TAG)) {
292- size_t endPos = entryPath.rfind(PathHelper::SLASH_TAG);
293- CString subEntryPath = entryPath.substr(0, endPos);
294- return ConcatUnifiedOhmUrl(bundleName, pkgname, subEntryPath, path, version);
295- }
296- // entryPath is empty.
297- return ConcatUnifiedOhmUrl(bundleName, pkgname, "", path, version);
298}325}
299 326 
300/*327/*
@@ -842,8 +869,28 @@ CString ModulePathHelper::ParseFileNameToVMAName(const CString &filename)
842}869}
843 870 
844#if !ENABLE_LATEST_OPTIMIZATION871#if !ENABLE_LATEST_OPTIMIZATION
845-CVector<CString> ModulePathHelper::GetPkgContextInfoListElements(EcmaVM *vm, const CString &moduleName,872+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
846- const CString &packageName)873+CVector<std::pair<CString, CString>> ModulePathHelper::GetPkgContextInfoListElements(EcmaVM *vm,
874+ const CString &moduleName, const CString &packageName)
875+{
876+ CVector<std::pair<CString, CString>> resultList;
877+ if (packageName.empty()) {
878+ return resultList;
879+ }
880+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextList = vm->GetPkgContextInfoList();
881+ if (pkgContextList.find(moduleName) == pkgContextList.end()) {
882+ return resultList;
883+ }
884+ CMap<CString, CVector<std::pair<CString, CString>>> pkgList = pkgContextList[moduleName];
885+ if (pkgList.find(packageName) == pkgList.end()) {
886+ return resultList;
887+ }
888+ resultList = pkgList[packageName];
889+ return resultList;
890+}
891+#else
892+CVector<CString> ModulePathHelper::GetPkgContextInfoListElements(EcmaVM *vm,
893+ const CString &moduleName, const CString &packageName)
847{894{
848 CVector<CString> resultList;895 CVector<CString> resultList;
849 if (packageName.empty()) {896 if (packageName.empty()) {
@@ -860,6 +907,7 @@ CVector<CString> ModulePathHelper::GetPkgContextInfoListElements(EcmaVM *vm, con
860 resultList = pkgList[packageName];907 resultList = pkgList[packageName];
861 return resultList;908 return resultList;
862}909}
910+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
863#endif911#endif
864 912 
865CString ModulePathHelper::ConcatImportFileNormalizedOhmurl(const CString &recordPath, const CString &requestName,913CString ModulePathHelper::ConcatImportFileNormalizedOhmurl(const CString &recordPath, const CString &requestName,
@@ -947,10 +995,18 @@ void ModulePathHelper::ConcatOtherNormalizedOhmurl(EcmaVM *vm, const JSPandaFile
947 }995 }
948 CString pkgName = vm->GetPkgNameWithAlias(requestPath);996 CString pkgName = vm->GetPkgNameWithAlias(requestPath);
949#if ENABLE_LATEST_OPTIMIZATION997#if ENABLE_LATEST_OPTIMIZATION
998+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
999+ CVector<std::pair<CString, CString>> data {};
1000+#else
950 CVector<CString> data {};1001 CVector<CString> data {};
1002+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
951 vm->GetPkgContextInfoListElements(currentModuleName, pkgName, data);1003 vm->GetPkgContextInfoListElements(currentModuleName, pkgName, data);
1004+#else
1005+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1006+ CVector<std::pair<CString, CString>> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgName);
952#else1007#else
953 CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgName);1008 CVector<CString> data = GetPkgContextInfoListElements(vm, currentModuleName, pkgName);
1009+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
954#endif1010#endif
955 if (!data.empty()) {1011 if (!data.empty()) {
956 CString entryPath;1012 CString entryPath;
@@ -989,10 +1045,18 @@ CString ModulePathHelper::ConcatOtherNormalizedOhmurlWithFilePath(EcmaVM *vm, si
989 CString entryPath = requestPath.substr(filePathPos + 1);1045 CString entryPath = requestPath.substr(filePathPos + 1);
990 CString pkgName = vm->GetPkgNameWithAlias(alias);1046 CString pkgName = vm->GetPkgNameWithAlias(alias);
991#if ENABLE_LATEST_OPTIMIZATION1047#if ENABLE_LATEST_OPTIMIZATION
1048+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1049+ CVector<std::pair<CString, CString>> data {};
1050+#else
992 CVector<CString> data {};1051 CVector<CString> data {};
1052+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
993 vm->GetPkgContextInfoListElements(moduleName, pkgName, data);1053 vm->GetPkgContextInfoListElements(moduleName, pkgName, data);
1054+#else
1055+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1056+ CVector<std::pair<CString, CString>> data = GetPkgContextInfoListElements(vm, moduleName, pkgName);
994#else1057#else
995 CVector<CString> data = GetPkgContextInfoListElements(vm, moduleName, pkgName);1058 CVector<CString> data = GetPkgContextInfoListElements(vm, moduleName, pkgName);
1059+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
996#endif1060#endif
997 if (!data.empty()) {1061 if (!data.empty()) {
998 result = ConcatNormalizedOhmurlWithData(data, pkgName, entryPath);1062 result = ConcatNormalizedOhmurlWithData(data, pkgName, entryPath);
@@ -1000,6 +1064,28 @@ CString ModulePathHelper::ConcatOtherNormalizedOhmurlWithFilePath(EcmaVM *vm, si
1000 return result;1064 return result;
1001}1065}
1002 1066 
1067+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1068+CString ModulePathHelper::ConcatNormalizedOhmurlWithData(const CVector<std::pair<CString, CString>> &data,
1069+ const CString &pkgName, CString &entryPath)
1070+{
1071+ CString bundleName = GetPkgInfoValueOrEmpty(data, PKGINFO_BUNDLE_NAME);
1072+ CString moduleName = GetPkgInfoValueOrEmpty(data, PKGINFO_MODULE_NAME);
1073+ CString version = GetPkgInfoValueOrEmpty(data, PKGINFO_VERSION);
1074+ if (entryPath.empty()) {
1075+ entryPath = GetPkgInfoValueOrEmpty(data, PKGINFO_ENTRY_PATH);
1076+ }
1077+ CString isSO = GetPkgInfoValueOrEmpty(data, PKGINFO_IS_SO);
1078+ if (entryPath.find(PathHelper::CURRENT_DIREATORY_TAG) == 0) {
1079+ entryPath = entryPath.substr(CURRENT_DIREATORY_TAG_LEN);
1080+ }
1081+ if (isSO == TRUE_FLAG) {
1082+ return ConcatNativeSoNormalizedOhmurl(moduleName, bundleName, pkgName, version);
1083+ } else {
1084+ entryPath = RemoveSuffix(entryPath);
1085+ return ConcatNotSoNormalizedOhmurl(moduleName, bundleName, pkgName, entryPath, version);
1086+ }
1087+}
1088+#else
1003CString ModulePathHelper::ConcatNormalizedOhmurlWithData(const CVector<CString> &data, const CString &pkgName,1089CString ModulePathHelper::ConcatNormalizedOhmurlWithData(const CVector<CString> &data, const CString &pkgName,
1004 CString &entryPath)1090 CString &entryPath)
1005{1091{
@@ -1020,6 +1106,7 @@ CString ModulePathHelper::ConcatNormalizedOhmurlWithData(const CVector<CString>
1020 return ConcatNotSoNormalizedOhmurl(moduleName, bundleName, pkgName, entryPath, version);1106 return ConcatNotSoNormalizedOhmurl(moduleName, bundleName, pkgName, entryPath, version);
1021 }1107 }
1022}1108}
1109+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1023 1110 
1024CString ModulePathHelper::TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,1111CString ModulePathHelper::TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,
1025 const CString &requestName)1112 const CString &requestName)
Mecmascript/module/module_path_helper.h+32-1
@@ -126,12 +126,32 @@ public:
126 static constexpr size_t SO_PREFIX_LEN = 3;126 static constexpr size_t SO_PREFIX_LEN = 3;
127 static constexpr size_t SO_SUFFIX_LEN = 3;127 static constexpr size_t SO_SUFFIX_LEN = 3;
128 128 
129+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
130+ static constexpr std::string_view PKGINFO_PACKAGE_NAME = "packageName";
131+ static constexpr std::string_view PKGINFO_BUNDLE_NAME = "bundleName";
132+ static constexpr std::string_view PKGINFO_MODULE_NAME = "moduleName";
133+ static constexpr std::string_view PKGINFO_VERSION = "version";
134+ static constexpr std::string_view PKGINFO_ENTRY_PATH = "entryPath";
135+ static constexpr std::string_view PKGINFO_IS_SO = "isSO";
136+ 
137+ // Returns the value for key if present, otherwise empty string.
138+ static CString GetPkgInfoValueOrEmpty(const CVector<std::pair<CString, CString>> &data, std::string_view key)
139+ {
140+ for (const auto &item : data) {
141+ if (item.first == key) {
142+ return item.second;
143+ }
144+ }
145+ return CString();
146+ }
147+#else
129 static constexpr size_t PKGINFO_PACKAGE_NAME_INDEX = 1;148 static constexpr size_t PKGINFO_PACKAGE_NAME_INDEX = 1;
130 static constexpr size_t PKGINFO_BUDNLE_NAME_INDEX = 3;149 static constexpr size_t PKGINFO_BUDNLE_NAME_INDEX = 3;
131 static constexpr size_t PKGINFO_MODULE_NAME_INDEX = 5;150 static constexpr size_t PKGINFO_MODULE_NAME_INDEX = 5;
132 static constexpr size_t PKGINFO_VERSION_INDEX = 7;151 static constexpr size_t PKGINFO_VERSION_INDEX = 7;
133 static constexpr size_t PKGINFO_ENTRY_PATH_INDEX = 9;152 static constexpr size_t PKGINFO_ENTRY_PATH_INDEX = 9;
134 static constexpr size_t PKGINFO_IS_SO_INDEX = 11;153 static constexpr size_t PKGINFO_IS_SO_INDEX = 11;
154+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
135 155 
136 static CString PUBLIC_API ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,156 static CString PUBLIC_API ConcatFileNameWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
137 CString &baseFileName, const CString &recordName, const CString &requestName);157 CString &baseFileName, const CString &recordName, const CString &requestName);
@@ -183,8 +203,13 @@ public:
183 [[maybe_unused]] CString &baseFileName, const CString &recordName,203 [[maybe_unused]] CString &baseFileName, const CString &recordName,
184 CString &requestPath);204 CString &requestPath);
185#if !ENABLE_LATEST_OPTIMIZATION205#if !ENABLE_LATEST_OPTIMIZATION
206+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
207+ static CVector<std::pair<CString, CString>> GetPkgContextInfoListElements(EcmaVM *vm, const CString &moduleName,
208+ const CString &packageName);
209+#else
186 static CVector<CString> GetPkgContextInfoListElements(EcmaVM *vm, const CString &moduleName,210 static CVector<CString> GetPkgContextInfoListElements(EcmaVM *vm, const CString &moduleName,
187 const CString &packageName);211 const CString &packageName);
212+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
188#endif213#endif
189 static CString TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,214 static CString TranslateNapiFileRequestPath(JSThread *thread, const CString &modulePath,
190 const CString &requestName);215 const CString &requestName);
@@ -205,8 +230,14 @@ public:
205 const CString &requestName);230 const CString &requestName);
206 static void ConcatOtherNormalizedOhmurl(EcmaVM *vm, const JSPandaFile *jsPandaFile,231 static void ConcatOtherNormalizedOhmurl(EcmaVM *vm, const JSPandaFile *jsPandaFile,
207 [[maybe_unused]] const CString &baseFileName, CString &requestPath);232 [[maybe_unused]] const CString &baseFileName, CString &requestPath);
208- static CString ConcatNormalizedOhmurlWithData(const CVector<CString> &data, const CString &pkgName,233+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
234+ static CString ConcatNormalizedOhmurlWithData(const CVector<std::pair<CString, CString>> &data,
235+ const CString &pkgName,
209 CString &entryPath);236 CString &entryPath);
237+#else
238+ static CString ConcatNormalizedOhmurlWithData(const CVector<CString> &data, const CString &pkgName,
239+ CString &entryPath);
240+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
210 static CString GetBundleNameWithRecordName(EcmaVM *vm, const CString &recordName);241 static CString GetBundleNameWithRecordName(EcmaVM *vm, const CString &recordName);
211 static CString Utf8ConvertToString(JSThread *thread, JSTaggedValue str);242 static CString Utf8ConvertToString(JSThread *thread, JSTaggedValue str);
212 243 
Mecmascript/module/tests/ecma_module_test.cpp+145-90
@@ -1222,6 +1222,78 @@ HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge1)
1222 EXPECT_EQ(baseFilename, newBaseFileName);1222 EXPECT_EQ(baseFilename, newBaseFileName);
1223}1223}
1224 1224 
1225+static void SetupEntryHarPkgContext(EcmaVM *vm, const CString &harVersion,
1226+ const CString &harEntryPath, const CString &harIsSo)
1227+{
1228+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1229+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
1230+ CMap<CString, CVector<std::pair<CString, CString>>> entryList;
1231+ entryList["entry"] = {
1232+ {"packageName", "entry"}, {"bundleName", ""}, {"moduleName", ""},
1233+ {"version", ""}, {"entryPath", "src/main/"}, {"isSO", "false"}
1234+ };
1235+ entryList["har"] = {
1236+ {"packageName", "har"}, {"bundleName", ""}, {"moduleName", ""},
1237+ {"version", harVersion}, {"entryPath", harEntryPath}, {"isSO", harIsSo}
1238+ };
1239+#else
1240+ CMap<CString, CMap<CString, CVector<CString>>> pkgList;
1241+ CMap<CString, CVector<CString>> entryList;
1242+ entryList["entry"] = {
1243+ "packageName", "entry", "bundleName", "", "moduleName", "",
1244+ "version", "", "entryPath", "src/main/", "isSO", "false"
1245+ };
1246+ entryList["har"] = {
1247+ "packageName", "har", "bundleName", "", "moduleName", "",
1248+ "version", harVersion, "entryPath", harEntryPath, "isSO", harIsSo
1249+ };
1250+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1251+ pkgList["entry"] = entryList;
1252+ vm->SetpkgContextInfoList(pkgList);
1253+}
1254+ 
1255+static void SetupEntryHarOhosPkgContext(EcmaVM *vm)
1256+{
1257+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1258+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
1259+ CMap<CString, CVector<std::pair<CString, CString>>> entryList;
1260+ entryList["entry"] = {
1261+ {"packageName", "entry"}, {"bundleName", ""}, {"moduleName", ""},
1262+ {"version", ""}, {"entryPath", "src/main/"}, {"isSO", "false"}
1263+ };
1264+ entryList["har"] = {
1265+ {"packageName", "har"}, {"bundleName", ""}, {"moduleName", ""},
1266+ {"version", "1.2.0"}, {"entryPath", ""}, {"isSO", "false"}
1267+ };
1268+ pkgList["entry"] = entryList;
1269+ CMap<CString, CVector<std::pair<CString, CString>>> ohosTestList;
1270+ ohosTestList["ohosTest"] = {
1271+ {"packageName", "ohosTest"}, {"bundleName", ""}, {"moduleName", ""},
1272+ {"version", ""}, {"entryPath", "src/"}, {"isSO", "false"}
1273+ };
1274+ pkgList["ohosTest"] = ohosTestList;
1275+#else
1276+ CMap<CString, CMap<CString, CVector<CString>>> pkgList;
1277+ CMap<CString, CVector<CString>> entryList;
1278+ entryList["entry"] = {
1279+ "packageName", "entry", "bundleName", "", "moduleName", "",
1280+ "version", "", "entryPath", "src/main/", "isSO", "false"
1281+ };
1282+ entryList["har"] = {
1283+ "packageName", "har", "bundleName", "", "moduleName", "",
1284+ "version", "1.2.0", "entryPath", "", "isSO", "false"
1285+ };
1286+ pkgList["entry"] = entryList;
1287+ CMap<CString, CVector<CString>> ohosTestList;
1288+ ohosTestList["ohosTest"] = {
1289+ "packageName", "ohosTest", "bundleName", "", "moduleName", "",
1290+ "version", "", "entryPath", "src/", "isSO", "false"
1291+ };
1292+ pkgList["ohosTest"] = ohosTestList;
1293+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1294+ vm->SetpkgContextInfoList(pkgList);
1295+}
1296+ 
1225HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge_Normalized)1297HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge_Normalized)
1226{1298{
1227 const CString baseFilename = "merge.abc";1299 const CString baseFilename = "merge.abc";
@@ -1248,26 +1320,7 @@ HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge_Normalized)
1248 EXPECT_EQ(baseFilename1, baseFilename);1320 EXPECT_EQ(baseFilename1, baseFilename);
1249 1321 
1250 // Test cross application1322 // Test cross application
1251- CMap<CString, CMap<CString, CVector<CString>>> pkgList;1323+ SetupEntryHarPkgContext(instance, "1.2.0", "Index.ets", "false");
1252- CMap<CString, CVector<CString>> entryList;
1253- entryList["entry"] = {
1254- "packageName", "entry",
1255- "bundleName", "",
1256- "moduleName", "",
1257- "version", "",
1258- "entryPath", "src/main/",
1259- "isSO", "false"
1260- };
1261- entryList["har"] = {
1262- "packageName", "har",
1263- "bundleName", "",
1264- "moduleName", "",
1265- "version", "1.2.0",
1266- "entryPath", "Index.ets",
1267- "isSO", "false"
1268- };
1269- pkgList["entry"] = entryList;
1270- instance->SetpkgContextInfoList(pkgList);
1271 CString moduleRequestName2 = "@normalized:N&moduleName&bundleNameBB&entryPath&version";1324 CString moduleRequestName2 = "@normalized:N&moduleName&bundleNameBB&entryPath&version";
1272 CString result2 = "bundleNameBB&entryPath&version";1325 CString result2 = "bundleNameBB&entryPath&version";
1273 CString newBaseFileName2 = "/data/storage/el1/bundle/bundleNameBB/moduleName/moduleName/ets/modules.abc";1326 CString newBaseFileName2 = "/data/storage/el1/bundle/bundleNameBB/moduleName/moduleName/ets/modules.abc";
@@ -1501,6 +1554,26 @@ HWTEST_F_L0(EcmaModuleTest, ParseAbcPathAndOhmUrl)
1501 EXPECT_EQ(entryPoint, res5);1554 EXPECT_EQ(entryPoint, res5);
1502 EXPECT_EQ(outFileName, "/data/storage/el1/bundle/moduleName/ets/modules.abc");1555 EXPECT_EQ(outFileName, "/data/storage/el1/bundle/moduleName/ets/modules.abc");
1503 1556 
1557+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1558+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
1559+ CMap<CString, CVector<std::pair<CString, CString>>> entryList;
1560+ entryList["entry"] = {
1561+ {"packageName", "entry"},
1562+ {"bundleName", ""},
1563+ {"moduleName", ""},
1564+ {"version", ""},
1565+ {"entryPath", "src/main/"},
1566+ {"isSO", "false"}
1567+ };
1568+ entryList["har"] = {
1569+ {"packageName", "har"},
1570+ {"bundleName", ""},
1571+ {"moduleName", ""},
1572+ {"version", "1.2.0"},
1573+ {"entryPath", "Index.ets"},
1574+ {"isSO", "false"}
1575+ };
1576+#else
1504 CMap<CString, CMap<CString, CVector<CString>>> pkgList;1577 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
1505 CMap<CString, CVector<CString>> entryList;1578 CMap<CString, CVector<CString>> entryList;
1506 entryList["entry"] = {1579 entryList["entry"] = {
@@ -1519,6 +1592,7 @@ HWTEST_F_L0(EcmaModuleTest, ParseAbcPathAndOhmUrl)
1519 "entryPath", "Index.ets",1592 "entryPath", "Index.ets",
1520 "isSO", "false"1593 "isSO", "false"
1521 };1594 };
1595+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1522 pkgList["entry"] = entryList;1596 pkgList["entry"] = entryList;
1523 instance->SetpkgContextInfoList(pkgList);1597 instance->SetpkgContextInfoList(pkgList);
1524 1598 
@@ -1799,6 +1873,18 @@ HWTEST_F_L0(EcmaModuleTest, ConcatNotSoNormalizedOhmurl)
1799 1873 
1800HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl2)1874HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl2)
1801{1875{
1876+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1877+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
1878+ CMap<CString, CVector<std::pair<CString, CString>>> entryList;
1879+ entryList["hsp"] = {
1880+ {"packageName", "hsp"},
1881+ {"bundleName", "com.hsp.application"},
1882+ {"moduleName", ""},
1883+ {"version", ""},
1884+ {"entryPath", ""},
1885+ {"isSO", "false"}
1886+ };
1887+#else
1802 CMap<CString, CMap<CString, CVector<CString>>> pkgList;1888 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
1803 CMap<CString, CVector<CString>> entryList;1889 CMap<CString, CVector<CString>> entryList;
1804 entryList["hsp"] = {1890 entryList["hsp"] = {
@@ -1809,6 +1895,7 @@ HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl2)
1809 "entryPath", "",1895 "entryPath", "",
1810 "isSO", "false"1896 "isSO", "false"
1811 };1897 };
1898+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
1812 pkgList["entry"] = entryList;1899 pkgList["entry"] = entryList;
1813 instance->SetpkgContextInfoList(pkgList);1900 instance->SetpkgContextInfoList(pkgList);
1814 1901 
@@ -1921,26 +2008,7 @@ HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized)
1921 2008 
1922HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized2)2009HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized2)
1923{2010{
1924- CMap<CString, CMap<CString, CVector<CString>>> pkgList;2011+ SetupEntryHarPkgContext(instance, "1.2.0", "Index.ets", "false");
1925- CMap<CString, CVector<CString>> entryList;
1926- entryList["entry"] = {
1927- "packageName", "entry",
1928- "bundleName", "",
1929- "moduleName", "",
1930- "version", "",
1931- "entryPath", "src/main/",
1932- "isSO", "false"
1933- };
1934- entryList["har"] = {
1935- "packageName", "har",
1936- "bundleName", "",
1937- "moduleName", "",
1938- "version", "1.2.0",
1939- "entryPath", "Index.ets",
1940- "isSO", "false"
1941- };
1942- pkgList["entry"] = entryList;
1943- instance->SetpkgContextInfoList(pkgList);
1944 2012 
1945 CString requestPath = "har";2013 CString requestPath = "har";
1946 CString baseFileName = "/data/storage/el1/bundle/entry/ets/modules.abc";2014 CString baseFileName = "/data/storage/el1/bundle/entry/ets/modules.abc";
@@ -1989,26 +2057,7 @@ HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized3)
1989 2057 
1990HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized4)2058HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized4)
1991{2059{
1992- CMap<CString, CMap<CString, CVector<CString>>> pkgList;2060+ SetupEntryHarPkgContext(instance, "1.2.0", "./Index.ets", "true");
1993- CMap<CString, CVector<CString>> entryList;
1994- entryList["entry"] = {
1995- "packageName", "entry",
1996- "bundleName", "",
1997- "moduleName", "",
1998- "version", "",
1999- "entryPath", "src/main/",
2000- "isSO", "false"
2001- };
2002- entryList["har"] = {
2003- "packageName", "har",
2004- "bundleName", "",
2005- "moduleName", "",
2006- "version", "1.2.0",
2007- "entryPath", "./Index.ets",
2008- "isSO", "true"
2009- };
2010- pkgList["entry"] = entryList;
2011- instance->SetpkgContextInfoList(pkgList);
2012 2061 
2013 // ConcatNormalizedOhmurlWithData testcase2062 // ConcatNormalizedOhmurlWithData testcase
2014 CString requestPath = "har";2063 CString requestPath = "har";
@@ -2026,6 +2075,18 @@ HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized4)
2026 2075 
2027HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized5)2076HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized5)
2028{2077{
2078+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2079+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
2080+ CMap<CString, CVector<std::pair<CString, CString>>> entryList;
2081+ entryList["har"] = {
2082+ {"packageName", "har"},
2083+ {"bundleName", ""},
2084+ {"moduleName", ""},
2085+ {"version", "1.2.0"},
2086+ {"entryPath", "./Index.ets"},
2087+ {"isSO", "false"}
2088+ };
2089+#else
2029 CMap<CString, CMap<CString, CVector<CString>>> pkgList;2090 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
2030 CMap<CString, CVector<CString>> entryList;2091 CMap<CString, CVector<CString>> entryList;
2031 entryList["har"] = {2092 entryList["har"] = {
@@ -2036,6 +2097,7 @@ HWTEST_F_L0(EcmaModuleTest, TranslateExpressionToNormalized5)
2036 "entryPath", "./Index.ets",2097 "entryPath", "./Index.ets",
2037 "isSO", "false"2098 "isSO", "false"
2038 };2099 };
2100+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2039 pkgList["entry"] = entryList;2101 pkgList["entry"] = entryList;
2040 instance->SetpkgContextInfoList(pkgList);2102 instance->SetpkgContextInfoList(pkgList);
2041 2103 
@@ -2057,8 +2119,13 @@ HWTEST_F_L0(EcmaModuleTest, TranslateNapiFileRequestPath)
2057 CString result = ModulePathHelper::TranslateNapiFileRequestPath(thread, modulePath, requestName);2119 CString result = ModulePathHelper::TranslateNapiFileRequestPath(thread, modulePath, requestName);
2058 EXPECT_EQ(result, "modulePath/requestName");2120 EXPECT_EQ(result, "modulePath/requestName");
2059 2121 
2122+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2123+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> list;
2124+ CMap<CString, CVector<std::pair<CString, CString>>> childList;
2125+#else
2060 CMap<CString, CMap<CString, CVector<CString>>> list;2126 CMap<CString, CMap<CString, CVector<CString>>> list;
2061 CMap<CString, CVector<CString>> childList;2127 CMap<CString, CVector<CString>> childList;
2128+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
2062 list["hsp"] = childList;2129 list["hsp"] = childList;
2063 instance->SetpkgContextInfoList(list);2130 instance->SetpkgContextInfoList(list);
2064 2131 
@@ -3241,8 +3308,13 @@ HWTEST_F_L0(EcmaModuleTest, GetBundleNameWithRecordName)
3241 CString res = ModulePathHelper::GetBundleNameWithRecordName(instance, recordName);3308 CString res = ModulePathHelper::GetBundleNameWithRecordName(instance, recordName);
3242 EXPECT_EQ(res, expectRes);3309 EXPECT_EQ(res, expectRes);
3243 3310 
3311+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
3312+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> list;
3313+ CMap<CString, CVector<std::pair<CString, CString>>> childList;
3314+#else
3244 CMap<CString, CMap<CString, CVector<CString>>> list;3315 CMap<CString, CMap<CString, CVector<CString>>> list;
3245 CMap<CString, CVector<CString>> childList;3316 CMap<CString, CVector<CString>> childList;
3317+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
3246 list["hsp"] = childList;3318 list["hsp"] = childList;
3247 instance->SetpkgContextInfoList(list);3319 instance->SetpkgContextInfoList(list);
3248 3320 
@@ -3283,36 +3355,7 @@ HWTEST_F_L0(EcmaModuleTest, ModuleInstantiation_ReEnterTest)
3283 3355 
3284HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl)3356HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl)
3285{3357{
3286- CMap<CString, CMap<CString, CVector<CString>>> pkgList;3358+ SetupEntryHarOhosPkgContext(instance);
3287- CMap<CString, CVector<CString>> entryList;
3288- entryList["entry"] = {
3289- "packageName", "entry",
3290- "bundleName", "",
3291- "moduleName", "",
3292- "version", "",
3293- "entryPath", "src/main/",
3294- "isSO", "false"
3295- };
3296- entryList["har"] = {
3297- "packageName", "har",
3298- "bundleName", "",
3299- "moduleName", "",
3300- "version", "1.2.0",
3301- "entryPath", "",
3302- "isSO", "false"
3303- };
3304- pkgList["entry"] = entryList;
3305- CMap<CString, CVector<CString>> ohosTestList;
3306- ohosTestList["ohosTest"] = {
3307- "packageName", "ohosTest",
3308- "bundleName", "",
3309- "moduleName", "",
3310- "version", "",
3311- "entryPath", "src/",
3312- "isSO", "false"
3313- };
3314- pkgList["ohosTest"] = ohosTestList;
3315- instance->SetpkgContextInfoList(pkgList);
3316 3359 
3317 CString inputFileName = "/data/storage/el1/bundle/entry/ets/modules.abc";3360 CString inputFileName = "/data/storage/el1/bundle/entry/ets/modules.abc";
3318 CString outBaseFileName = "";3361 CString outBaseFileName = "";
@@ -6459,7 +6502,11 @@ HWTEST_F_L0(EcmaModuleTest, GetPkgNamesWithNormalizedOhmurl)
6459 6502 
6460HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl)6503HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl)
6461{6504{
6505+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6506+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
6507+#else
6462 CMap<CString, CMap<CString, CVector<CString>>> pkgList;6508 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
6509+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6463 pkgList["entry"] = {};6510 pkgList["entry"] = {};
6464 instance->SetpkgContextInfoList(pkgList);6511 instance->SetpkgContextInfoList(pkgList);
6465 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsList;6512 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsList;
@@ -6508,7 +6555,11 @@ HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl)
6508 6555 
6509HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl1)6556HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl1)
6510{6557{
6558+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6559+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
6560+#else
6511 CMap<CString, CMap<CString, CVector<CString>>> pkgList;6561 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
6562+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6512 pkgList["entry"] = {};6563 pkgList["entry"] = {};
6513 instance->SetpkgContextInfoList(pkgList);6564 instance->SetpkgContextInfoList(pkgList);
6514 6565 
@@ -6547,7 +6598,11 @@ HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl2)
6547 6598 
6548HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl_ImportNotNormalizedPrefix)6599HWTEST_F_L0(EcmaModuleTest, CheckExportsWithOhmurl_ImportNotNormalizedPrefix)
6549{6600{
6601+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6602+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgList;
6603+#else
6550 CMap<CString, CMap<CString, CVector<CString>>> pkgList;6604 CMap<CString, CMap<CString, CVector<CString>>> pkgList;
6605+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
6551 pkgList["entry"] = {};6606 pkgList["entry"] = {};
6552 instance->SetpkgContextInfoList(pkgList);6607 instance->SetpkgContextInfoList(pkgList);
6553 6608 
Mecmascript/napi/include/jsnapi.h+12-0
@@ -248,6 +248,16 @@ public:
248 return isRestrictedWorker_;248 return isRestrictedWorker_;
249 }249 }
250 250 
251+ void SetIsFormThread(bool isFormThread)
252+ {
253+ isFormThread_ = isFormThread;
254+ }
255+ 
256+ bool GetIsFormThread() const
257+ {
258+ return isFormThread_;
259+ }
260+ 
251 void SetBundleName(const std::string &value)261 void SetBundleName(const std::string &value)
252 {262 {
253 bundleName_ = value;263 bundleName_ = value;
@@ -474,6 +484,8 @@ private:
474 bool enableBuiltinsLazy_ {true};484 bool enableBuiltinsLazy_ {true};
475 bool isWorker_ {false};485 bool isWorker_ {false};
476 bool isRestrictedWorker_ {false};486 bool isRestrictedWorker_ {false};
487+ bool isFormThread_ {false};
488+ 
477 std::string bundleName_ {};489 std::string bundleName_ {};
478 bool enableAOT_ {false};490 bool enableAOT_ {false};
479 std::string anDir_ {};491 std::string anDir_ {};
Mecmascript/napi/jsnapi_expo.cpp+101-1
@@ -181,7 +181,6 @@ bool JSNApi::isForked_ = false;
181static ecmascript::Mutex *mutex = new panda::ecmascript::Mutex();181static ecmascript::Mutex *mutex = new panda::ecmascript::Mutex();
182StartIdleMonitorCallback JSNApi::startIdleMonitorCallback_ = nullptr;182StartIdleMonitorCallback JSNApi::startIdleMonitorCallback_ = nullptr;
183const static uint32_t API_VERSION_MASK = 100;183const static uint32_t API_VERSION_MASK = 100;
184- 
185// ----------------------------------- ArkCrashHolder --------------------------------------184// ----------------------------------- ArkCrashHolder --------------------------------------
186constexpr size_t FORMATED_FUNCPTR_LENGTH = 36; // length of dec function pointer185constexpr size_t FORMATED_FUNCPTR_LENGTH = 36; // length of dec function pointer
187 186 
@@ -4860,10 +4859,15 @@ void JSNApi::UpdatePkgAliasList(EcmaVM *vm, const std::map<std::string, std::str
4860 pkgAliasList.emplace(alias, pkgName);4859 pkgAliasList.emplace(alias, pkgName);
4861 }4860 }
4862 vm->UpdatePkgAliasList(pkgAliasList);4861 vm->UpdatePkgAliasList(pkgAliasList);
4862+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4863+ // vm demuxes by IsFormThread(): form VM -> per-VM local; non-form VM -> Runtime shared
4864+ // store, so all non-form workers see this update automatically. No manual worker sync.
4865+#else
4863 ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();4866 ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();
4864 for (auto &[workerId, workerVm]: workerList) {4867 for (auto &[workerId, workerVm]: workerList) {
4865 workerVm->UpdatePkgAliasList(pkgAliasList);4868 workerVm->UpdatePkgAliasList(pkgAliasList);
4866 }4869 }
4870+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4867}4871}
4868 4872 
4869void JSNApi::SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list)4873void JSNApi::SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list)
@@ -4882,10 +4886,15 @@ void JSNApi::UpdatePkgNameList(EcmaVM *vm, const std::map<std::string, std::stri
4882 pkgNameList.emplace(moduleName, pkgName);4886 pkgNameList.emplace(moduleName, pkgName);
4883 }4887 }
4884 vm->UpdatePkgNameList(pkgNameList);4888 vm->UpdatePkgNameList(pkgNameList);
4889+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4890+ // vm demuxes by IsFormThread(): form VM -> per-VM local; non-form VM -> Runtime shared
4891+ // store, so all non-form workers see this update automatically. No manual worker sync.
4892+#else
4885 ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();4893 ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();
4886 for (auto &[workerId, workerVm]: workerList) {4894 for (auto &[workerId, workerVm]: workerList) {
4887 workerVm->UpdatePkgNameList(pkgNameList);4895 workerVm->UpdatePkgNameList(pkgNameList);
4888 }4896 }
4897+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4889}4898}
4890 4899 
4891std::string JSNApi::GetPkgName(EcmaVM *vm, const std::string &moduleName)4900std::string JSNApi::GetPkgName(EcmaVM *vm, const std::string &moduleName)
@@ -4893,6 +4902,28 @@ std::string JSNApi::GetPkgName(EcmaVM *vm, const std::string &moduleName)
4893 return vm->GetPkgName(moduleName.c_str()).c_str();4902 return vm->GetPkgName(moduleName.c_str()).c_str();
4894}4903}
4895 4904 
4905+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4906+void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
4907+ std::vector<std::vector<std::string>>> &list)
4908+{
4909+ ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
4910+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>>> pkgContextInfoList;
4911+ for (auto it = list.begin(); it != list.end(); it++) {
4912+ const std::vector<std::vector<std::string>> vec = it->second;
4913+ ecmascript::CMap<ecmascript::CString,
4914+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>> map;
4915+ for (size_t i = 0; i < vec.size(); i++) {
4916+ if (vec[i].empty()) {
4917+ continue;
4918+ }
4919+ ecmascript::CString pkgName = vec[i][0].c_str();
4920+ map.emplace(pkgName, ecmascript::ohos::ModulePkgParser::BuildPkgContextInfo(vec[i]));
4921+ }
4922+ pkgContextInfoList.emplace(it->first.c_str(), map);
4923+ }
4924+ vm->SetpkgContextInfoList(pkgContextInfoList);
4925+}
4926+#else
4896void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,4927void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
4897 std::vector<std::vector<std::string>>> &list)4928 std::vector<std::vector<std::string>>> &list)
4898{4929{
@@ -4913,7 +4944,29 @@ void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
4913 }4944 }
4914 vm->SetpkgContextInfoList(pkgContextInfoList);4945 vm->SetpkgContextInfoList(pkgContextInfoList);
4915}4946}
4947+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4916 4948 
4949+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4950+void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm,
4951+ const std::map<std::string, std::vector<std::vector<std::string>>> &list)
4952+{
4953+ ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
4954+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>>> pkgContextInfoList;
4955+ for (auto &[moduleName, pkgContextInfos]: list) {
4956+ ecmascript::CMap<ecmascript::CString,
4957+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>> map;
4958+ for (auto &datas: pkgContextInfos) {
4959+ if (datas.empty()) {
4960+ continue;
4961+ }
4962+ ecmascript::CString pkgName = datas[0].c_str();
4963+ map.emplace(pkgName, ecmascript::ohos::ModulePkgParser::BuildPkgContextInfo(datas));
4964+ }
4965+ pkgContextInfoList.emplace(moduleName, map);
4966+ }
4967+ vm->UpdatePkgContextInfoList(pkgContextInfoList);
4968+}
4969+#else
4917void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm,4970void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm,
4918 const std::map<std::string, std::vector<std::vector<std::string>>> &list)4971 const std::map<std::string, std::vector<std::vector<std::string>>> &list)
4919{4972{
@@ -4941,7 +4994,24 @@ void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm,
4941 workerVm->UpdatePkgContextInfoList(pkgContextInfoList);4994 workerVm->UpdatePkgContextInfoList(pkgContextInfoList);
4942 }4995 }
4943}4996}
4997+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4944 4998 
4999+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5000+void JSNApi::SetPkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,
5001+ std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)
5002+{
5003+ ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
5004+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>>> pkgContextInfoList;
5005+ ecmascript::CMap <ecmascript::CString, ecmascript::CString> pkgAliasList;
5006+ ecmascript::CUnorderedMap<ecmascript::CString, ecmascript::CUnorderedMap<ecmascript::CString,
5007+ ecmascript::CUnorderedSet<ecmascript::CString>>> ohExportsList;
5008+ ecmascript::ohos::ModulePkgParser::ParseModulePkgJson(vm, pkgInfoMap, pkgContextInfoList, pkgAliasList,
5009+ ohExportsList);
5010+ vm->SetpkgContextInfoList(pkgContextInfoList);
5011+ vm->SetPkgAliasList(pkgAliasList);
5012+ vm->SetOhExportsList(ohExportsList);
5013+}
5014+#else
4945void JSNApi::SetPkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,5015void JSNApi::SetPkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,
4946 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)5016 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)
4947{5017{
@@ -4956,7 +5026,24 @@ void JSNApi::SetPkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::str
4956 vm->SetPkgAliasList(pkgAliasList);5026 vm->SetPkgAliasList(pkgAliasList);
4957 vm->SetOhExportsList(ohExportsList);5027 vm->SetOhExportsList(ohExportsList);
4958}5028}
5029+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4959 5030 
5031+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5032+void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,
5033+ std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)
5034+{
5035+ ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
5036+ ecmascript::CVector<std::pair<ecmascript::CString, ecmascript::CString>>>> pkgContextInfoList;
5037+ ecmascript::CMap <ecmascript::CString, ecmascript::CString> pkgAliasList;
5038+ ecmascript::CUnorderedMap<ecmascript::CString, ecmascript::CUnorderedMap<ecmascript::CString,
5039+ ecmascript::CUnorderedSet<ecmascript::CString>>> ohExportsMap;
5040+ ecmascript::ohos::ModulePkgParser::ParseModulePkgJson(vm, pkgInfoMap, pkgContextInfoList, pkgAliasList,
5041+ ohExportsMap);
5042+ vm->UpdatePkgContextInfoList(pkgContextInfoList);
5043+ vm->UpdatePkgAliasList(pkgAliasList);
5044+ vm->UpdateOhExportsList(ohExportsMap);
5045+}
5046+#else
4960void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,5047void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::string,
4961 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)5048 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap)
4962{5049{
@@ -4977,6 +5064,7 @@ void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm, const std::unordered_map<std::
4977 workerVm->UpdateOhExportsList(ohExportsMap);5064 workerVm->UpdateOhExportsList(ohExportsMap);
4978 }5065 }
4979}5066}
5067+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4980 5068 
4981void JSNApi::SetAbilityName(const std::string &abilityName)5069void JSNApi::SetAbilityName(const std::string &abilityName)
4982{5070{
@@ -5129,10 +5217,19 @@ void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM)
5129 vm->SetModuleName(hostVM->GetModuleName());5217 vm->SetModuleName(hostVM->GetModuleName());
5130 vm->SetAssetPath(hostVM->GetAssetPath());5218 vm->SetAssetPath(hostVM->GetAssetPath());
5131 vm->SetIsBundlePack(hostVM->IsBundlePack());5219 vm->SetIsBundlePack(hostVM->IsBundlePack());
5220+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5221+ if (vm->IsFormThread()) {
5222+ vm->SetPkgNameList(const_cast<EcmaVM *>(hostVM)->GetPkgNameList());
5223+ vm->SetPkgAliasList(const_cast<EcmaVM *>(hostVM)->GetPkgAliasList());
5224+ vm->SetpkgContextInfoList(const_cast<EcmaVM *>(hostVM)->GetPkgContextInfoList());
5225+ vm->SetOhExportsList(const_cast<EcmaVM *>(hostVM)->GetOhExportList());
5226+ }
5227+#else
5132 vm->SetPkgNameList(const_cast<EcmaVM *>(hostVM)->GetPkgNameList());5228 vm->SetPkgNameList(const_cast<EcmaVM *>(hostVM)->GetPkgNameList());
5133 vm->SetPkgAliasList(const_cast<EcmaVM *>(hostVM)->GetPkgAliasList());5229 vm->SetPkgAliasList(const_cast<EcmaVM *>(hostVM)->GetPkgAliasList());
5134 vm->SetpkgContextInfoList(const_cast<EcmaVM *>(hostVM)->GetPkgContextInfoList());5230 vm->SetpkgContextInfoList(const_cast<EcmaVM *>(hostVM)->GetPkgContextInfoList());
5135 vm->SetOhExportsList(const_cast<EcmaVM *>(hostVM)->GetOhExportList());5231 vm->SetOhExportsList(const_cast<EcmaVM *>(hostVM)->GetOhExportList());
5232+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5136 5233 
5137 ecmascript::ModuleManager *vmModuleManager =5234 ecmascript::ModuleManager *vmModuleManager =
5138 vm->GetAssociatedJSThread()->GetModuleManager();5235 vm->GetAssociatedJSThread()->GetModuleManager();
@@ -5212,6 +5309,9 @@ EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
5212 runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());5309 runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
5213 runtimeOptions.SetIsWorker(option.GetIsWorker());5310 runtimeOptions.SetIsWorker(option.GetIsWorker());
5214 runtimeOptions.SetIsRestrictedWorker(option.GetIsRestrictedWorker());5311 runtimeOptions.SetIsRestrictedWorker(option.GetIsRestrictedWorker());
5312+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5313+ runtimeOptions.SetIsFormThread(option.GetIsFormThread());
5314+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
5215// Disable the asm-interpreter of ark-engine for ios-platform temporarily.5315// Disable the asm-interpreter of ark-engine for ios-platform temporarily.
5216#if !defined(PANDA_TARGET_IOS)5316#if !defined(PANDA_TARGET_IOS)
5217 // asmInterpreter5317 // asmInterpreter
Mecmascript/napi/test/jsnapi_third_tests.cpp+137-48
@@ -4393,6 +4393,111 @@ HWTEST_F_L0(JSNApiTests, SetStopPreLoadSoCallback)
4393 EXPECT_EQ(stopPreLoadCallbacks.size(), 0);4393 EXPECT_EQ(stopPreLoadCallbacks.size(), 0);
4394}4394}
4395 4395 
4396+static std::pair<std::unique_ptr<uint8_t[]>, size_t> CreateBufferFromString(const std::string &str)
4397+{
4398+ size_t size = str.size();
4399+ auto buffer = std::make_unique<uint8_t[]>(size);
4400+ std::copy(str.begin(), str.end(), buffer.get());
4401+ return std::make_pair(std::move(buffer), size);
4402+}
4403+ 
4404+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4405+[[maybe_unused]] static constexpr size_t PKG_FLAT_ENTRY_COUNT = 12; // 6 pkg fields x 2 (key, value)
4406+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4407+static constexpr size_t ENTRY_HAP_PAIR_COUNT = 3; // non-empty pairs for the "entry" hap
4408+static constexpr size_t HSP_PAIR_COUNT = 4; // non-empty pairs for the "hsp"
4409+static constexpr size_t LIBRARY_PAIR_COUNT = 6; // non-empty pairs for the "library"
4410+ 
4411+static void VerifyEntryHspPkgInfo(EcmaVM *vm)
4412+{
4413+#if ENABLE_LATEST_OPTIMIZATION
4414+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4415+ CVector<std::pair<CString, CString>> hapInfo{};
4416+ vm->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4417+ EXPECT_EQ(hapInfo.size(), ENTRY_HAP_PAIR_COUNT);
4418+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "packageName"), "entry");
4419+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "bundleName"), "");
4420+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "moduleName"), "");
4421+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "version"), "");
4422+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "entryPath"), "src/main/");
4423+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "isSO"), "false");
4424+ CVector<std::pair<CString, CString>> hspInfo{};
4425+ vm->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);
4426+ EXPECT_EQ(hspInfo.size(), HSP_PAIR_COUNT);
4427+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "packageName"), "hsp");
4428+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "bundleName"), "");
4429+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "moduleName"), "");
4430+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "version"), "1.1.0");
4431+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "entryPath"), "Index.ets");
4432+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "isSO"), "false");
4433+#else
4434+ CVector<CString> hapInfo{};
4435+ vm->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4436+ EXPECT_EQ(hapInfo.size(), PKG_FLAT_ENTRY_COUNT);
4437+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_PACKAGE_NAME_INDEX], "entry");
4438+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_BUDNLE_NAME_INDEX], "");
4439+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_MODULE_NAME_INDEX], "");
4440+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_VERSION_INDEX], "");
4441+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_ENTRY_PATH_INDEX], "src/main/");
4442+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_IS_SO_INDEX], "false");
4443+ CVector<CString> hspInfo{};
4444+ vm->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);
4445+ EXPECT_EQ(hspInfo.size(), PKG_FLAT_ENTRY_COUNT);
4446+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_PACKAGE_NAME_INDEX], "hsp");
4447+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_BUDNLE_NAME_INDEX], "");
4448+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_MODULE_NAME_INDEX], "");
4449+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_VERSION_INDEX], "1.1.0");
4450+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_ENTRY_PATH_INDEX], "Index.ets");
4451+ EXPECT_EQ(hspInfo[ModulePathHelper::PKGINFO_IS_SO_INDEX], "false");
4452+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4453+#endif
4454+}
4455+ 
4456+static void VerifyEntryLibraryPkgInfo(EcmaVM *vm)
4457+{
4458+#if ENABLE_LATEST_OPTIMIZATION
4459+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4460+ CVector<std::pair<CString, CString>> hapInfo{};
4461+ vm->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4462+ EXPECT_EQ(hapInfo.size(), ENTRY_HAP_PAIR_COUNT);
4463+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "packageName"), "entry");
4464+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "bundleName"), "");
4465+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "moduleName"), "");
4466+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "version"), "");
4467+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "entryPath"), "src/main/");
4468+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hapInfo, "isSO"), "false");
4469+ CVector<std::pair<CString, CString>> libraryInfo{};
4470+ vm->GetPkgContextInfoListElements("library", "library", libraryInfo);
4471+ EXPECT_EQ(libraryInfo.size(), LIBRARY_PAIR_COUNT);
4472+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "packageName"), "library");
4473+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "bundleName"), "com.xxx.xxxx");
4474+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "moduleName"), "library");
4475+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "version"), "1.0.0");
4476+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "entryPath"), "Index.ets");
4477+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(libraryInfo, "isSO"), "false");
4478+#else
4479+ CVector<CString> hapInfo{};
4480+ vm->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4481+ EXPECT_EQ(hapInfo.size(), PKG_FLAT_ENTRY_COUNT);
4482+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_PACKAGE_NAME_INDEX], "entry");
4483+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_BUDNLE_NAME_INDEX], "");
4484+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_MODULE_NAME_INDEX], "");
4485+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_VERSION_INDEX], "");
4486+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_ENTRY_PATH_INDEX], "src/main/");
4487+ EXPECT_EQ(hapInfo[ModulePathHelper::PKGINFO_IS_SO_INDEX], "false");
4488+ CVector<CString> libraryInfo{};
4489+ vm->GetPkgContextInfoListElements("library", "library", libraryInfo);
4490+ EXPECT_EQ(libraryInfo.size(), PKG_FLAT_ENTRY_COUNT);
4491+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_PACKAGE_NAME_INDEX], "library");
4492+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_BUDNLE_NAME_INDEX], "com.xxx.xxxx");
4493+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_MODULE_NAME_INDEX], "library");
4494+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_VERSION_INDEX], "1.0.0");
4495+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_ENTRY_PATH_INDEX], "Index.ets");
4496+ EXPECT_EQ(libraryInfo[ModulePathHelper::PKGINFO_IS_SO_INDEX], "false");
4497+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4498+#endif
4499+}
4500+ 
4396HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoList)4501HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoList)
4397{4502{
4398 std::map<std::string, std::vector<std::vector<std::string>>> pkgList;4503 std::map<std::string, std::vector<std::vector<std::string>>> pkgList;
@@ -4417,31 +4522,20 @@ HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoList)
4417 };4522 };
4418 newPkgList["hsp"] = {hspList};4523 newPkgList["hsp"] = {hspList};
4419 JSNApi::UpdatePkgContextInfoList(vm_, newPkgList);4524 JSNApi::UpdatePkgContextInfoList(vm_, newPkgList);
4525+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4526+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> vmPkgList = vm_->GetPkgContextInfoList();
4527+ EXPECT_EQ(vmPkgList.size(), 2);
4528+ EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 3);
4529+ EXPECT_EQ(vmPkgList["hsp"].size(), 1);
4530+ EXPECT_EQ(vmPkgList["hsp"]["hsp"].size(), 4);
4531+#else
4420 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();4532 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();
4421 EXPECT_EQ(vmPkgList.size(), 2);4533 EXPECT_EQ(vmPkgList.size(), 2);
4422 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);4534 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);
4423 EXPECT_EQ(vmPkgList["hsp"].size(), 1);4535 EXPECT_EQ(vmPkgList["hsp"].size(), 1);
4424 EXPECT_EQ(vmPkgList["hsp"]["hsp"].size(), 12);4536 EXPECT_EQ(vmPkgList["hsp"]["hsp"].size(), 12);
4425-#if ENABLE_LATEST_OPTIMIZATION4537+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4426- CVector<CString> hapInfo{};4538+ VerifyEntryHspPkgInfo(vm_);
4427- vm_->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4428- EXPECT_EQ(hapInfo.size(), 12);
4429- EXPECT_EQ(hapInfo[1], "entry");
4430- EXPECT_EQ(hapInfo[3], "");
4431- EXPECT_EQ(hapInfo[5], "");
4432- EXPECT_EQ(hapInfo[7], "");
4433- EXPECT_EQ(hapInfo[9], "src/main/");
4434- EXPECT_EQ(hapInfo[11], "false");
4435- CVector<CString> hspInfo{};
4436- vm_->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);
4437- EXPECT_EQ(hspInfo.size(), 12);
4438- EXPECT_EQ(hspInfo[1], "hsp");
4439- EXPECT_EQ(hspInfo[3], "");
4440- EXPECT_EQ(hspInfo[5], "");
4441- EXPECT_EQ(hspInfo[7], "1.1.0");
4442- EXPECT_EQ(hspInfo[9], "Index.ets");
4443- EXPECT_EQ(hspInfo[11], "false");
4444-#endif
4445}4539}
4446 4540 
4447HWTEST_F_L0(JSNApiTests, UpdatePkgNameList)4541HWTEST_F_L0(JSNApiTests, UpdatePkgNameList)
@@ -4483,40 +4577,23 @@ HWTEST_F_L0(JSNApiTests, SetPkgContextInfoListWithBuffer)
4483 "", "version":"", "entryPath":"src/main/", "isSO":false, "dependencyAlias":""}})";4577 "", "version":"", "entryPath":"src/main/", "isSO":false, "dependencyAlias":""}})";
4484 std::string libraryString = R"({"library":{"packageName":"library", "bundleName":"com.xxx.xxxx", "moduleName":4578 std::string libraryString = R"({"library":{"packageName":"library", "bundleName":"com.xxx.xxxx", "moduleName":
4485 "library", "version":"1.0.0", "entryPath":"Index.ets", "isSO":false, "dependencyAlias":"har"}})";4579 "library", "version":"1.0.0", "entryPath":"Index.ets", "isSO":false, "dependencyAlias":"har"}})";
4486- auto createBufferFromString = [](const std::string& str) {4580+ modulePkgContentMap["entry"] = CreateBufferFromString(entryString);
4487- size_t size = str.size();4581+ modulePkgContentMap["library"] = CreateBufferFromString(libraryString);
4488- auto buffer = std::make_unique<uint8_t[]>(size);
4489- std::copy(str.begin(), str.end(), buffer.get());
4490- return std::make_pair(std::move(buffer), size);
4491- };
4492- modulePkgContentMap["entry"] = createBufferFromString(entryString);
4493- modulePkgContentMap["library"] = createBufferFromString(libraryString);
4494 JSNApi::SetPkgContextInfoList(vm_, modulePkgContentMap);4582 JSNApi::SetPkgContextInfoList(vm_, modulePkgContentMap);
4583+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4584+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> vmPkgList = vm_->GetPkgContextInfoList();
4585+ EXPECT_EQ(vmPkgList.size(), 2);
4586+ EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 3);
4587+ EXPECT_EQ(vmPkgList["library"].size(), 1);
4588+ EXPECT_EQ(vmPkgList["library"]["library"].size(), 6);
4589+#else
4495 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();4590 CMap<CString, CMap<CString, CVector<CString>>> vmPkgList = vm_->GetPkgContextInfoList();
4496 EXPECT_EQ(vmPkgList.size(), 2);4591 EXPECT_EQ(vmPkgList.size(), 2);
4497 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);4592 EXPECT_EQ(vmPkgList["entry"]["entry"].size(), 12);
4498 EXPECT_EQ(vmPkgList["library"].size(), 1);4593 EXPECT_EQ(vmPkgList["library"].size(), 1);
4499 EXPECT_EQ(vmPkgList["library"]["library"].size(), 12);4594 EXPECT_EQ(vmPkgList["library"]["library"].size(), 12);
4500-#if ENABLE_LATEST_OPTIMIZATION4595+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4501- CVector<CString> hapInfo{};4596+ VerifyEntryLibraryPkgInfo(vm_);
4502- vm_->GetPkgContextInfoListElements("entry", "entry", hapInfo);
4503- EXPECT_EQ(hapInfo.size(), 12);
4504- EXPECT_EQ(hapInfo[1], "entry");
4505- EXPECT_EQ(hapInfo[3], "");
4506- EXPECT_EQ(hapInfo[5], "");
4507- EXPECT_EQ(hapInfo[7], "");
4508- EXPECT_EQ(hapInfo[9], "src/main/");
4509- EXPECT_EQ(hapInfo[11], "false");
4510- CVector<CString> libraryInfo{};
4511- vm_->GetPkgContextInfoListElements("library", "library", libraryInfo);
4512- EXPECT_EQ(libraryInfo.size(), 12);
4513- EXPECT_EQ(libraryInfo[1], "library");
4514- EXPECT_EQ(libraryInfo[3], "com.xxx.xxxx");
4515- EXPECT_EQ(libraryInfo[5], "library");
4516- EXPECT_EQ(libraryInfo[7], "1.0.0");
4517- EXPECT_EQ(libraryInfo[9], "Index.ets");
4518- EXPECT_EQ(libraryInfo[11], "false");
4519-#endif
4520}4597}
4521 4598 
4522HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoListWithBuffer)4599HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoListWithBuffer)
@@ -4533,6 +4610,17 @@ HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoListWithBuffer)
4533 updatePkgContentMap["hsp"] = createBufferFromString(hspString);4610 updatePkgContentMap["hsp"] = createBufferFromString(hspString);
4534 JSNApi::UpdatePkgContextInfoList(vm_, updatePkgContentMap);4611 JSNApi::UpdatePkgContextInfoList(vm_, updatePkgContentMap);
4535#if ENABLE_LATEST_OPTIMIZATION4612#if ENABLE_LATEST_OPTIMIZATION
4613+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4614+ CVector<std::pair<CString, CString>> hspInfo{};
4615+ vm_->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);
4616+ EXPECT_EQ(hspInfo.size(), 5);
4617+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "packageName"), "hsp");
4618+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "bundleName"), "");
4619+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "moduleName"), "hsp");
4620+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "version"), "1.1.0");
4621+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "entryPath"), "Index.ets");
4622+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(hspInfo, "isSO"), "false");
4623+#else
4536 CVector<CString> hspInfo{};4624 CVector<CString> hspInfo{};
4537 vm_->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);4625 vm_->GetPkgContextInfoListElements("hsp", "hsp", hspInfo);
4538 EXPECT_EQ(hspInfo.size(), 12);4626 EXPECT_EQ(hspInfo.size(), 12);
@@ -4542,6 +4630,7 @@ HWTEST_F_L0(JSNApiTests, UpdatePkgContextInfoListWithBuffer)
4542 EXPECT_EQ(hspInfo[7], "1.1.0");4630 EXPECT_EQ(hspInfo[7], "1.1.0");
4543 EXPECT_EQ(hspInfo[9], "Index.ets");4631 EXPECT_EQ(hspInfo[9], "Index.ets");
4544 EXPECT_EQ(hspInfo[11], "false");4632 EXPECT_EQ(hspInfo[11], "false");
4633+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
4545#endif4634#endif
4546}4635}
4547 4636 
Mecmascript/ohos/adapter/modulemanager/module_pkg_parser.cpp+112-1
@@ -25,6 +25,33 @@ static const std::string IS_SO = "isSO";
25static const std::string DEPENDENCY_ALIAS = "dependencyAlias";25static const std::string DEPENDENCY_ALIAS = "dependencyAlias";
26static const std::string OH_EXPORT = "oh-exports";26static const std::string OH_EXPORT = "oh-exports";
27 27 
28+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
29+bool ModulePkgParser::ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,
30+ std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,
31+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &pkgContextInfoList,
32+ CMap<CString, CString> &pkgAliasList,
33+ CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap)
34+{
35+#ifndef CROSS_PLATFORM
36+ for (auto it = pkgInfoMap.begin(); it != pkgInfoMap.end(); ++it) {
37+ CString moduleName(it->first);
38+ const std::unique_ptr<uint8_t[]> &data = it->second.first;
39+ size_t dataLen = it->second.second;
40+ CMap<CString, CVector<std::pair<CString, CString>>> modulePkgInfo;
41+ CUnorderedMap<CString, CUnorderedSet<CString>> moduleOhExportsMap;
42+ if (!ParsePkgContextInfoJson(vm, moduleName, data.get(), dataLen, modulePkgInfo, pkgAliasList,
43+ moduleOhExportsMap)) {
44+ LOG_ECMA(ERROR) << "ModulePkgParser::ParseModulePkgJson parse module context info failed, moduleName is "
45+ << moduleName;
46+ return false;
47+ }
48+ pkgContextInfoList.emplace(moduleName, modulePkgInfo);
49+ ohExportsMap.emplace(moduleName, moduleOhExportsMap);
50+ }
51+#endif
52+ return true;
53+}
54+#else
28bool ModulePkgParser::ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,55bool ModulePkgParser::ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,
29 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,56 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,
30 CMap<CString, CMap<CString, CVector<CString>>> &pkgContextInfoList,57 CMap<CString, CMap<CString, CVector<CString>>> &pkgContextInfoList,
@@ -50,10 +77,66 @@ bool ModulePkgParser::ParseModulePkgJson(const EcmaVM *vm, const std::unordered_
50#endif77#endif
51 return true;78 return true;
52}79}
80+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
81+ 
82+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
83+static constexpr size_t KEY_VALUE_PAIR_STEP = 2;
84+ 
85+CVector<std::pair<CString, CString>> ModulePkgParser::BuildPkgContextInfo(const std::vector<std::string> &datas)
86+{
87+ CVector<std::pair<CString, CString>> pkgContextInfo;
88+ for (size_t i = 1; i + 1 < datas.size(); i += KEY_VALUE_PAIR_STEP) {
89+ if (datas[i + 1].empty()) {
90+ continue; // filter empty value
91+ }
92+ pkgContextInfo.emplace_back(CString(datas[i].c_str()), CString(datas[i + 1].c_str()));
93+ }
94+ return pkgContextInfo;
95+}
96+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
53 97 
54#ifndef CROSS_PLATFORM98#ifndef CROSS_PLATFORM
99+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
55bool ModulePkgParser::ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,100bool ModulePkgParser::ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,
56- size_t dataLen, CMap<CString, CVector<CString>> &modulePkgInfo, CMap<CString, CString> &pkgAliasList,101+ size_t dataLen, CMap<CString, CVector<std::pair<CString, CString>>> &modulePkgInfo,
102+ CMap<CString, CString> &pkgAliasList,
103+ CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap)
104+{
105+ auto jsonObject = nlohmann::json::parse(data, data + dataLen, nullptr, false);
106+ if (jsonObject.is_discarded()) {
107+ LOG_ECMA(ERROR) << "ModulePkgParser::ParseModulePkgJson parse json failed, moduleName is "
108+ << moduleName;
109+ return false;
110+ }
111+ for (auto jsonIt = jsonObject.begin(); jsonIt != jsonObject.end(); ++jsonIt) {
112+ CVector<std::pair<CString, CString>> items;
113+ CUnorderedSet<CString> ohExportsSet;
114+ nlohmann::json itemObject = jsonIt.value();
115+ if (!itemObject.is_object()) {
116+ LOG_ECMA(ERROR) << "ModulePkgParser::ParseModulePkgJson item is not object, moduleName is "
117+ << moduleName;
118+ return false;
119+ }
120+ ParsePkgContextInfoItemJson(itemObject, PACKAGE_NAME, items);
121+ ParsePkgContextInfoItemJson(itemObject, BUNDLE_NAME, items);
122+ ParsePkgContextInfoItemJson(itemObject, MODULE_NAME, items);
123+ ParsePkgContextInfoItemJson(itemObject, VERSION, items);
124+ ParsePkgContextInfoItemJson(itemObject, ENTRY_PATH, items);
125+ ParsePkgContextInfoSoJson(itemObject, items);
126+ 
127+ CString packageName(jsonIt.key());
128+ ParsePkgContextInfoAliasJson(itemObject, packageName, pkgAliasList);
129+ modulePkgInfo.emplace(packageName, items);
130+ if (ParsePkgContextInfoOhExports(itemObject, ohExportsSet)) {
131+ moduleOhExportsMap.emplace(packageName, ohExportsSet);
132+ }
133+ }
134+ return true;
135+}
136+#else
137+bool ModulePkgParser::ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,
138+ size_t dataLen, CMap<CString, CVector<CString>> &modulePkgInfo,
139+ CMap<CString, CString> &pkgAliasList,
57 CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap)140 CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap)
58{141{
59 auto jsonObject = nlohmann::json::parse(data, data + dataLen, nullptr, false);142 auto jsonObject = nlohmann::json::parse(data, data + dataLen, nullptr, false);
@@ -87,7 +170,22 @@ bool ModulePkgParser::ParsePkgContextInfoJson(const EcmaVM *vm, const CString &m
87 }170 }
88 return true;171 return true;
89}172}
173+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
90 174 
175+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
176+void ModulePkgParser::ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,
177+ CVector<std::pair<CString, CString>> &items)
178+{
179+ if (itemObject[key].is_null() || !itemObject[key].is_string()) {
180+ return;
181+ }
182+ CString valueStr(itemObject[key].get<std::string>());
183+ if (valueStr.empty()) {
184+ return;
185+ }
186+ items.emplace_back(CString(key), valueStr);
187+}
188+#else
91void ModulePkgParser::ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,189void ModulePkgParser::ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,
92 CVector<CString> &items)190 CVector<CString> &items)
93{191{
@@ -100,7 +198,19 @@ void ModulePkgParser::ParsePkgContextInfoItemJson(const nlohmann::json &itemObje
100 items.emplace_back(valueStr);198 items.emplace_back(valueStr);
101 }199 }
102}200}
201+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
103 202 
203+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
204+void ModulePkgParser::ParsePkgContextInfoSoJson(const nlohmann::json &itemObject,
205+ CVector<std::pair<CString, CString>> &items)
206+{
207+ CString isSoValue("false");
208+ if (!itemObject[IS_SO].is_null() && itemObject[IS_SO].is_boolean() && itemObject[IS_SO].get<bool>()) {
209+ isSoValue = "true";
210+ }
211+ items.emplace_back(CString(IS_SO), isSoValue);
212+}
213+#else
104void ModulePkgParser::ParsePkgContextInfoSoJson(const nlohmann::json &itemObject, CVector<CString> &items)214void ModulePkgParser::ParsePkgContextInfoSoJson(const nlohmann::json &itemObject, CVector<CString> &items)
105{215{
106 items.emplace_back(IS_SO);216 items.emplace_back(IS_SO);
@@ -115,6 +225,7 @@ void ModulePkgParser::ParsePkgContextInfoSoJson(const nlohmann::json &itemObject
115 }225 }
116 }226 }
117}227}
228+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
118 229 
119void ModulePkgParser::ParsePkgContextInfoAliasJson(const nlohmann::json &itemObject, const CString &packageName,230void ModulePkgParser::ParsePkgContextInfoAliasJson(const nlohmann::json &itemObject, const CString &packageName,
120 CMap<CString, CString> &pkgAliasList)231 CMap<CString, CString> &pkgAliasList)
Mecmascript/ohos/adapter/modulemanager/module_pkg_parser.h+26-1
@@ -17,7 +17,9 @@
17 17 
18#include <cstdint>18#include <cstdint>
19#include <memory>19#include <memory>
20+#include <string>
20#include <unordered_map>21#include <unordered_map>
22+#include <vector>
21 23 
22#ifndef CROSS_PLATFORM24#ifndef CROSS_PLATFORM
23#include <nlohmann/json.hpp>25#include <nlohmann/json.hpp>
@@ -28,19 +30,42 @@
28namespace panda::ecmascript::ohos {30namespace panda::ecmascript::ohos {
29class ModulePkgParser {31class ModulePkgParser {
30public:32public:
33+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
34+ static CVector<std::pair<CString, CString>> BuildPkgContextInfo(const std::vector<std::string> &datas);
35+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
36+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
37+ static bool ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,
38+ std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,
39+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &pkgContextInfoList,
40+ CMap<CString, CString> &pkgAliasList,
41+ CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap);
42+#else
31 static bool ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,43 static bool ParseModulePkgJson(const EcmaVM *vm, const std::unordered_map<std::string,
32 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,44 std::pair<std::unique_ptr<uint8_t[]>, size_t>> &pkgInfoMap,
33 CMap<CString, CMap<CString, CVector<CString>>> &pkgContextInfoList,45 CMap<CString, CMap<CString, CVector<CString>>> &pkgContextInfoList,
34 CMap<CString, CString> &pkgAliasList,46 CMap<CString, CString> &pkgAliasList,
35 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap);47 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> &ohExportsMap);
48+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
36private:49private:
37#ifndef CROSS_PLATFORM50#ifndef CROSS_PLATFORM
51+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
38 static bool ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,52 static bool ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,
39- size_t dataLen, CMap<CString, CVector<CString>> &modulePkgInfo, CMap<CString, CString> &pkgAliasList,53+ size_t dataLen, CMap<CString, CVector<std::pair<CString, CString>>> &modulePkgInfo,
54+ CMap<CString, CString> &pkgAliasList,
55+ CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap);
56+ static void ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,
57+ CVector<std::pair<CString, CString>> &items);
58+ static void ParsePkgContextInfoSoJson(const nlohmann::json &itemObject,
59+ CVector<std::pair<CString, CString>> &items);
60+#else
61+ static bool ParsePkgContextInfoJson(const EcmaVM *vm, const CString &moduleName, const uint8_t *data,
62+ size_t dataLen, CMap<CString, CVector<CString>> &modulePkgInfo,
63+ CMap<CString, CString> &pkgAliasList,
40 CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap);64 CUnorderedMap<CString, CUnorderedSet<CString>> &moduleOhExportsMap);
41 static void ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,65 static void ParsePkgContextInfoItemJson(const nlohmann::json &itemObject, const std::string &key,
42 CVector<CString> &items);66 CVector<CString> &items);
43 static void ParsePkgContextInfoSoJson(const nlohmann::json &itemObject, CVector<CString> &items);67 static void ParsePkgContextInfoSoJson(const nlohmann::json &itemObject, CVector<CString> &items);
68+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
44 static void ParsePkgContextInfoAliasJson(const nlohmann::json &itemObject, const CString &packageName,69 static void ParsePkgContextInfoAliasJson(const nlohmann::json &itemObject, const CString &packageName,
45 CMap<CString, CString> &pkgAliasList);70 CMap<CString, CString> &pkgAliasList);
46 static bool ParsePkgContextInfoOhExports(const nlohmann::json &itemObject, CUnorderedSet<CString> &result);71 static bool ParsePkgContextInfoOhExports(const nlohmann::json &itemObject, CUnorderedSet<CString> &result);
Aecmascript/ohos/adapter/modulemanager/pkg_context_store.h+194-0
@@ -0,0 +1,194 @@
1+/**
2+ * Copyright (c) 2025-2026 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+#ifndef ECMASCRIPT_OHOS_ADAPTER_MODULEMANAGER_PKG_CONTEXT_STORE_H
17+#define ECMASCRIPT_OHOS_ADAPTER_MODULEMANAGER_PKG_CONTEXT_STORE_H
18+ 
19+#include "ecmascript/log_wrapper.h"
20+#include "ecmascript/mem/c_containers.h"
21+#include "ecmascript/mem/c_string.h"
22+#include "ecmascript/platform/mutex.h"
23+ 
24+namespace panda::ecmascript {
25+ 
26+class PkgContextStore {
27+public:
28+ void SetPkgNameList(const CMap<CString, CString> &list)
29+ {
30+ WriteLockHolder lock(pkgNameListLock_);
31+ pkgNameList_ = list;
32+ }
33+ 
34+ void UpdatePkgNameList(const CMap<CString, CString> &list)
35+ {
36+ WriteLockHolder lock(pkgNameListLock_);
37+ pkgNameList_.insert(list.begin(), list.end());
38+ }
39+ 
40+ CMap<CString, CString> GetPkgNameList() const
41+ {
42+ ReadLockHolder lock(pkgNameListLock_);
43+ return pkgNameList_;
44+ }
45+ 
46+ CString GetPkgName(const CString &moduleName) const
47+ {
48+ ReadLockHolder lock(pkgNameListLock_);
49+ auto it = pkgNameList_.find(moduleName);
50+ if (it == pkgNameList_.end()) {
51+ LOG_ECMA(INFO) << " Get Pkg Name failed";
52+ return moduleName;
53+ }
54+ return it->second;
55+ }
56+ 
57+ void SetPkgAliasList(const CMap<CString, CString> &list)
58+ {
59+ WriteLockHolder lock(pkgAliasListLock_);
60+ pkgAliasList_ = list;
61+ }
62+ 
63+ void UpdatePkgAliasList(const CMap<CString, CString> &list)
64+ {
65+ WriteLockHolder lock(pkgAliasListLock_);
66+ pkgAliasList_.insert(list.begin(), list.end());
67+ }
68+ 
69+ CMap<CString, CString> GetPkgAliasList() const
70+ {
71+ ReadLockHolder lock(pkgAliasListLock_);
72+ return pkgAliasList_;
73+ }
74+ 
75+ CString GetPkgNameWithAlias(const CString &alias) const
76+ {
77+ ReadLockHolder lock(pkgAliasListLock_);
78+ auto it = pkgAliasList_.find(alias);
79+ if (it == pkgAliasList_.end()) {
80+ return alias;
81+ }
82+ return it->second;
83+ }
84+ 
85+ void SetPkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list)
86+ {
87+ WriteLockHolder lock(pkgContextInfoLock_);
88+ pkgContextInfoList_ = list;
89+ }
90+ 
91+ void UpdatePkgContextInfoList(const CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> &list)
92+ {
93+ WriteLockHolder lock(pkgContextInfoLock_);
94+ pkgContextInfoList_.insert(list.begin(), list.end());
95+ }
96+ 
97+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> GetPkgContextInfoList() const
98+ {
99+ ReadLockHolder lock(pkgContextInfoLock_);
100+ return pkgContextInfoList_;
101+ }
102+ 
103+ bool IsNormalizedOhmUrlPack() const
104+ {
105+ ReadLockHolder lock(pkgContextInfoLock_);
106+ return !pkgContextInfoList_.empty();
107+ }
108+ 
109+ void GetPkgContextInfoListElements(const CString &moduleName, const CString &packageName,
110+ CVector<std::pair<CString, CString>> &resultList) const
111+ {
112+ ReadLockHolder lock(pkgContextInfoLock_);
113+ if (packageName.empty()) {
114+ return;
115+ }
116+ auto pkgContextIt = pkgContextInfoList_.find(moduleName);
117+ if (pkgContextIt == pkgContextInfoList_.end()) {
118+ return;
119+ }
120+ const CMap<CString, CVector<std::pair<CString, CString>>> &pkgList = pkgContextIt->second;
121+ auto pkgIt = pkgList.find(packageName);
122+ if (pkgIt == pkgList.end()) {
123+ return;
124+ }
125+ resultList = pkgIt->second;
126+ }
127+ 
128+ void SetOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
129+ CUnorderedSet<CString>>> &ohExportsMap)
130+ {
131+ WriteLockHolder lock(ohExportListLock_);
132+ ohExportsList_ = ohExportsMap;
133+ }
134+ 
135+ void UpdateOhExportsList(const CUnorderedMap<CString, CUnorderedMap<CString,
136+ CUnorderedSet<CString>>> &ohExportsMap)
137+ {
138+ WriteLockHolder lock(ohExportListLock_);
139+ ohExportsList_.insert(ohExportsMap.begin(), ohExportsMap.end());
140+ }
141+ 
142+ CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> GetOhExportList() const
143+ {
144+ ReadLockHolder lock(ohExportListLock_);
145+ return ohExportsList_;
146+ }
147+ 
148+ bool CheckOhExportsWithOhmurl(const CString &moduleName, const CString &packageName,
149+ const CString &ohmurl) const
150+ {
151+ ReadLockHolder lock(ohExportListLock_);
152+ if (packageName.empty()) {
153+ return true;
154+ }
155+ auto moduleIt = ohExportsList_.find(moduleName);
156+ if (moduleIt == ohExportsList_.end()) {
157+ return true;
158+ }
159+ const CUnorderedMap<CString, CUnorderedSet<CString>> &moduleExportsList = moduleIt->second;
160+ auto packageIt = moduleExportsList.find(packageName);
161+ if (packageIt == moduleExportsList.end()) {
162+ return true;
163+ }
164+ const CUnorderedSet<CString> &packageExportsList = packageIt->second;
165+ return (packageExportsList.find(ohmurl) != packageExportsList.end());
166+ }
167+ 
168+ // Reset process-level non-form pkg context (main VM teardown / Runtime reuse).
169+ void ClearPkgContextInfo()
170+ {
171+ WriteLockHolder l1(pkgNameListLock_);
172+ WriteLockHolder l2(pkgAliasListLock_);
173+ WriteLockHolder l3(pkgContextInfoLock_);
174+ WriteLockHolder l4(ohExportListLock_);
175+ pkgNameList_.clear();
176+ pkgAliasList_.clear();
177+ pkgContextInfoList_.clear();
178+ ohExportsList_.clear();
179+ }
180+ 
181+private:
182+ mutable RWLock pkgContextInfoLock_;
183+ mutable RWLock pkgAliasListLock_;
184+ mutable RWLock pkgNameListLock_;
185+ mutable RWLock ohExportListLock_;
186+ CMap<CString, CString> pkgNameList_;
187+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextInfoList_;
188+ CMap<CString, CString> pkgAliasList_;
189+ CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsList_;
190+};
191+ 
192+} // namespace panda::ecmascript
193+ 
194+#endif // ECMASCRIPT_OHOS_ADAPTER_MODULEMANAGER_PKG_CONTEXT_STORE_H
Mecmascript/ohos/tests/ohos_test.cpp+45-10
@@ -25,6 +25,7 @@
25#include "ecmascript/ohos/ohos_pkg_args.h"25#include "ecmascript/ohos/ohos_pkg_args.h"
26#include "ecmascript/ohos/enable_aot_list_helper.h"26#include "ecmascript/ohos/enable_aot_list_helper.h"
27#include "ecmascript/ohos/adapter/modulemanager/module_pkg_parser.h"27#include "ecmascript/ohos/adapter/modulemanager/module_pkg_parser.h"
28+#include "ecmascript/module/module_path_helper.h"
28#include "ecmascript/ohos/tests/mock/mock_enable_aot_list_helper.h"29#include "ecmascript/ohos/tests/mock/mock_enable_aot_list_helper.h"
29#include "ecmascript/platform/file.h"30#include "ecmascript/platform/file.h"
30#include "ecmascript/tests/test_helper.h"31#include "ecmascript/tests/test_helper.h"
@@ -334,6 +335,14 @@ HWTEST_F_L0(OhosTest, AotIsEnableArkProfileFalse)
334 rmdir(whiteListTestDir);335 rmdir(whiteListTestDir);
335}336}
336 337 
338+static std::pair<std::unique_ptr<uint8_t[]>, size_t> CreateBufferFromString(const std::string &str)
339+{
340+ size_t size = str.size();
341+ auto buffer = std::make_unique<uint8_t[]>(size);
342+ std::copy(str.begin(), str.end(), buffer.get());
343+ return std::make_pair(std::move(buffer), size);
344+}
345+ 
337HWTEST_F_L0(OhosTest, ModulePkgParserTest)346HWTEST_F_L0(OhosTest, ModulePkgParserTest)
338{347{
339 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;348 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;
@@ -349,25 +358,31 @@ HWTEST_F_L0(OhosTest, ModulePkgParserTest)
349 "oh-exports":{}}})";358 "oh-exports":{}}})";
350 std::string hsp2String = R"({"hsp2":{"packageName":"hsp2", "bundleName":"com.xxx.xxxx", "moduleName":359 std::string hsp2String = R"({"hsp2":{"packageName":"hsp2", "bundleName":"com.xxx.xxxx", "moduleName":
351 "hsp2", "version":"1.0.0", "entryPath":"Index.ets", "isSO":false, "dependencyAlias": "@ohos/hsp2"}})";360 "hsp2", "version":"1.0.0", "entryPath":"Index.ets", "isSO":false, "dependencyAlias": "@ohos/hsp2"}})";
352- auto createBufferFromString = [](const std::string& str) {361+ modulePkgContentMap["entry"] = CreateBufferFromString(entryString);
353- size_t size = str.size();362+ modulePkgContentMap["library"] = CreateBufferFromString(libraryString);
354- auto buffer = std::make_unique<uint8_t[]>(size);363+ modulePkgContentMap["hsp"] = CreateBufferFromString(hspString);
355- std::copy(str.begin(), str.end(), buffer.get());364+ modulePkgContentMap["hsp2"] = CreateBufferFromString(hsp2String);
356- return std::make_pair(std::move(buffer), size);365+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
357- };366+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextInfoList;
358- modulePkgContentMap["entry"] = createBufferFromString(entryString);367+#else
359- modulePkgContentMap["library"] = createBufferFromString(libraryString);
360- modulePkgContentMap["hsp"] = createBufferFromString(hspString);
361- modulePkgContentMap["hsp2"] = createBufferFromString(hsp2String);
362 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;368 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;
369+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
363 CMap<CString, CString> pkgAliasList;370 CMap<CString, CString> pkgAliasList;
364 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;371 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;
365 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList, pkgAliasList,372 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList, pkgAliasList,
366 ohExportsMap);373 ohExportsMap);
367 EXPECT_TRUE(result);374 EXPECT_TRUE(result);
375+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
376+ EXPECT_EQ(pkgContextInfoList["entry"]["entry"].size(), 6);
377+#else
368 EXPECT_EQ(pkgContextInfoList["entry"]["entry"].size(), 12);378 EXPECT_EQ(pkgContextInfoList["entry"]["entry"].size(), 12);
379+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
369 EXPECT_EQ(pkgContextInfoList["library"].size(), 1);380 EXPECT_EQ(pkgContextInfoList["library"].size(), 1);
381+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
382+ EXPECT_EQ(pkgContextInfoList["library"]["library"].size(), 6);
383+#else
370 EXPECT_EQ(pkgContextInfoList["library"]["library"].size(), 12);384 EXPECT_EQ(pkgContextInfoList["library"]["library"].size(), 12);
385+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
371 386 
372 EXPECT_EQ(pkgAliasList.size(), 3);387 EXPECT_EQ(pkgAliasList.size(), 3);
373 EXPECT_EQ(pkgAliasList["har"], "library");388 EXPECT_EQ(pkgAliasList["har"], "library");
@@ -397,18 +412,34 @@ HWTEST_F_L0(OhosTest, ModulePkgParserTest1)
397 };412 };
398 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;413 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;
399 modulePkgContentMap["entry"] = createBufferFromString(entryString);414 modulePkgContentMap["entry"] = createBufferFromString(entryString);
415+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
416+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextInfoList;
417+#else
400 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;418 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;
419+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
401 CMap<CString, CString> pkgAliasList;420 CMap<CString, CString> pkgAliasList;
402 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;421 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;
403 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList, pkgAliasList,422 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList, pkgAliasList,
404 ohExportsMap);423 ohExportsMap);
405 EXPECT_TRUE(result);424 EXPECT_TRUE(result);
406 //version of entry425 //version of entry
426+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
427+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(pkgContextInfoList["entry"]["entry"], "version"), "");
428+#else
407 EXPECT_EQ(pkgContextInfoList["entry"]["entry"][7], "");429 EXPECT_EQ(pkgContextInfoList["entry"]["entry"][7], "");
430+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
408 //libentry.so isSo431 //libentry.so isSo
432+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
433+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(pkgContextInfoList["entry"]["libentry.so"], "isSO"), "true");
434+#else
409 EXPECT_EQ(pkgContextInfoList["entry"]["libentry.so"][11], "true");435 EXPECT_EQ(pkgContextInfoList["entry"]["libentry.so"][11], "true");
436+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
410 //libhar.so isSo437 //libhar.so isSo
438+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
439+ EXPECT_EQ(ModulePathHelper::GetPkgInfoValueOrEmpty(pkgContextInfoList["entry"]["libhar.so"], "isSO"), "false");
440+#else
411 EXPECT_EQ(pkgContextInfoList["entry"]["libhar.so"][11], "false");441 EXPECT_EQ(pkgContextInfoList["entry"]["libhar.so"][11], "false");
442+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
412}443}
413 444 
414HWTEST_F_L0(OhosTest, ModulePkgParserTest2)445HWTEST_F_L0(OhosTest, ModulePkgParserTest2)
@@ -422,7 +453,11 @@ HWTEST_F_L0(OhosTest, ModulePkgParserTest2)
422 };453 };
423 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;454 std::unordered_map<std::string, std::pair<std::unique_ptr<uint8_t[]>, size_t>> modulePkgContentMap;
424 modulePkgContentMap["entry"] = createBufferFromString(entryString);455 modulePkgContentMap["entry"] = createBufferFromString(entryString);
456+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
457+ CMap<CString, CMap<CString, CVector<std::pair<CString, CString>>>> pkgContextInfoList;
458+#else
425 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;459 CMap<CString, CMap<CString, CVector<CString>>> pkgContextInfoList;
460+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
426 CMap<CString, CString> pkgAliasList;461 CMap<CString, CString> pkgAliasList;
427 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;462 CUnorderedMap<CString, CUnorderedMap<CString, CUnorderedSet<CString>>> ohExportsMap;
428 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList,463 bool result = ohos::ModulePkgParser::ParseModulePkgJson(vm_, modulePkgContentMap, pkgContextInfoList,
Mecmascript/runtime.h+14-0
@@ -28,6 +28,9 @@
28#include "ecmascript/mem/visitor.h"28#include "ecmascript/mem/visitor.h"
29#include "ecmascript/module/js_shared_module_manager.h"29#include "ecmascript/module/js_shared_module_manager.h"
30#include "ecmascript/mutator_lock.h"30#include "ecmascript/mutator_lock.h"
31+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
32+#include "ecmascript/ohos/adapter/modulemanager/pkg_context_store.h"
33+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
31#include "ecmascript/platform/dfx_hisys_event.h"34#include "ecmascript/platform/dfx_hisys_event.h"
32#include "ecmascript/platform/mutex.h"35#include "ecmascript/platform/mutex.h"
33#include "ecmascript/serializer/serialize_chunk.h"36#include "ecmascript/serializer/serialize_chunk.h"
@@ -463,6 +466,13 @@ public:
463 return entryAbilityName_;466 return entryAbilityName_;
464 }467 }
465 468 
469+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
470+ PkgContextStore &GetPkgContextStore()
471+ {
472+ return pkgContextStore_;
473+ }
474+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
475+ 
466private:476private:
467 static constexpr int32_t WORKER_DESTRUCTION_COUNT = 3;477 static constexpr int32_t WORKER_DESTRUCTION_COUNT = 3;
468 static constexpr int32_t MIN_GC_TRIGGER_VM_COUNT = 4;478 static constexpr int32_t MIN_GC_TRIGGER_VM_COUNT = 4;
@@ -555,6 +565,10 @@ private:
555 CMap<DFXHiSysEvent::IncompatibleType, uint32_t> incompatibleEventMap_;565 CMap<DFXHiSysEvent::IncompatibleType, uint32_t> incompatibleEventMap_;
556 RWLock incompatibleEventLock_;566 RWLock incompatibleEventLock_;
557 567 
568+#if ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
569+ PkgContextStore pkgContextStore_;
570+#endif // ENABLE_MODULE_PKGCONTEXT_OPTIMIZATION
571+ 
558 // Runtime instance and VMs creation.572 // Runtime instance and VMs creation.
559 static int32_t vmCount_;573 static int32_t vmCount_;
560 static int32_t destroyCount_;574 static int32_t destroyCount_;