Commit 6a41878b authored by Torne (Richard Coles)'s avatar Torne (Richard Coles) Committed by Chromium LUCI CQ

android: make CrRendererMain's stack bigger.

On Android we create the renderer main thread from Java instead of using
the process's actual main thread (which is functioning as the Android
looper). This means that rather than the stack size being determined by
the kernel's defaults, it's determined by the JVM's defaults, which are
considerably smaller, and we overflow the stack in rare cases that work
on other platforms.

Use the stackSize parameter to the Java Thread constructor to request a
larger stack: 4MB in 32-bit processes and 8MB in 64-bit processes (to
match crrev.com/c/2490667 which set this for Windows). This parameter is
not required to be honoured by the JVM but ART on Android does use this
as a lower bound on the thread's stack size on all the Android versions
we care about.

Verified that this works by inspection of /proc/$pid/maps on ToT
Android, which gives names to the thread stack mappings that include the
tid (earlier versions of Android do not do this and there's no easy way
to tell how big non-main-thread stacks are).

Fixed: 1151869
Change-Id: I42e0bd987abc4f57a65e1c25436568eb51d8ac02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2625887
Auto-Submit: Richard Coles <torne@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845378}
parent f3c8d46f
......@@ -10,6 +10,7 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.Build;
import android.os.Process;
import android.preference.PreferenceManager;
......@@ -18,6 +19,7 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.compat.ApiHelperForM;
/**
* This class provides Android application context related utility methods.
......@@ -146,6 +148,18 @@ public class ContextUtils {
return ApiCompatibilityUtils.getProcessName();
}
/** @return Whether the current process is 64-bit. */
public static boolean isProcess64Bit() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ApiHelperForM.isProcess64Bit();
} else {
// Android sets CPU_ABI to the first supported ABI for the current process bitness
// (for compat reasons), so we can use this to infer our bitness.
return Build.SUPPORTED_64_BIT_ABIS.length > 0
&& Build.SUPPORTED_64_BIT_ABIS[0].equals(Build.CPU_ABI);
}
}
/**
* Extract the {@link Activity} if the given {@link Context} either is or wraps one.
*
......
......@@ -221,7 +221,13 @@ public class ChildProcessService {
mDelegate.onServiceCreated();
mMainThread = new Thread(new Runnable() {
// Unlike desktop Linux, on Android we leave the main looper thread to handle Android
// lifecycle events, and create a separate thread to serve as the main renderer. This
// affects the thread stack size: instead of getting the kernel default we get the Java
// default, which can be much smaller. So, explicitly set up a larger stack here.
long stackSize = ContextUtils.isProcess64Bit() ? 8 * 1024 * 1024 : 4 * 1024 * 1024;
mMainThread = new Thread(/*threadGroup=*/null, new Runnable() {
@Override
public void run() {
try {
......@@ -305,7 +311,7 @@ public class ChildProcessService {
}
ChildProcessServiceJni.get().exitChildProcess();
}
}, MAIN_THREAD_NAME);
}, MAIN_THREAD_NAME, stackSize);
mMainThread.start();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment