1 /* Verify that libffi closures aren't deallocated too early. 2 3 Copyright (C) 2007 Free Software Foundation, Inc 4 Contributed by Alexandre Oliva <aoliva@redhat.com> 5 6 If libffi closures are released too early, we lose. 7 */ 8 9 import java.util.HashSet; 10 11 public class TestClosureGC { objId(Object obj)12 public static String objId (Object obj) { 13 return obj + "/" 14 + Integer.toHexString(obj.getClass().getClassLoader().hashCode()); 15 } 16 public static class cld extends java.net.URLClassLoader { 17 static final Object obj = new cl0(); cld()18 public cld () throws Exception { 19 super(new java.net.URL[] { }); 20 /* System.out.println (objId (this) + " created"); */ 21 } finalize()22 public void finalize () { 23 /* System.out.println (objId (this) + " finalized"); */ 24 } toString()25 public String toString () { 26 return this.getClass().getName() + "@" 27 + Integer.toHexString (hashCode ()); 28 } loadClass(String name)29 public Class loadClass (String name) throws ClassNotFoundException { 30 try { 31 java.io.InputStream IS = getSystemResourceAsStream 32 (name + ".class"); 33 int maxsz = 1024, readsz = 0; 34 byte buf[] = new byte[maxsz]; 35 for(;;) { 36 int readnow = IS.read (buf, readsz, maxsz - readsz); 37 if (readnow <= 0) 38 break; 39 readsz += readnow; 40 if (readsz == maxsz) { 41 byte newbuf[] = new byte[maxsz *= 2]; 42 System.arraycopy (buf, 0, newbuf, 0, readsz); 43 buf = newbuf; 44 } 45 } 46 return defineClass (name, buf, 0, readsz); 47 } catch (Exception e) { 48 return super.loadClass (name); 49 } 50 } 51 } 52 public static class cl0 { cl0()53 public cl0 () { 54 /* System.out.println (objId (this) + " created"); */ 55 } finalize()56 public void finalize () { 57 /* System.out.println (objId (this) + " finalized"); */ 58 } 59 } 60 public static class cl1 { 61 final HashSet hs; 62 static final Object obj = new cl0(); cl1(final HashSet hs)63 public cl1 (final HashSet hs) { 64 this.hs = hs; 65 /* System.out.println (objId (this) + " created"); */ 66 } finalize()67 public void finalize () { 68 /* System.out.println (objId (this) + " finalized"); */ 69 } 70 } 71 public static class cl2 { 72 final HashSet hs; 73 static final Object obj = new cl0(); cl2(final HashSet hs)74 public cl2 (final HashSet hs) { 75 this.hs = hs; 76 /* System.out.println (objId (this) + " created"); */ 77 } finalize()78 public void finalize () { 79 /* System.out.println (objId (this) + " finalized"); */ 80 hs.add(this); 81 hs.add(new cl0()); 82 } 83 } 84 static final HashSet hs = new HashSet(); 85 static final Object obj = new cl0(); main(String[] argv)86 public static void main(String[] argv) throws Exception { 87 { 88 Class[] hscs = { HashSet.class }; 89 Object[] hsos = { hs }; 90 new cld().loadClass ("TestClosureGC$cl1"). 91 getConstructor (hscs).newInstance (hsos); 92 new cld().loadClass ("TestClosureGC$cl2"). 93 getConstructor (hscs).newInstance (hsos); 94 new cld().loadClass ("TestClosureGC$cl1"). 95 getConstructor (hscs).newInstance (hsos); 96 new cld().loadClass ("TestClosureGC$cl1"). 97 getConstructor (hscs).newInstance (hsos); 98 } 99 for (int i = 1; i <= 5; i++) { 100 /* System.out.println ("Will run GC and finalization " + i); */ 101 System.gc (); 102 Thread.sleep (100); 103 System.runFinalization (); 104 Thread.sleep (100); 105 if (hs.isEmpty ()) 106 continue; 107 java.util.Iterator it = hs.iterator (); 108 while (it.hasNext ()) { 109 Object obj = it.next(); 110 /* System.out.println (objId (obj) + " in ht, removing"); */ 111 it.remove (); 112 } 113 } 114 System.out.println ("ok"); 115 } 116 } 117