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

Commit a2934d5f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Cache AndroidBlockGuardPolicy to avoid allocation.

Every incoming Binder call ends up triggering a BlockGuardPolicy
update, which would thrash between new AndroidBlockGuardPolicy
instances and BlockGuard.LAX_POLICY, causing GC churn.

This change avoids the extra allocations by recycling a single
AndroidBlockGuardPolicy in a ThreadLocal.  Worst-case thrashing case
is now 10% faster; from 7.46us to 6.65us.

Bug: 9424568
Change-Id: I9c3b1c097a2aecc9b1f109a824cf3ea319fb3393
parent b28f8c82
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -783,13 +783,15 @@ public final class StrictMode {
            BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
            return;
        }
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask));
        final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        final AndroidBlockGuardPolicy androidPolicy;
        if (policy instanceof AndroidBlockGuardPolicy) {
            androidPolicy = (AndroidBlockGuardPolicy) policy;
        } else {
            AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy;
            androidPolicy.setPolicyMask(policyMask);
            androidPolicy = threadAndroidPolicy.get();
            BlockGuard.setThreadPolicy(androidPolicy);
        }
        androidPolicy.setPolicyMask(policyMask);
    }

    // Sets up CloseGuard in Dalvik/libcore
@@ -1060,6 +1062,14 @@ public final class StrictMode {
        }
    };

    private static final ThreadLocal<AndroidBlockGuardPolicy>
            threadAndroidPolicy = new ThreadLocal<AndroidBlockGuardPolicy>() {
        @Override
        protected AndroidBlockGuardPolicy initialValue() {
            return new AndroidBlockGuardPolicy(0);
        }
    };

    private static boolean tooManyViolationsThisLoop() {
        return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP;
    }
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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 android.os;

import android.os.StrictMode.ThreadPolicy;

import com.google.caliper.SimpleBenchmark;

public class StrictModeBenchmark extends SimpleBenchmark {

    private ThreadPolicy mOff = new ThreadPolicy.Builder().build();
    private ThreadPolicy mOn = new ThreadPolicy.Builder().detectAll().build();

    public void timeToggleThreadPolicy(int reps) {
        for (int i = 0; i < reps; i++) {
            StrictMode.setThreadPolicy(mOn);
            StrictMode.setThreadPolicy(mOff);
        }
    }
}