Merge "Move profile registration from bindApplication to LoadedApk" into nyc-dev

This commit is contained in:
TreeHugger Robot
2016-04-19 15:29:18 +00:00
committed by Android (Google) Code Review
2 changed files with 93 additions and 71 deletions

View File

@@ -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

View File

@@ -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