content: /*
   * 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);
      }
  }
  