/*
 * Copyright (C) 2009 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;

public class Main {
    public static void main(String[] args) {
        staleStackTest();
    }

    public static void staleStackTest() {
        WeakReference wrefs[] = new WeakReference[10];

        populate(wrefs);

        check(wrefs);
    }

    static void populate(WeakReference[] wrefs) {
        /*
         * Get a bunch of non-constant String objects into registers.  These
         * should be the first locals declared.
         */
        String str0 = generateString("String", 0);
        String str1 = generateString("String", 1);
        String str2 = generateString("String", 2);
        String str3 = generateString("String", 3);
        String str4 = generateString("String", 4);
        String str5 = generateString("String", 5);
        String str6 = generateString("String", 6);
        String str7 = generateString("String", 7);
        String str8 = generateString("String", 8);
        String str9 = generateString("String", 9);

        /* stuff them into the weak references array */
        wrefs[0] = new WeakReference(str0);
        wrefs[1] = new WeakReference(str1);
        wrefs[2] = new WeakReference(str2);
        wrefs[3] = new WeakReference(str3);
        wrefs[4] = new WeakReference(str4);
        wrefs[5] = new WeakReference(str5);
        wrefs[6] = new WeakReference(str6);
        wrefs[7] = new WeakReference(str7);
        wrefs[8] = new WeakReference(str8);
        wrefs[9] = new WeakReference(str9);
    }

    static String generateString(String base, int num) {
        return base + num;
    }

    static void check(WeakReference[] wrefs) {
        /*
         * Declare locals so that our stack overlaps the same region
         * that populate() did.
         */
        String str0;
        String str1;
        String str2;
        String str3;
        String str4;
        String str5;
        String str6;
        String str7;
        String str8;
        String str9;
        int numValid = 0;

        /*
         * This *should* blow out all the weakly-reference objects.  If
         * we still have stale copies of references on the stack, a
         * conservative GC will try to hold on to those objects and the
         * count will be nonzero.
         *
         * Getting a zero result here isn't conclusive, but it's a strong
         * indicator that precise GC is having an impact.
         */
        Runtime.getRuntime().gc();

        for (int i = 0; i < wrefs.length; i++) {
            if (wrefs[i].get() != null)
                numValid++;
        }

        System.out.println("Valid refs: " + numValid);

        /* use the locals in case the compiler gets smart */
        str0 = generateString("String", 0);
        str1 = generateString("String", 1);
        str2 = generateString("String", 2);
        str3 = generateString("String", 3);
        str4 = generateString("String", 4);
        str5 = generateString("String", 5);
        str6 = generateString("String", 6);
        str7 = generateString("String", 7);
        str8 = generateString("String", 8);
        str9 = generateString("String", 9);
        System.out.println(str0+str1+str2+str3+str4+str5+str6+str7+str8+str9);
    }
}
