Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/test/626-const-class-linking/src/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 13 kB image not shown  

Quelle  Main.java

  Sprache: JAVA
 

/*
 * Copyright (C) 2016 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.
 */


import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) throws Exception {
        try {
            // Check if we're running dalvik or RI.
            Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader");
            System.loadLibrary(args[0]);
        } catch (ClassNotFoundException e) {
            usingRI = true;
            // Add expected JNI_OnLoad log line to match expected-stdout.txt.
            System.out.println("JNI_OnLoad called");
        }

        testClearDexCache();
        testMultiDex();
        testRacyLoader();
        testRacyLoader2();
        testMisbehavingLoader();
        testRacyMisbehavingLoader();
        testRacyMisbehavingLoader2();
    }

    private static void testClearDexCache() throws Exception {
        DelegatingLoader delegating_loader = createDelegatingLoader();
        Class<?> helper = delegating_loader.loadClass("Helper1");

        WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper);
        changeInner(delegating_loader);
        clearResolvedTypes(helper);
        Runtime.getRuntime().gc();
        WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper);
        Runtime.getRuntime().gc();

        Class<?> test1 = weak_test1.get();
        if (test1 == null) {
            System.out.println("test1 disappeared");
        }
        Class<?> test2 = weak_test2.get();
        if (test2 == null) {
            System.out.println("test2 disappeared");
        }
        if (test1 != test2) {
            System.out.println("test1 != test2");
        }

        System.out.println("testClearDexCache done");
    }

    private static void testMultiDex() throws Exception {
        DelegatingLoader delegating_loader = createDelegatingLoader();

        Class<?> helper1 = delegating_loader.loadClass("Helper1");
        WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper1);

        changeInner(delegating_loader);

        Class<?> helper2 = delegating_loader.loadClass("Helper2");
        WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper2);

        Runtime.getRuntime().gc();

        Class<?> test1 = weak_test1.get();
        if (test1 == null) {
            System.out.println("test1 disappeared");
        }
        Class<?> test2 = weak_test2.get();
        if (test2 == null) {
            System.out.println("test2 disappeared");
        }
        if (test1 != test2) {
            System.out.println("test1 != test2");
        }

        System.out.println("testMultiDex done");
    }

    private static void testMisbehavingLoader() throws Exception {
        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
        DefiningLoader defining_loader = new DefiningLoader(system_loader);
        MisbehavingLoader misbehaving_loader =
            new MisbehavingLoader(system_loader, defining_loader);
        Class<?> helper = misbehaving_loader.loadClass("Helper1");

        try {
            WeakReference<Class<?>> weak_test = wrapHelperGet(helper);
        } catch (InvocationTargetException ite) {
            String message = ite.getCause().getMessage();
            if (usingRI && "Test".equals(message)) {
              // Replace RI message with dalvik message to match expected-stdout.txt.
              message = "Initiating class loader of type " +
                  misbehaving_loader.getClass().getName() +
                  " returned class Helper2 instead of Test.";
            }
            System.out.println(ite.getCause().getClass().getName() + ": " + message);
        }
        System.out.println("testMisbehavingLoader done");
    }

    private static void testRacyLoader() throws Exception {
        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();

        final Thread[] threads = new Thread[4];
        final Object[] results = new Object[threads.length];

        final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
        final Class<?> helper1 = racy_loader.loadClass("Helper1");
        skipVerification(helper1);  // Avoid class loading during verification.

        for (int i = 0; i != threads.length; ++i) {
            final int my_index = i;
            Thread t = new Thread() {
                public void run() {
                    try {
                        Method get = helper1.getDeclaredMethod("get");
                        results[my_index] = get.invoke(null);
                    } catch (InvocationTargetException ite) {
                        results[my_index] = ite.getCause();
                    } catch (Throwable t) {
                        results[my_index] = t;
                    }
                }
            };
            t.start();
            threads[i] = t;
        }
        for (Thread t : threads) {
            t.join();
        }
        dumpResultStats(results, 1);
        System.out.println("testRacyLoader done");
    }

    private static void testRacyLoader2() throws Exception {
        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();

        final Thread[] threads = new Thread[4];
        final Object[] results = new Object[threads.length];

        final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
        final Class<?> helper1 = racy_loader.loadClass("Helper1");
        skipVerification(helper1);  // Avoid class loading during verification.
        final Class<?> helper3 = racy_loader.loadClass("Helper3");
        skipVerification(helper3);  // Avoid class loading during verification.

        for (int i = 0; i != threads.length; ++i) {
            final int my_index = i;
            Thread t = new Thread() {
                public void run() {
                    try {
                        Class<?> helper = (my_index < threads.length / 2) ? helper1 : helper3;
                        Method get = helper.getDeclaredMethod("get");
                        results[my_index] = get.invoke(null);
                    } catch (InvocationTargetException ite) {
                        results[my_index] = ite.getCause();
                    } catch (Throwable t) {
                        results[my_index] = t;
                    }
                }
            };
            t.start();
            threads[i] = t;
        }
        for (Thread t : threads) {
            t.join();
        }
        dumpResultStats(results, 2);
        System.out.println("testRacyLoader2 done");
    }

    private static void testRacyMisbehavingLoader() throws Exception {
        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();

        final Thread[] threads = new Thread[4];
        final Object[] results = new Object[threads.length];

        final RacyMisbehavingLoader racy_loader =
            new RacyMisbehavingLoader(system_loader, threads.length, false);
        final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
        skipVerification(helper1);  // Avoid class loading during verification.

        for (int i = 0; i != threads.length; ++i) {
            final int my_index = i;
            Thread t = new Thread() {
                public void run() {
                    try {
                        Method get = helper1.getDeclaredMethod("get");
                        results[my_index] = get.invoke(null);
                    } catch (InvocationTargetException ite) {
                        results[my_index] = ite.getCause();
                    } catch (Throwable t) {
                        results[my_index] = t;
                    }
                }
            };
            t.start();
            threads[i] = t;
        }
        for (Thread t : threads) {
            t.join();
        }
        dumpResultStats(results, 1);
        System.out.println("testRacyMisbehavingLoader done");
    }

    private static void testRacyMisbehavingLoader2() throws Exception {
        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();

        final Thread[] threads = new Thread[4];
        final Object[] results = new Object[threads.length];

        final RacyMisbehavingLoader racy_loader =
            new RacyMisbehavingLoader(system_loader, threads.length, true);
        final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
        skipVerification(helper1);  // Avoid class loading during verification.

        for (int i = 0; i != threads.length; ++i) {
            final int my_index = i;
            Thread t = new Thread() {
                public void run() {
                    try {
                        Method get = helper1.getDeclaredMethod("get");
                        results[my_index] = get.invoke(null);
                    } catch (InvocationTargetException ite) {
                        results[my_index] = ite.getCause();
                    } catch (Throwable t) {
                        results[my_index] = t;
                    }
                }
            };
            t.start();
            threads[i] = t;
        }
        for (Thread t : threads) {
            t.join();
        }
        dumpResultStats(results, 1);
        System.out.println("testRacyMisbehavingLoader2 done");
    }

    private static void dumpResultStats(Object[] results, int expected_unique) throws Exception {
        int throwables = 0;
        int classes = 0;
        int unique_classes = 0;
        for (int i = 0; i != results.length; ++i) {
            Object r = results[i];
            if (r instanceof Throwable) {
                ++throwables;
                System.out.println(((Throwable) r).getMessage());
            } else if (isClassPair(r)) {
                printPair(r);
                Object ref = getSecond(r);
                ++classes;
                ++unique_classes;
                for (int j = 0; j != i; ++j) {
                    Object rj = results[j];
                    if (isClassPair(results[j]) && getSecond(results[j]) == ref) {
                        --unique_classes;
                        break;
                    }
                }
            }
        }
        System.out.println("total: " + results.length);
        System.out.println("  throwables: " + throwables);
        System.out.println("  classes: " + classes
            + " (" + unique_classes + " unique)");
        if (expected_unique != unique_classes) {
            System.out.println("MISMATCH with expected_unique: " + expected_unique);
            ArrayList<Class<?>> list = new ArrayList<Class<?>>();
            for (int i = 0; i != results.length; ++i) {
                Object r = results[i];
                if (isClassPair(r)) {
                    list.add(getSecond(r));
                }
            }
            nativeDumpClasses(list.toArray());
        }
    }

    private static DelegatingLoader createDelegatingLoader() {
        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
        DefiningLoader defining_loader = new DefiningLoader(system_loader);
        return new DelegatingLoader(system_loader, defining_loader);
    }

    private static void changeInner(DelegatingLoader delegating_loader) {
        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
        DefiningLoader defining_loader = new DefiningLoader(system_loader);
        delegating_loader.resetDefiningLoader(defining_loader);
    }

    private static WeakReference<Class<?>> wrapHelperGet(Class<?> helper) throws Exception {
        Method get = helper.getDeclaredMethod("get");
        Object pair = get.invoke(null);
        printPair(pair);
        return new WeakReference<Class<?>>(getSecond(pair));
    }

    private static void printPair(Object pair) throws Exception {
        Method print = pair.getClass().getDeclaredMethod("print");
        print.invoke(pair);
    }

    private static Class<?> getSecond(Object pair) throws Exception {
        Field second = pair.getClass().getDeclaredField("second");
        return (Class<?>) second.get(pair);
    }

    private static boolean isClassPair(Object r) {
        return r != null && r.getClass().getName().equals("ClassPair");
    }

    public static void clearResolvedTypes(Class<?> c) {
        if (!usingRI) {
            nativeClearResolvedTypes(c);
        }
    }

    // Skip verification of a class on ART. Verification can cause classes to be loaded
    // while holding a lock on the class being verified and holding that lock can interfere
    // with the intent of the "racy" tests. In these tests we're waiting in the loadClass()
    // for all the tested threads to synchronize and they cannot reach that point if they
    // are waiting for the class lock on ClassLinker::InitializeClass(Helper1/Helper3).
    public static void skipVerification(Class<?> c) {
        if (!usingRI) {
            nativeSkipVerification(c);
        }
    }

    public static native void nativeClearResolvedTypes(Class<?> c);
    public static native void nativeSkipVerification(Class<?> c);
    public static native void nativeDumpClasses(Object[] array);

    static boolean usingRI = false;
}

Messung V0.5 in Prozent
C=82 H=94 G=88

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.