Skip to content

Commit 1d316bf

Browse files
committed
PackageInfo: Optimize ApplicationInfo creation
When opening and closing activities in Settings, a significant amount of CPU time is spent in ART interface method call trampolines, as reported by simpleperf: 0.32% /apex/com.android.art/lib64/libart.so art_quick_imt_conflict_trampoline PackageInfoWithoutStateUtils is responsible for a substantial portion of the time: 0.34% 0.24% /apex/com.android.art/lib64/libart.so art_quick_imt_conflict_trampoline | -- art_quick_imt_conflict_trampoline | |--5.48%-- android.content.pm.parsing.PackageInfoWithoutStateUtils.appInfoFlags | com.android.server.pm.parsing.pkg.PackageImpl.toAppInfoWithoutState | android.content.pm.parsing.PackageInfoWithoutStateUtils.generateApplicationInfoUnchecked | com.android.server.pm.parsing.PackageInfoUtils.generateApplicationInfo | | | |--33.53%-- com.android.server.pm.parsing.PackageInfoUtils.generateActivityInfo | | | | | |--76.24%-- com.android.server.pm.ComponentResolver$ActivityIntentResolver.newResult To avoid the overhead of calling methods through interfaces, opportunistically cast ParsingPackageRead objects to the real implementation and access fields directly on it. This isn't pretty, but it reduces the CPU time wasted on interface method calls. Test: simpleperf record -a; verify that PackageInfoWithoutStateUtils.appInfoFlags no longer appears under art_quick_imt_conflict_trampoline Change-Id: I475ba804c61739c7537e664b09973665f001270b
1 parent 06d3f98 commit 1d316bf

File tree

1 file changed

+113
-50
lines changed

1 file changed

+113
-50
lines changed

core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java

Lines changed: 113 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -750,58 +750,112 @@ private static int flag(boolean hasFlag, int flag) {
750750
/** @see ApplicationInfo#flags */
751751
public static int appInfoFlags(ParsingPackageRead pkg) {
752752
// @formatter:off
753-
return flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
754-
| flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
755-
| flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
756-
| flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
757-
| flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
758-
| flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
759-
| flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
760-
| flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
761-
| flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
762-
| flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
763-
| flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
764-
| flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
765-
| flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
766-
| flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
767-
| flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
768-
| flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
769-
| flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
770-
| flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
771-
| flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
772-
| flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
773-
| flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
774-
| flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
775-
| flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
776-
| flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
777-
| flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES);
753+
if (pkg instanceof ParsingPackageImpl) {
754+
ParsingPackageImpl pkgi = (ParsingPackageImpl) pkg;
755+
return flag(pkgi.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
756+
| flag(pkgi.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
757+
| flag(pkgi.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
758+
| flag(pkgi.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
759+
| flag(pkgi.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
760+
| flag(pkgi.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
761+
| flag(pkgi.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
762+
| flag(pkgi.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
763+
| flag(pkgi.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
764+
| flag(pkgi.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
765+
| flag(pkgi.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
766+
| flag(pkgi.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
767+
| flag(pkgi.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
768+
| flag(pkgi.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
769+
| flag(pkgi.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
770+
| flag(pkgi.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
771+
| flag(pkgi.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
772+
| flag(pkgi.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
773+
| flag(pkgi.isGame(), ApplicationInfo.FLAG_IS_GAME)
774+
| flag(pkgi.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
775+
| flag(pkgi.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
776+
| flag(pkgi.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
777+
| flag(pkgi.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
778+
| flag(pkgi.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
779+
| flag(pkgi.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES);
780+
} else {
781+
return flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
782+
| flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
783+
| flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
784+
| flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
785+
| flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
786+
| flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
787+
| flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
788+
| flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
789+
| flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
790+
| flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
791+
| flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
792+
| flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
793+
| flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
794+
| flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
795+
| flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
796+
| flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
797+
| flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
798+
| flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
799+
| flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
800+
| flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
801+
| flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
802+
| flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
803+
| flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
804+
| flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
805+
| flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES);
806+
}
778807
// @formatter:on
779808
}
780809

781810
/** @see ApplicationInfo#privateFlags */
782811
public static int appInfoPrivateFlags(ParsingPackageRead pkg) {
783812
// @formatter:off
784-
int privateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
785-
| flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
786-
| flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
787-
| flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
788-
| flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
789-
| flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
790-
| flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
791-
| flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
792-
| flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
793-
| flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
794-
| flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
795-
| flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
796-
| flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
797-
| flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
798-
| flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
799-
| flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
800-
| flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
801-
| flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING);
813+
int privateFlags;
814+
Boolean resizeableActivity;
815+
if (pkg instanceof ParsingPackageImpl) {
816+
ParsingPackageImpl pkgi = (ParsingPackageImpl) pkg;
817+
privateFlags = flag(pkgi.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
818+
| flag(pkgi.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
819+
| flag(pkgi.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
820+
| flag(pkgi.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
821+
| flag(pkgi.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
822+
| flag(pkgi.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
823+
| flag(pkgi.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
824+
| flag(pkgi.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
825+
| flag(pkgi.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
826+
| flag(pkgi.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
827+
| flag(pkgi.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
828+
| flag(pkgi.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
829+
| flag(pkgi.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
830+
| flag(pkgi.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
831+
| flag(pkgi.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
832+
| flag(pkgi.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
833+
| flag(pkgi.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
834+
| flag(pkgi.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING);
835+
resizeableActivity = pkgi.getResizeableActivity();
836+
} else {
837+
privateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
838+
| flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
839+
| flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
840+
| flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
841+
| flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
842+
| flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
843+
| flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
844+
| flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
845+
| flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
846+
| flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
847+
| flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
848+
| flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
849+
| flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
850+
| flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
851+
| flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
852+
| flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
853+
| flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
854+
| flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING);
855+
resizeableActivity = pkg.getResizeableActivity();
856+
}
802857
// @formatter:on
803858

804-
Boolean resizeableActivity = pkg.getResizeableActivity();
805859
if (resizeableActivity != null) {
806860
if (resizeableActivity) {
807861
privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
@@ -816,12 +870,21 @@ public static int appInfoPrivateFlags(ParsingPackageRead pkg) {
816870
/** @see ApplicationInfo#privateFlagsExt */
817871
public static int appInfoPrivateFlagsExt(ParsingPackageRead pkg) {
818872
// @formatter:off
819-
int privateFlagsExt =
820-
flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
821-
| flag(pkg.hasRequestForegroundServiceExemption(),
822-
ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
823-
| flag(pkg.areAttributionsUserVisible(),
824-
ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE);
873+
int privateFlagsExt;
874+
if (pkg instanceof ParsingPackageImpl) {
875+
ParsingPackageImpl pkgi = (ParsingPackageImpl) pkg;
876+
privateFlagsExt = flag(pkgi.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
877+
| flag(pkgi.hasRequestForegroundServiceExemption(),
878+
ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
879+
| flag(pkgi.areAttributionsUserVisible(),
880+
ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE);
881+
} else {
882+
privateFlagsExt = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
883+
| flag(pkg.hasRequestForegroundServiceExemption(),
884+
ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
885+
| flag(pkg.areAttributionsUserVisible(),
886+
ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE);
887+
}
825888
// @formatter:on
826889
return privateFlagsExt;
827890
}

0 commit comments

Comments
 (0)