Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 703e5d3c authored by Brad Fitzpatrick's avatar Brad Fitzpatrick
Browse files

StrictMode: avoid an allocation in common case

Make the initialValue() of the ThreadLocal be null, so checking it doesn't
cause one to be created in the case of an RPC call not using StrictMode.

Change-Id: I3ea19ce444a1b3c39a6e53c5cb5d4faf4b07a6c8
parent 0c36c96f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1202,6 +1202,7 @@ public final class Parcel {
            code = EX_ILLEGAL_STATE;
        }
        writeInt(code);
        StrictMode.clearGatheredViolations();
        if (code == 0) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
+30 −9
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ public final class StrictMode {
     * our offending stack traces to the caller to ultimately handle
     * in the originating process.
     *
     * This must be kept in sync with the constant in libs/binder/Parcel.cpp
     *
     * @hide
     */
    public static final int PENALTY_GATHER = 0x100;
@@ -98,7 +100,10 @@ public final class StrictMode {
    private static ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>> gatheredViolations =
            new ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>>() {
        @Override protected ArrayList<ApplicationErrorReport.CrashInfo> initialValue() {
            return new ArrayList<ApplicationErrorReport.CrashInfo>(1);
            // Starts null to avoid unnecessary allocations when
            // checking whether there are any violations or not in
            // hasGatheredViolations() below.
            return null;
        }
    };

@@ -308,7 +313,10 @@ public final class StrictMode {

            if ((policy & PENALTY_GATHER) != 0) {
                ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get();
                if (violations.size() >= 5) {
                if (violations == null) {
                    violations = new ArrayList<ApplicationErrorReport.CrashInfo>(1);
                    gatheredViolations.set(violations);
                } else if (violations.size() >= 5) {
                    // Too many.  In a loop or something?  Don't gather them all.
                    return;
                }
@@ -393,7 +401,16 @@ public final class StrictMode {
     * Called from Parcel.writeNoException()
     */
    /* package */ static boolean hasGatheredViolations() {
        return !gatheredViolations.get().isEmpty();
        return gatheredViolations.get() != null;
    }

    /**
     * Called from Parcel.writeException(), so we drop this memory and
     * don't incorrectly attribute it to the wrong caller on the next
     * Binder call on this thread.
     */
    /* package */ static void clearGatheredViolations() {
        gatheredViolations.set(null);
    }

    /**
@@ -401,13 +418,17 @@ public final class StrictMode {
     */
    /* package */ static void writeGatheredViolationsToParcel(Parcel p) {
        ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get();
        if (violations == null) {
            p.writeInt(0);
        } else {
            p.writeInt(violations.size());
            for (int i = 0; i < violations.size(); ++i) {
                violations.get(i).writeToParcel(p, 0 /* unused flags? */);
            }

            if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size());
        violations.clear();
            violations.clear(); // somewhat redundant, as we're about to null the threadlocal
        }
        gatheredViolations.set(null);
    }

    private static class LogStackTrace extends Exception {}