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

Commit c0c15eb5 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reduce unnecessary overhead of always-true predicate lambda

Currently compiler always generates new class as
$$ExternalSyntheticLambda* on every invocation place.
And a new instance will be always created on invocation no matter
whether the lambda is capturing arguments or not.

By using an explicit shared instance, it can reduce synthetic class
and method generation. Also reduce 4 instructions per invocation:
new-instance, invoke-direct, check-cast, invoke-static.

Bug: 163976519
Test: CtsWindowManagerDeviceActivity

Change-Id: I71a89713d64f0605faf6045ba44389a8eb47f3d5
parent b972663f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11109,7 +11109,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * Otherwise, return the creation time of the top window.
     */
    long getLastWindowCreateTime() {
        final WindowState window = getWindow(win -> true);
        final WindowState window = getWindow(alwaysTruePredicate());
        return window != null && window.mAttrs.type != TYPE_BASE_APPLICATION
                ? window.getCreateTime()
                : createTime;
+1 −1
Original line number Diff line number Diff line
@@ -2755,7 +2755,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    @Nullable
    Task getTopRootTask() {
        return getRootTask(t -> true);
        return getRootTask(alwaysTruePredicate());
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {

    @VisibleForTesting
    Task getTopRootTask() {
        return getRootTask(t -> true);
        return getRootTask(alwaysTruePredicate());
    }

    @Nullable
+15 −13
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ import com.android.internal.util.ToBooleanFunction;
import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import com.android.server.wm.utils.AlwaysTruePredicate;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -2019,29 +2020,34 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
                callback, boundary, includeBoundary, traverseTopToBottom, boundaryFound);
    }

    @SuppressWarnings("unchecked")
    static <T> Predicate<T> alwaysTruePredicate() {
        return (Predicate<T>) AlwaysTruePredicate.INSTANCE;
    }

    ActivityRecord getActivityAbove(ActivityRecord r) {
        return getActivity((above) -> true, r,
        return getActivity(alwaysTruePredicate(), r /* boundary */,
                false /*includeBoundary*/, false /*traverseTopToBottom*/);
    }

    ActivityRecord getActivityBelow(ActivityRecord r) {
        return getActivity((below) -> true, r,
        return getActivity(alwaysTruePredicate(), r /* boundary */,
                false /*includeBoundary*/, true /*traverseTopToBottom*/);
    }

    ActivityRecord getBottomMostActivity() {
        return getActivity((r) -> true, false /*traverseTopToBottom*/);
        return getActivity(alwaysTruePredicate(), false /* traverseTopToBottom */);
    }

    ActivityRecord getTopMostActivity() {
        return getActivity((r) -> true, true /*traverseTopToBottom*/);
        return getActivity(alwaysTruePredicate(), true /* traverseTopToBottom */);
    }

    ActivityRecord getTopActivity(boolean includeFinishing, boolean includeOverlays) {
        // Break down into 4 calls to avoid object creation due to capturing input params.
        if (includeFinishing) {
            if (includeOverlays) {
                return getActivity((r) -> true);
                return getActivity(alwaysTruePredicate());
            }
            return getActivity((r) -> !r.isTaskOverlay());
        } else if (includeOverlays) {
@@ -2220,21 +2226,17 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        }
    }

    Task getTaskAbove(Task t) {
        return getTask(
                (above) -> true, t, false /*includeBoundary*/, false /*traverseTopToBottom*/);
    }

    Task getTaskBelow(Task t) {
        return getTask((below) -> true, t, false /*includeBoundary*/, true /*traverseTopToBottom*/);
        return getTask(alwaysTruePredicate(), t /* boundary */,
                false /* includeBoundary */, true /* traverseTopToBottom */);
    }

    Task getBottomMostTask() {
        return getTask((t) -> true, false /*traverseTopToBottom*/);
        return getTask(alwaysTruePredicate(), false /* traverseTopToBottom */);
    }

    Task getTopMostTask() {
        return getTask((t) -> true, true /*traverseTopToBottom*/);
        return getTask(alwaysTruePredicate(), true /* traverseTopToBottom */);
    }

    Task getTask(Predicate<Task> callback) {
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.server.wm.utils;

import java.util.function.Predicate;

/** A simple Predicate to avoid synthetic allocation of lambda expression "o -> true". */
public class AlwaysTruePredicate implements Predicate<Object> {

    public static final AlwaysTruePredicate INSTANCE = new AlwaysTruePredicate();

    private AlwaysTruePredicate() {
    }

    @Override
    public boolean test(Object o) {
        return true;
    }
}