Skip to content

Commit

Permalink
add SystemLoadWrapperSoSource
Browse files Browse the repository at this point in the history
Summary:
Add new experiment flag `SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE` to test the SystemLoadWrapperSoSource.
This flag would help reduce the overhead on reading the APK file. The directApk soSource needs to iterate/read the APK(zip) file to calculate the lib and dependency list.

Reviewed By: vener91

Differential Revision: D51493295

fbshipit-source-id: e1cac9e012870eb7386a4e40dec7a5cfcaecdc43
  • Loading branch information
simpleton authored and facebook-github-bot committed Nov 28, 2023
1 parent ae5374a commit 6984ea7
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 22 deletions.
63 changes: 41 additions & 22 deletions java/com/facebook/soloader/SoLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ public class SoLoader {
/** Experiment ONLY: disable the fsync job in soSource */
public static final int SOLOADER_DISABLE_FS_SYNC_JOB = (1 << 8);

/**
* Experiment ONLY: use the {@link SystemLoadWrapperSoSource} to instead of the
* directApk/Application soSource. This could work on the apps w/o superpack or any other so file
* compression.
*/
public static final int SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE = (1 << 9);

@GuardedBy("sSoSourcesLock")
private static int sFlags;

Expand Down Expand Up @@ -336,29 +343,35 @@ private static void initSoSources(Context context, int flags) throws IOException
sFlags = flags;

ArrayList<SoSource> soSources = new ArrayList<>();
addSystemLibSoSource(soSources);

// We can only proceed forward if we have a Context. The prominent case
// where we don't have a Context is barebones dalvikvm instantiations. In
// that case, the caller is responsible for providing a correct LD_LIBRARY_PATH.

if (context != null) {
// Prepend our own SoSource for our own DSOs.

if ((flags & SOLOADER_ENABLE_EXOPACKAGE) != 0) {
// Even for an exopackage, there might be some native libraries
// packaged directly in the application (e.g. ASAN libraries alongside
// a wrap.sh script [1]), so make sure we can load them.
// [1] https://developer.android.com/ndk/guides/wrap-script
addApplicationSoSource(soSources, getApplicationSoSourceFlags());
LogUtil.d(TAG, "Adding exo package source: " + SO_STORE_NAME_MAIN);
soSources.add(0, new ExoSoSource(context, SO_STORE_NAME_MAIN));
} else {
if (SysUtil.isSupportedDirectLoad(context, sAppType)) {
addDirectApkSoSource(context, soSources);
final boolean isEnabledSystemLoadWrapper =
(flags & SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE) != 0;
if (isEnabledSystemLoadWrapper) {
addSystemLoadWrapperSoSource(context, soSources);
} else {
addSystemLibSoSource(soSources);

// We can only proceed forward if we have a Context. The prominent case
// where we don't have a Context is barebones dalvikvm instantiations. In
// that case, the caller is responsible for providing a correct LD_LIBRARY_PATH.

if (context != null) {
// Prepend our own SoSource for our own DSOs.

if ((flags & SOLOADER_ENABLE_EXOPACKAGE) != 0) {
// Even for an exopackage, there might be some native libraries
// packaged directly in the application (e.g. ASAN libraries alongside
// a wrap.sh script [1]), so make sure we can load them.
// [1] https://developer.android.com/ndk/guides/wrap-script
addApplicationSoSource(soSources, getApplicationSoSourceFlags());
LogUtil.d(TAG, "Adding exo package source: " + SO_STORE_NAME_MAIN);
soSources.add(0, new ExoSoSource(context, SO_STORE_NAME_MAIN));
} else {
if (SysUtil.isSupportedDirectLoad(context, sAppType)) {
addDirectApkSoSource(context, soSources);
}
addApplicationSoSource(soSources, getApplicationSoSourceFlags());
addBackupSoSource(context, soSources, BackupSoSource.PREFER_ANDROID_LIBS_DIRECTORY);
}
addApplicationSoSource(soSources, getApplicationSoSourceFlags());
addBackupSoSource(context, soSources, BackupSoSource.PREFER_ANDROID_LIBS_DIRECTORY);
}
}

Expand Down Expand Up @@ -511,6 +524,12 @@ private static void addSystemLibSoSource(ArrayList<SoSource> soSources) {
}
}

private static void addSystemLoadWrapperSoSource(Context context, ArrayList<SoSource> soSources) {
SystemLoadWrapperSoSource systemLoadWrapperSoSource = new SystemLoadWrapperSoSource();
LogUtil.d(TAG, "adding systemLoadWrapper source: " + systemLoadWrapperSoSource);
soSources.add(0, systemLoadWrapperSoSource);
}

private static int makePrepareFlags() {
int prepareFlags = 0;
// ensure the write lock is being held to protect sFlags
Expand Down
63 changes: 63 additions & 0 deletions java/com/facebook/soloader/SystemLoadWrapperSoSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.soloader;

import android.annotation.SuppressLint;
import android.os.StrictMode;
import java.io.File;
import java.io.IOException;
import javax.annotation.Nullable;

/**
* A {@link SoSource} that uses the system's {@code System.loadLibrary()} method to load a library
*/
public class SystemLoadWrapperSoSource extends SoSource {

@SuppressLint("CatchGeneralException")
@Override
public int loadLibrary(String soName, int loadFlags, StrictMode.ThreadPolicy threadPolicy)
throws IOException {
try {
System.loadLibrary(soName.substring("lib".length(), soName.length() - ".so".length()));
} catch (Exception e) {
LogUtil.e(SoLoader.TAG, "Error loading library: " + soName, e);
return LOAD_RESULT_NOT_FOUND;
}
return LOAD_RESULT_LOADED;
}

@Nullable
@Override
public File unpackLibrary(String soName) throws IOException {
return null;
}

@Override
public String getName() {
return "SystemLoadWrapperSoSource";
}

@Override
public String toString() {
return new StringBuilder()
.append(getName())
.append("[")
.append(SysUtil.getClassLoaderLdLoadLibrary())
.append("]")
.toString();
}
}

0 comments on commit 6984ea7

Please sign in to comment.