1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package gc.gctests.PhantomReference; 24 25 import java.lang.ref.ReferenceQueue; 26 import java.util.Date; 27 import java.util.HashMap; 28 29 /** 30 * Helper class that tracks the original hash code for the 31 * object. 32 */ 33 public final class PhantomHelper { 34 35 private int originalHashCode; 36 private int hashCounter; 37 38 /** 39 * Constructor for helper class that tracks the hash code. 40 * 41 * @param originalHashCode Referred objects hash code 42 */ PhantomHelper(int originalHashCode)43 public PhantomHelper(int originalHashCode) { 44 this.originalHashCode = originalHashCode; 45 hashCounter = 1; 46 } 47 48 /** 49 * Get the referred objects original hash code. 50 * 51 * @return Original referred objects hash code 52 */ getOriginalHashCode()53 public int getOriginalHashCode() { 54 return originalHashCode; 55 } 56 57 /** 58 * Increase the counter for the number of objects 59 * using this hash code. 60 */ increaseHashCounter()61 public void increaseHashCounter() { 62 hashCounter++; 63 } 64 65 /** 66 * Decrease the counter for the number of objects 67 * using this hash code. 68 */ decreaseHashCounter()69 public void decreaseHashCounter() { 70 hashCounter--; 71 } 72 73 /** 74 * Retreive the hash code counter. 75 * 76 * @return Hash code counter value 77 */ getHashCounter()78 public int getHashCounter() { 79 return hashCounter; 80 } 81 82 /** 83 * Verify all the hash codes from the objects in the reference 84 * queue against the hash map. 85 * 86 * @param rq Reference queue for the phantom references. 87 * @param hmHelper Hashmap that contains all the hash codes 88 * @param maxWaitTime Maximum time to wait for completion of deref:ing 89 * from the reference queue. 90 * @return True if all hash codes matches 91 */ checkAllHashCodes(ReferenceQueue rq, HashMap hmHelper, long maxWaitTime)92 public static final String checkAllHashCodes(ReferenceQueue rq, 93 HashMap hmHelper, 94 long maxWaitTime) { 95 // Check all the phantom references 96 long startTime = new Date().getTime(); 97 boolean keepRunning = true; 98 99 while (keepRunning) { 100 try { 101 PRHelper prh = (PRHelper) rq.remove(1000); 102 103 if (prh != null) { 104 Integer ik = new Integer(prh.getReferentHashCode()); 105 PhantomHelper ph = (PhantomHelper) hmHelper.get(ik); 106 107 if (ph != null) { 108 if (ph.getOriginalHashCode() 109 == prh.getReferentHashCode()) { 110 ph.decreaseHashCounter(); 111 if (ph.getHashCounter() == 0) { 112 hmHelper.remove( 113 new Integer(prh.getReferentHashCode())); 114 } else { 115 hmHelper.put(ik, ph); 116 } 117 prh.clear(); 118 } 119 } else { 120 return "Unmapped hash code detected. The test is faulty."; 121 } 122 123 prh = null; 124 } 125 } catch (InterruptedException e) { 126 ; // Checkstyle wants at least one line here... 127 } 128 129 if (new Date().getTime() - startTime > maxWaitTime) { 130 return "All phantom references weren't processed " 131 + "in the configured max time (" 132 + (maxWaitTime / 1000) + " secs)"; 133 } 134 135 if (hmHelper.size() == 0) { 136 keepRunning = false; 137 } 138 } 139 140 return null; 141 } 142 } 143