Merge "Move profile registration from bindApplication to LoadedApk" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f016d3aef7
@@ -4970,70 +4970,6 @@ public final class ActivityThread {
|
||||
}
|
||||
}
|
||||
|
||||
// Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp).
|
||||
private static File getPrimaryProfileFile(String packageName) {
|
||||
File profileDir = Environment.getDataProfilesDePackageDirectory(
|
||||
UserHandle.myUserId(), packageName);
|
||||
return new File(profileDir, "primary.prof");
|
||||
}
|
||||
|
||||
private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) {
|
||||
if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
|
||||
return;
|
||||
}
|
||||
final ApplicationInfo appInfo = loadedApk.getApplicationInfo();
|
||||
final List<String> codePaths = new ArrayList<>();
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
||||
codePaths.add(appInfo.sourceDir);
|
||||
}
|
||||
if (appInfo.splitSourceDirs != null) {
|
||||
Collections.addAll(codePaths, appInfo.splitSourceDirs);
|
||||
}
|
||||
|
||||
if (codePaths.isEmpty()) {
|
||||
// If there are no code paths there's no need to setup a profile file and register with
|
||||
// the runtime,
|
||||
return;
|
||||
}
|
||||
|
||||
final File profileFile = getPrimaryProfileFile(loadedApk.mPackageName);
|
||||
if (!profileFile.exists()) {
|
||||
FileDescriptor fd = null;
|
||||
try {
|
||||
final int permissions = 0600; // read-write for user.
|
||||
fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
|
||||
Os.fchmod(fd, permissions);
|
||||
Os.fchown(fd, appInfo.uid, appInfo.uid);
|
||||
} catch (ErrnoException e) {
|
||||
Log.v(TAG, "Unable to create jit profile file "
|
||||
+ profileFile + ": " + e.getMessage());
|
||||
try {
|
||||
Os.unlink(profileFile.getAbsolutePath());
|
||||
} catch (ErrnoException unlinkErr) {
|
||||
if (unlinkErr.errno != OsConstants.ENOENT) {
|
||||
Log.v(TAG, "Unable to unlink jit profile file "
|
||||
+ profileFile + ": " + unlinkErr.getMessage());
|
||||
}
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
IoUtils.closeQuietly(fd);
|
||||
}
|
||||
}
|
||||
|
||||
final File foreignDexProfilesFile =
|
||||
Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
|
||||
String foreignDexProfilesPath = null;
|
||||
if (!foreignDexProfilesFile.exists()) {
|
||||
Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
|
||||
foreignDexProfilesFile.getPath());
|
||||
} else {
|
||||
foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
|
||||
}
|
||||
VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir,
|
||||
codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
|
||||
}
|
||||
|
||||
private void updateDefaultDensity() {
|
||||
final int densityDpi = mCurDefaultDisplayDpi;
|
||||
if (!mDensityCompatMode
|
||||
@@ -5259,18 +5195,13 @@ public final class ActivityThread {
|
||||
+ "due to missing cache directory");
|
||||
}
|
||||
|
||||
// Setup a location to store generated/compiled graphics code and
|
||||
// JIT profiling data. Note that this data is stored in a
|
||||
// device-protected storage area, so these caches must never contain
|
||||
// user sensitive user data.
|
||||
// Setup a location to store generated/compiled graphics code.
|
||||
final Context deviceContext = appContext.createDeviceProtectedStorageContext();
|
||||
final File codeCacheDir = deviceContext.getCodeCacheDir();
|
||||
if (codeCacheDir != null) {
|
||||
setupGraphicsSupport(data.info, codeCacheDir);
|
||||
setupJitProfileSupport(data.info, codeCacheDir);
|
||||
} else {
|
||||
Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " +
|
||||
"due to missing code-cache directory");
|
||||
Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
|
||||
}
|
||||
|
||||
// Add the lib dir path to hardware renderer so that vulkan layers
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.content.res.AssetManager;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.FileUtils;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -38,6 +39,9 @@ import android.os.StrictMode;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
import android.system.ErrnoException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.ArrayMap;
|
||||
@@ -50,6 +54,7 @@ import android.view.DisplayAdjustments;
|
||||
import dalvik.system.VMRuntime;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -62,6 +67,8 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
final class IntentReceiverLeaked extends AndroidRuntimeException {
|
||||
public IntentReceiverLeaked(String msg) {
|
||||
super(msg);
|
||||
@@ -488,6 +495,13 @@ public final class LoadedApk {
|
||||
final String add = TextUtils.join(File.pathSeparator, addedPaths);
|
||||
ApplicationLoaders.getDefault().addPath(mClassLoader, add);
|
||||
}
|
||||
|
||||
// Setup jit profile support.
|
||||
// It is ok to call this multiple times if the application gets updated with new splits.
|
||||
// The runtime only keeps track of unique code paths and can handle re-registration of
|
||||
// the same code path. There's no need to pass `addedPaths` since any new code paths
|
||||
// are already in `mApplicationInfo`.
|
||||
setupJitProfileSupport();
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
@@ -499,6 +513,83 @@ public final class LoadedApk {
|
||||
}
|
||||
}
|
||||
|
||||
// Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp).
|
||||
private static File getPrimaryProfileFile(String packageName) {
|
||||
File profileDir = Environment.getDataProfilesDePackageDirectory(
|
||||
UserHandle.myUserId(), packageName);
|
||||
return new File(profileDir, "primary.prof");
|
||||
}
|
||||
|
||||
private void setupJitProfileSupport() {
|
||||
if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
|
||||
return;
|
||||
}
|
||||
final List<String> codePaths = new ArrayList<>();
|
||||
if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
||||
codePaths.add(mApplicationInfo.sourceDir);
|
||||
}
|
||||
if (mApplicationInfo.splitSourceDirs != null) {
|
||||
Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
|
||||
}
|
||||
|
||||
if (codePaths.isEmpty()) {
|
||||
// If there are no code paths there's no need to setup a profile file and register with
|
||||
// the runtime,
|
||||
return;
|
||||
}
|
||||
|
||||
final File profileFile = getPrimaryProfileFile(mPackageName);
|
||||
if (profileFile.exists()) {
|
||||
if (!profileFile.canRead() || !profileFile.canWrite()) {
|
||||
// The apk might be loaded in a context where we don't have permissions
|
||||
// to track the profile (e.g. when loaded by another app via
|
||||
// createApplicationContext)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Profile does not exist. Create it.
|
||||
FileDescriptor fd = null;
|
||||
try {
|
||||
final int permissions = 0600; // read-write for user.
|
||||
fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
|
||||
Os.fchmod(fd, permissions);
|
||||
Os.fchown(fd, mApplicationInfo.uid, mApplicationInfo.uid);
|
||||
} catch (ErrnoException e) {
|
||||
if (e.errno == OsConstants.EACCES) {
|
||||
// It can happen that the profile file does not exist but the apk is loaded in a
|
||||
// context where we don't have permissions (e.g. when loaded by another app via
|
||||
// createApplicationContext)
|
||||
return;
|
||||
}
|
||||
Log.v(TAG, "Unable to create jit profile file "
|
||||
+ profileFile + ": " + e.getMessage());
|
||||
try {
|
||||
Os.unlink(profileFile.getAbsolutePath());
|
||||
} catch (ErrnoException unlinkErr) {
|
||||
if (unlinkErr.errno != OsConstants.ENOENT) {
|
||||
Log.v(TAG, "Unable to unlink jit profile file "
|
||||
+ profileFile + ": " + unlinkErr.getMessage());
|
||||
}
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
IoUtils.closeQuietly(fd);
|
||||
}
|
||||
}
|
||||
|
||||
final File foreignDexProfilesFile =
|
||||
Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
|
||||
String foreignDexProfilesPath = null;
|
||||
if (!foreignDexProfilesFile.exists()) {
|
||||
Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
|
||||
foreignDexProfilesFile.getPath());
|
||||
} else {
|
||||
foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
|
||||
}
|
||||
VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), mApplicationInfo.dataDir,
|
||||
codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup value for Thread.getContextClassLoader(). If the
|
||||
* package will not run in in a VM with other packages, we set
|
||||
|
||||
Reference in New Issue
Block a user