diff options
author | Makoto Onuki <omakoto@google.com> | 2020-06-02 14:40:10 -0700 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-12-08 17:55:56 +0200 |
commit | 21659a2683eed66e16aeafeb8d9c40916946a51b (patch) | |
tree | 6ed132e7f255dff70d217fabd3820ccf69420839 | |
parent | 1cf76752389fa8e38160db40eb922237b0a2001d (diff) |
[Metalava] don't use reflections
(The "merged-in" is to prevent it from getting merged into
qt-qpr1-dev-plus-aosp)
Bug: 151160048
Test: build
Test: Run metalava with verbose log
Merged-In: I802343a9ff189fcef00d8310c84302f355becc24
Change-Id: I5e0af5c807640c9c6ee5ec61489d65e13b6e4887
4 files changed, 32 insertions, 189 deletions
diff --git a/src/main/java/com/android/tools/metalava/CommandArgsPreprocessor.kt b/src/main/java/com/android/tools/metalava/CommandArgsPreprocessor.kt index 8325188..598c6ef 100644 --- a/src/main/java/com/android/tools/metalava/CommandArgsPreprocessor.kt +++ b/src/main/java/com/android/tools/metalava/CommandArgsPreprocessor.kt @@ -168,7 +168,7 @@ private fun generateRerunScript(stdout: PrintWriter, args: Array<String>) { // Metalava's jar path. val jar = ApiLint::class.java.protectionDomain?.codeSource?.location?.toURI()?.path // JVM options. - val jvmOptions = ManagementWrapper.getVmArguments() + val jvmOptions = runtimeMXBean.inputArguments if (jvmOptions == null || jar == null) { stdout.println("$PROGRAM_NAME unable to get my jar file path.") return diff --git a/src/main/java/com/android/tools/metalava/JavaManagement.kt b/src/main/java/com/android/tools/metalava/JavaManagement.kt new file mode 100644 index 0000000..c5d1a50 --- /dev/null +++ b/src/main/java/com/android/tools/metalava/JavaManagement.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 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.tools.metalava + +import java.lang.management.ManagementFactory + +/** Returns the [ThreadMXBean] singleton. */ +val threadMXBean = ManagementFactory.getThreadMXBean() + +/** Returns the [RuntimeMXBean] singleton. */ +val runtimeMXBean = ManagementFactory.getRuntimeMXBean() + +/** Returns the [ThreadMXBean] singleton. */ +val memoryMXBean = ManagementFactory.getMemoryMXBean() diff --git a/src/main/java/com/android/tools/metalava/ManagementWrapper.java b/src/main/java/com/android/tools/metalava/ManagementWrapper.java deleted file mode 100644 index 510181f..0000000 --- a/src/main/java/com/android/tools/metalava/ManagementWrapper.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2020 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.tools.metalava; - -import java.lang.reflect.Method; -import java.util.List; - -/** - * A collection of wrapper functions for java.lang.management APIs. Unfortunately we need to - * use reflections for them due to b/151224432. - * - * TODO(b/151224432) Resolve the device-side dependency and stop using reflections here. - * - * To avoid extra possible allocations around casts in kotlin, it's written in Java. - */ -final class ManagementWrapper { - private static Class<?>[] EMPTY_CLASSES = new Class[]{}; - private static Object[] EMPTY_ARGS = new Object[]{}; - - private static void onReflectionException(Exception e) { - throw new RuntimeException(e); - } - - private abstract static class Lazy<T> { - private boolean mInitialized; - private T mValue; - - abstract T init(); - - public T get() { - if (!mInitialized) { - mValue = init(); - mInitialized = true; - } - return mValue; - } - } - - private static class LazyClass extends Lazy<Class<?>> { - private final String mName; - - private LazyClass(String name) { - mName = name; - } - - @Override - Class<?> init() { - try { - return Class.forName(mName); - } catch (Exception e) { - onReflectionException(e); - return null; - } - } - } - - private static class LazyMethod<TV> extends Lazy<Method> { - private final LazyClass mClazz; - private final String mName; - private TV mCachedInvokeResult; - private TV mDefault; - - private LazyMethod(LazyClass clazz, String name) { - this(clazz, name, null); - } - - private LazyMethod(LazyClass clazz, String name, TV defaultValue) { - mClazz = clazz; - mName = name; - mDefault = defaultValue; - } - - @Override - Method init() { - try { - final Class<?> clazz = mClazz.get(); - final Method m = clazz.getMethod(mName, EMPTY_CLASSES); - m.setAccessible(true); - return m; - } catch (Exception e) { - onReflectionException(e); - return null; - } - } - - @SuppressWarnings("unchecked") - public TV invoke(Object target) { - try { - return (TV) get().invoke(target, EMPTY_ARGS); - } catch (Exception e) { - onReflectionException(e); - return mDefault; - } - } - - public TV invokeOnce(Object target) { - if (mCachedInvokeResult == null) { - mCachedInvokeResult = invoke(target); - } - return mCachedInvokeResult; - } - } - - private static LazyClass sFactoryClazz = new LazyClass("java.lang.management.ManagementFactory"); - private static LazyClass sThreadMxClazz = new LazyClass("java.lang.management.ThreadMXBean"); - private static LazyClass sRuntimeMxClazz = new LazyClass("java.lang.management.RuntimeMXBean"); - private static LazyClass sMemoryMxClazz = new LazyClass("java.lang.management.MemoryMXBean"); - private static LazyClass sMemoryUsageClazz = new LazyClass("java.lang.management.MemoryUsage"); - - private static LazyMethod<Object> sRuntimeMxGetter = new LazyMethod<>(sFactoryClazz, "getRuntimeMXBean"); - private static LazyMethod<Object> sThreadMxGetter = new LazyMethod<>(sFactoryClazz, "getThreadMXBean"); - private static LazyMethod<Object> sMemoryMxGetter = new LazyMethod<>(sFactoryClazz, "getMemoryMXBean"); - - // RuntimeMxBean functions - private static LazyMethod<List<String>> sGetInputArguments = new LazyMethod<>(sRuntimeMxClazz, "getInputArguments"); - - /** This corresponds to RuntimeMxBean.getInputArguments() */ - public static List<String> getVmArguments() { - return sGetInputArguments.invoke(sRuntimeMxGetter.invokeOnce(null)); - } - - // ThreadMxBean functions - private static LazyMethod<Long> sUserTime = new LazyMethod<>(sThreadMxClazz, "getCurrentThreadUserTime", 0L); - private static LazyMethod<Long> sCpuTime = new LazyMethod<>(sThreadMxClazz, "getCurrentThreadCpuTime", 0L); - - /** This corresponds to ThreadMxBean.getCurrentThreadUserTime() */ - public static long getUserTimeNano() { - return sUserTime.invoke(sThreadMxGetter.invokeOnce(null)); - } - - /** This corresponds to ThreadMxBean.getCurrentThreadCpuTime() */ - public static long getCpuTimeNano() { - return sCpuTime.invoke(sThreadMxGetter.invokeOnce(null)); - } - - // MemoryMxBean functions - - /** Corresponds to java.lang.management.MemoryUsage */ - public static final class MemoryUsage { - public final long init; - public final long used; - public final long committed; - public final long max; - - public MemoryUsage(long init, long used, long committed, long max) { - this.init = init; - this.used = used; - this.committed = committed; - this.max = max; - } - } - - // This returns a java.lang.management.MemoryUsage instance. - private static LazyMethod<Object> sGetHeapMemoryUsage = new LazyMethod<>(sMemoryMxClazz, "getHeapMemoryUsage"); - private static LazyMethod<Long> sGetInitMemory = new LazyMethod<>(sMemoryUsageClazz, "getInit", 0L); - private static LazyMethod<Long> sGetUsedMemory = new LazyMethod<>(sMemoryUsageClazz, "getUsed", 0L); - private static LazyMethod<Long> sGetCommittedMemory = new LazyMethod<>(sMemoryUsageClazz, "getCommitted", 0L); - private static LazyMethod<Long> sGetMaxMemory = new LazyMethod<>(sMemoryUsageClazz, "getMax", 0L); - - /** Corresponds to java.lang.management.MemoryUsage.getHeapMemoryUsage() */ - public static MemoryUsage getHeapUsage() { - final Object heapUsage = sGetHeapMemoryUsage.invoke(sMemoryMxGetter.invokeOnce(null)); - - return new MemoryUsage( - sGetInitMemory.invoke(heapUsage), - sGetUsedMemory.invoke(heapUsage), - sGetCommittedMemory.invoke(heapUsage), - sGetMaxMemory.invoke(heapUsage) - ); - } -} diff --git a/src/main/java/com/android/tools/metalava/Progress.kt b/src/main/java/com/android/tools/metalava/Progress.kt index ebb2fd9..9c461ea 100644 --- a/src/main/java/com/android/tools/metalava/Progress.kt +++ b/src/main/java/com/android/tools/metalava/Progress.kt @@ -56,8 +56,8 @@ private var lastCpuMillis: Long = -1L private fun getCpuStats(): String { val nowMillis = System.currentTimeMillis() - val userMillis = ManagementWrapper.getUserTimeNano() / 1000_000 - val cpuMillis = ManagementWrapper.getCpuTimeNano() / 1000_000 + val userMillis = threadMXBean.getCurrentThreadUserTime() / 1000_000 + val cpuMillis = threadMXBean.getCurrentThreadCpuTime() / 1000_000 if (lastMillis == -1L) { lastMillis = nowMillis @@ -86,7 +86,7 @@ private fun getCpuStats(): String { } private fun getMemoryStats(): String { - val mu = ManagementWrapper.getHeapUsage() + val mu = memoryMXBean.getHeapMemoryUsage() return String.format( "%dmi %dmu %dmc %dmx", |