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

Commit c9e7c10a authored by Hans Boehm's avatar Hans Boehm Committed by android-build-merger
Browse files

Merge "Only count uncleared ProxyMap refs when deciding to crash"

am: 90027eb1

Change-Id: I56471aa9ac0b93e3280b48fed3b29ad2b743cf39
parents a9d1e2a9 90027eb1
Loading
Loading
Loading
Loading
+38 −11
Original line number Diff line number Diff line
@@ -792,7 +792,7 @@ final class BinderProxy implements IBinder {
        /**
         * Return the total number of pairs in the map.
         */
        int size() {
        private int size() {
            int size = 0;
            for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
                if (a != null) {
@@ -802,6 +802,24 @@ final class BinderProxy implements IBinder {
            return size;
        }

        /**
         * Return the total number of pairs in the map containing values that have
         * not been cleared. More expensive than the above size function.
         */
        private int unclearedSize() {
            int size = 0;
            for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
                if (a != null) {
                    for (WeakReference<BinderProxy> ref : a) {
                        if (ref.get() != null) {
                            ++size;
                        }
                    }
                }
            }
            return size;
        }

        /**
         * Remove ith entry from the hash bucket indicated by hash.
         */
@@ -895,17 +913,31 @@ final class BinderProxy implements IBinder {
                Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
                        + " total = " + totalSize);
                mWarnBucketSize += WARN_INCREMENT;
                if (Build.IS_DEBUGGABLE && totalSize > CRASH_AT_SIZE) {
                    diagnosticCrash();
                if (Build.IS_DEBUGGABLE && totalSize >= CRASH_AT_SIZE) {
                    // Use the number of uncleared entries to determine whether we should
                    // really report a histogram and crash. We don't want to fundamentally
                    // change behavior for a debuggable process, so we GC only if we are
                    // about to crash.
                    final int totalUnclearedSize = unclearedSize();
                    if (totalUnclearedSize >= CRASH_AT_SIZE) {
                        dumpProxyInterfaceCounts();
                        Runtime.getRuntime().gc();
                        throw new AssertionError("Binder ProxyMap has too many entries: "
                                + totalSize + " (total), " + totalUnclearedSize + " (uncleared), "
                                + unclearedSize() + " (uncleared after GC). BinderProxy leak?");
                    } else if (totalSize > 3 * totalUnclearedSize / 2) {
                        Log.v(Binder.TAG, "BinderProxy map has many cleared entries: "
                                + (totalSize - totalUnclearedSize) + " of " + totalSize
                                + " are cleared");
                    }
                }
            }
        }

        /**
         * Dump a histogram to the logcat, then throw an assertion error. Used to diagnose
         * abnormally large proxy maps.
         * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps.
         */
        private void diagnosticCrash() {
        private void dumpProxyInterfaceCounts() {
            Map<String, Integer> counts = new HashMap<>();
            for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
                if (a != null) {
@@ -940,11 +972,6 @@ final class BinderProxy implements IBinder {
                Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i].getKey() + " x"
                        + sorted[i].getValue());
            }

            // Now throw an assertion.
            final int totalSize = size();
            throw new AssertionError("Binder ProxyMap has too many entries: " + totalSize
                    + ". BinderProxy leak?");
        }

        // Corresponding ArrayLists in the following two arrays always have the same size.