1 /* 2 * Copyright (c) 2010, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang; 27 28 import java.util.WeakHashMap; 29 import java.lang.ref.WeakReference; 30 import java.util.concurrent.atomic.AtomicInteger; 31 32 import jdk.internal.misc.Unsafe; 33 34 import static java.lang.ClassValue.ClassValueMap.probeHomeLocation; 35 import static java.lang.ClassValue.ClassValueMap.probeBackupLocations; 36 37 /** 38 * Lazily associate a computed value with (potentially) every type. 39 * For example, if a dynamic language needs to construct a message dispatch 40 * table for each class encountered at a message send call site, 41 * it can use a {@code ClassValue} to cache information needed to 42 * perform the message send quickly, for each class encountered. 43 * @author John Rose, JSR 292 EG 44 * @since 1.7 45 */ 46 public abstract class ClassValue<T> { 47 /** 48 * Sole constructor. (For invocation by subclass constructors, typically 49 * implicit.) 50 */ ClassValue()51 protected ClassValue() { 52 } 53 54 /** 55 * Computes the given class's derived value for this {@code ClassValue}. 56 * <p> 57 * This method will be invoked within the first thread that accesses 58 * the value with the {@link #get get} method. 59 * <p> 60 * Normally, this method is invoked at most once per class, 61 * but it may be invoked again if there has been a call to 62 * {@link #remove remove}. 63 * <p> 64 * If this method throws an exception, the corresponding call to {@code get} 65 * will terminate abnormally with that exception, and no class value will be recorded. 66 * 67 * @param type the type whose class value must be computed 68 * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface 69 * @see #get 70 * @see #remove 71 */ computeValue(Class<?> type)72 protected abstract T computeValue(Class<?> type); 73 74 /** 75 * Returns the value for the given class. 76 * If no value has yet been computed, it is obtained by 77 * an invocation of the {@link #computeValue computeValue} method. 78 * <p> 79 * The actual installation of the value on the class 80 * is performed atomically. 81 * At that point, if several racing threads have 82 * computed values, one is chosen, and returned to 83 * all the racing threads. 84 * <p> 85 * The {@code type} parameter is typically a class, but it may be any type, 86 * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}. 87 * <p> 88 * In the absence of {@code remove} calls, a class value has a simple 89 * state diagram: uninitialized and initialized. 90 * When {@code remove} calls are made, 91 * the rules for value observation are more complex. 92 * See the documentation for {@link #remove remove} for more information. 93 * 94 * @param type the type whose class value must be computed or retrieved 95 * @return the current value associated with this {@code ClassValue}, for the given class or interface 96 * @throws NullPointerException if the argument is null 97 * @see #remove 98 * @see #computeValue 99 */ get(Class<?> type)100 public T get(Class<?> type) { 101 // non-racing this.hashCodeForCache : final int 102 Entry<?>[] cache; 103 Entry<T> e = probeHomeLocation(cache = getCacheCarefully(type), this); 104 // racing e : current value <=> stale value from current cache or from stale cache 105 // invariant: e is null or an Entry with readable Entry.version and Entry.value 106 if (match(e)) 107 // invariant: No false positive matches. False negatives are OK if rare. 108 // The key fact that makes this work: if this.version == e.version, 109 // then this thread has a right to observe (final) e.value. 110 return e.value(); 111 // The fast path can fail for any of these reasons: 112 // 1. no entry has been computed yet 113 // 2. hash code collision (before or after reduction mod cache.length) 114 // 3. an entry has been removed (either on this type or another) 115 // 4. the GC has somehow managed to delete e.version and clear the reference 116 return getFromBackup(cache, type); 117 } 118 119 /** 120 * Removes the associated value for the given class. 121 * If this value is subsequently {@linkplain #get read} for the same class, 122 * its value will be reinitialized by invoking its {@link #computeValue computeValue} method. 123 * This may result in an additional invocation of the 124 * {@code computeValue} method for the given class. 125 * <p> 126 * In order to explain the interaction between {@code get} and {@code remove} calls, 127 * we must model the state transitions of a class value to take into account 128 * the alternation between uninitialized and initialized states. 129 * To do this, number these states sequentially from zero, and note that 130 * uninitialized (or removed) states are numbered with even numbers, 131 * while initialized (or re-initialized) states have odd numbers. 132 * <p> 133 * When a thread {@code T} removes a class value in state {@code 2N}, 134 * nothing happens, since the class value is already uninitialized. 135 * Otherwise, the state is advanced atomically to {@code 2N+1}. 136 * <p> 137 * When a thread {@code T} queries a class value in state {@code 2N}, 138 * the thread first attempts to initialize the class value to state {@code 2N+1} 139 * by invoking {@code computeValue} and installing the resulting value. 140 * <p> 141 * When {@code T} attempts to install the newly computed value, 142 * if the state is still at {@code 2N}, the class value will be initialized 143 * with the computed value, advancing it to state {@code 2N+1}. 144 * <p> 145 * Otherwise, whether the new state is even or odd, 146 * {@code T} will discard the newly computed value 147 * and retry the {@code get} operation. 148 * <p> 149 * Discarding and retrying is an important proviso, 150 * since otherwise {@code T} could potentially install 151 * a disastrously stale value. For example: 152 * <ul> 153 * <li>{@code T} calls {@code CV.get(C)} and sees state {@code 2N} 154 * <li>{@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it 155 * <li>{@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time 156 * <li>...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N} 157 * <li>{@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)} 158 * <li>{@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work 159 * <li> the previous actions of {@code T2} are repeated several times 160 * <li> also, the relevant computed values change over time: {@code V1}, {@code V2}, ... 161 * <li>...meanwhile, {@code T} wakes up and attempts to install {@code V0}; <em>this must fail</em> 162 * </ul> 163 * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly 164 * observe the time-dependent states as it computes {@code V1}, etc. 165 * This does not remove the threat of a stale value, since there is a window of time 166 * between the return of {@code computeValue} in {@code T} and the installation 167 * of the new value. No user synchronization is possible during this time. 168 * 169 * @param type the type whose class value must be removed 170 * @throws NullPointerException if the argument is null 171 */ remove(Class<?> type)172 public void remove(Class<?> type) { 173 ClassValueMap map = getMap(type); 174 map.removeEntry(this); 175 } 176 177 // Possible functionality for JSR 292 MR 1 put(Class<?> type, T value)178 /*public*/ void put(Class<?> type, T value) { 179 ClassValueMap map = getMap(type); 180 map.changeEntry(this, value); 181 } 182 183 /// -------- 184 /// Implementation... 185 /// -------- 186 187 /** Return the cache, if it exists, else a dummy empty cache. */ getCacheCarefully(Class<?> type)188 private static Entry<?>[] getCacheCarefully(Class<?> type) { 189 // racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y] 190 ClassValueMap map = type.classValueMap; 191 if (map == null) return EMPTY_CACHE; 192 Entry<?>[] cache = map.getCache(); 193 return cache; 194 // invariant: returned value is safe to dereference and check for an Entry 195 } 196 197 /** Initial, one-element, empty cache used by all Class instances. Must never be filled. */ 198 private static final Entry<?>[] EMPTY_CACHE = { null }; 199 200 /** 201 * Slow tail of ClassValue.get to retry at nearby locations in the cache, 202 * or take a slow lock and check the hash table. 203 * Called only if the first probe was empty or a collision. 204 * This is a separate method, so compilers can process it independently. 205 */ getFromBackup(Entry<?>[] cache, Class<?> type)206 private T getFromBackup(Entry<?>[] cache, Class<?> type) { 207 Entry<T> e = probeBackupLocations(cache, this); 208 if (e != null) 209 return e.value(); 210 return getFromHashMap(type); 211 } 212 213 // Hack to suppress warnings on the (T) cast, which is a no-op. 214 @SuppressWarnings("unchecked") castEntry(Entry<?> e)215 Entry<T> castEntry(Entry<?> e) { return (Entry<T>) e; } 216 217 /** Called when the fast path of get fails, and cache reprobe also fails. 218 */ getFromHashMap(Class<?> type)219 private T getFromHashMap(Class<?> type) { 220 // The fail-safe recovery is to fall back to the underlying classValueMap. 221 ClassValueMap map = getMap(type); 222 for (;;) { 223 Entry<T> e = map.startEntry(this); 224 if (!e.isPromise()) 225 return e.value(); 226 try { 227 // Try to make a real entry for the promised version. 228 e = makeEntry(e.version(), computeValue(type)); 229 } finally { 230 // Whether computeValue throws or returns normally, 231 // be sure to remove the empty entry. 232 e = map.finishEntry(this, e); 233 } 234 if (e != null) 235 return e.value(); 236 // else try again, in case a racing thread called remove (so e == null) 237 } 238 } 239 240 /** Check that e is non-null, matches this ClassValue, and is live. */ match(Entry<?> e)241 boolean match(Entry<?> e) { 242 // racing e.version : null (blank) => unique Version token => null (GC-ed version) 243 // non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile) 244 return (e != null && e.get() == this.version); 245 // invariant: No false positives on version match. Null is OK for false negative. 246 // invariant: If version matches, then e.value is readable (final set in Entry.<init>) 247 } 248 249 /** Internal hash code for accessing Class.classValueMap.cacheArray. */ 250 final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK; 251 252 /** Value stream for hashCodeForCache. See similar structure in ThreadLocal. */ 253 private static final AtomicInteger nextHashCode = new AtomicInteger(); 254 255 /** Good for power-of-two tables. See similar structure in ThreadLocal. */ 256 private static final int HASH_INCREMENT = 0x61c88647; 257 258 /** Mask a hash code to be positive but not too large, to prevent wraparound. */ 259 static final int HASH_MASK = (-1 >>> 2); 260 261 /** 262 * Private key for retrieval of this object from ClassValueMap. 263 */ 264 static class Identity { 265 } 266 /** 267 * This ClassValue's identity, expressed as an opaque object. 268 * The main object {@code ClassValue.this} is incorrect since 269 * subclasses may override {@code ClassValue.equals}, which 270 * could confuse keys in the ClassValueMap. 271 */ 272 final Identity identity = new Identity(); 273 274 /** 275 * Current version for retrieving this class value from the cache. 276 * Any number of computeValue calls can be cached in association with one version. 277 * But the version changes when a remove (on any type) is executed. 278 * A version change invalidates all cache entries for the affected ClassValue, 279 * by marking them as stale. Stale cache entries do not force another call 280 * to computeValue, but they do require a synchronized visit to a backing map. 281 * <p> 282 * All user-visible state changes on the ClassValue take place under 283 * a lock inside the synchronized methods of ClassValueMap. 284 * Readers (of ClassValue.get) are notified of such state changes 285 * when this.version is bumped to a new token. 286 * This variable must be volatile so that an unsynchronized reader 287 * will receive the notification without delay. 288 * <p> 289 * If version were not volatile, one thread T1 could persistently hold onto 290 * a stale value this.value == V1, while another thread T2 advances 291 * (under a lock) to this.value == V2. This will typically be harmless, 292 * but if T1 and T2 interact causally via some other channel, such that 293 * T1's further actions are constrained (in the JMM) to happen after 294 * the V2 event, then T1's observation of V1 will be an error. 295 * <p> 296 * The practical effect of making this.version be volatile is that it cannot 297 * be hoisted out of a loop (by an optimizing JIT) or otherwise cached. 298 * Some machines may also require a barrier instruction to execute 299 * before this.version. 300 */ 301 private volatile Version<T> version = new Version<>(this); version()302 Version<T> version() { return version; } bumpVersion()303 void bumpVersion() { version = new Version<>(this); } 304 static class Version<T> { 305 private final ClassValue<T> classValue; 306 private final Entry<T> promise = new Entry<>(this); Version(ClassValue<T> classValue)307 Version(ClassValue<T> classValue) { this.classValue = classValue; } classValue()308 ClassValue<T> classValue() { return classValue; } promise()309 Entry<T> promise() { return promise; } isLive()310 boolean isLive() { return classValue.version() == this; } 311 } 312 313 /** One binding of a value to a class via a ClassValue. 314 * States are:<ul> 315 * <li> promise if value == Entry.this 316 * <li> else dead if version == null 317 * <li> else stale if version != classValue.version 318 * <li> else live </ul> 319 * Promises are never put into the cache; they only live in the 320 * backing map while a computeValue call is in flight. 321 * Once an entry goes stale, it can be reset at any time 322 * into the dead state. 323 */ 324 static class Entry<T> extends WeakReference<Version<T>> { 325 final Object value; // usually of type T, but sometimes (Entry)this Entry(Version<T> version, T value)326 Entry(Version<T> version, T value) { 327 super(version); 328 this.value = value; // for a regular entry, value is of type T 329 } assertNotPromise()330 private void assertNotPromise() { assert(!isPromise()); } 331 /** For creating a promise. */ Entry(Version<T> version)332 Entry(Version<T> version) { 333 super(version); 334 this.value = this; // for a promise, value is not of type T, but Entry! 335 } 336 /** Fetch the value. This entry must not be a promise. */ 337 @SuppressWarnings("unchecked") // if !isPromise, type is T value()338 T value() { assertNotPromise(); return (T) value; } isPromise()339 boolean isPromise() { return value == this; } version()340 Version<T> version() { return get(); } classValueOrNull()341 ClassValue<T> classValueOrNull() { 342 Version<T> v = version(); 343 return (v == null) ? null : v.classValue(); 344 } isLive()345 boolean isLive() { 346 Version<T> v = version(); 347 if (v == null) return false; 348 if (v.isLive()) return true; 349 clear(); 350 return false; 351 } refreshVersion(Version<T> v2)352 Entry<T> refreshVersion(Version<T> v2) { 353 assertNotPromise(); 354 @SuppressWarnings("unchecked") // if !isPromise, type is T 355 Entry<T> e2 = new Entry<>(v2, (T) value); 356 clear(); 357 // value = null -- caller must drop 358 return e2; 359 } 360 static final Entry<?> DEAD_ENTRY = new Entry<>(null, null); 361 } 362 363 /** Return the backing map associated with this type. */ getMap(Class<?> type)364 private static ClassValueMap getMap(Class<?> type) { 365 // racing type.classValueMap : null (blank) => unique ClassValueMap 366 // if a null is observed, a map is created (lazily, synchronously, uniquely) 367 // all further access to that map is synchronized 368 ClassValueMap map = type.classValueMap; 369 if (map != null) return map; 370 return initializeMap(type); 371 } 372 373 private static final Object CRITICAL_SECTION = new Object(); 374 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); initializeMap(Class<?> type)375 private static ClassValueMap initializeMap(Class<?> type) { 376 ClassValueMap map; 377 synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks 378 // happens about once per type 379 if ((map = type.classValueMap) == null) { 380 map = new ClassValueMap(); 381 // Place a Store fence after construction and before publishing to emulate 382 // ClassValueMap containing final fields. This ensures it can be 383 // published safely in the non-volatile field Class.classValueMap, 384 // since stores to the fields of ClassValueMap will not be reordered 385 // to occur after the store to the field type.classValueMap 386 UNSAFE.storeFence(); 387 388 type.classValueMap = map; 389 } 390 } 391 return map; 392 } 393 makeEntry(Version<T> explicitVersion, T value)394 static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) { 395 // Note that explicitVersion might be different from this.version. 396 return new Entry<>(explicitVersion, value); 397 398 // As soon as the Entry is put into the cache, the value will be 399 // reachable via a data race (as defined by the Java Memory Model). 400 // This race is benign, assuming the value object itself can be 401 // read safely by multiple threads. This is up to the user. 402 // 403 // The entry and version fields themselves can be safely read via 404 // a race because they are either final or have controlled states. 405 // If the pointer from the entry to the version is still null, 406 // or if the version goes immediately dead and is nulled out, 407 // the reader will take the slow path and retry under a lock. 408 } 409 410 // The following class could also be top level and non-public: 411 412 /** A backing map for all ClassValues. 413 * Gives a fully serialized "true state" for each pair (ClassValue cv, Class type). 414 * Also manages an unserialized fast-path cache. 415 */ 416 static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> { 417 private Entry<?>[] cacheArray; 418 private int cacheLoad, cacheLoadLimit; 419 420 /** Number of entries initially allocated to each type when first used with any ClassValue. 421 * It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves. 422 * Must be a power of 2. 423 */ 424 private static final int INITIAL_ENTRIES = 32; 425 426 /** Build a backing map for ClassValues. 427 * Also, create an empty cache array and install it on the class. 428 */ ClassValueMap()429 ClassValueMap() { 430 sizeCache(INITIAL_ENTRIES); 431 } 432 getCache()433 Entry<?>[] getCache() { return cacheArray; } 434 435 /** Initiate a query. Store a promise (placeholder) if there is no value yet. */ 436 synchronized startEntry(ClassValue<T> classValue)437 <T> Entry<T> startEntry(ClassValue<T> classValue) { 438 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 439 Entry<T> e = (Entry<T>) get(classValue.identity); 440 Version<T> v = classValue.version(); 441 if (e == null) { 442 e = v.promise(); 443 // The presence of a promise means that a value is pending for v. 444 // Eventually, finishEntry will overwrite the promise. 445 put(classValue.identity, e); 446 // Note that the promise is never entered into the cache! 447 return e; 448 } else if (e.isPromise()) { 449 // Somebody else has asked the same question. 450 // Let the races begin! 451 if (e.version() != v) { 452 e = v.promise(); 453 put(classValue.identity, e); 454 } 455 return e; 456 } else { 457 // there is already a completed entry here; report it 458 if (e.version() != v) { 459 // There is a stale but valid entry here; make it fresh again. 460 // Once an entry is in the hash table, we don't care what its version is. 461 e = e.refreshVersion(v); 462 put(classValue.identity, e); 463 } 464 // Add to the cache, to enable the fast path, next time. 465 checkCacheLoad(); 466 addToCache(classValue, e); 467 return e; 468 } 469 } 470 471 /** Finish a query. Overwrite a matching placeholder. Drop stale incoming values. */ 472 synchronized finishEntry(ClassValue<T> classValue, Entry<T> e)473 <T> Entry<T> finishEntry(ClassValue<T> classValue, Entry<T> e) { 474 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 475 Entry<T> e0 = (Entry<T>) get(classValue.identity); 476 if (e == e0) { 477 // We can get here during exception processing, unwinding from computeValue. 478 assert(e.isPromise()); 479 remove(classValue.identity); 480 return null; 481 } else if (e0 != null && e0.isPromise() && e0.version() == e.version()) { 482 // If e0 matches the intended entry, there has not been a remove call 483 // between the previous startEntry and now. So now overwrite e0. 484 Version<T> v = classValue.version(); 485 if (e.version() != v) 486 e = e.refreshVersion(v); 487 put(classValue.identity, e); 488 // Add to the cache, to enable the fast path, next time. 489 checkCacheLoad(); 490 addToCache(classValue, e); 491 return e; 492 } else { 493 // Some sort of mismatch; caller must try again. 494 return null; 495 } 496 } 497 498 /** Remove an entry. */ 499 synchronized removeEntry(ClassValue<?> classValue)500 void removeEntry(ClassValue<?> classValue) { 501 Entry<?> e = remove(classValue.identity); 502 if (e == null) { 503 // Uninitialized, and no pending calls to computeValue. No change. 504 } else if (e.isPromise()) { 505 // State is uninitialized, with a pending call to finishEntry. 506 // Since remove is a no-op in such a state, keep the promise 507 // by putting it back into the map. 508 put(classValue.identity, e); 509 } else { 510 // In an initialized state. Bump forward, and de-initialize. 511 classValue.bumpVersion(); 512 // Make all cache elements for this guy go stale. 513 removeStaleEntries(classValue); 514 } 515 } 516 517 /** Change the value for an entry. */ 518 synchronized changeEntry(ClassValue<T> classValue, T value)519 <T> void changeEntry(ClassValue<T> classValue, T value) { 520 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 521 Entry<T> e0 = (Entry<T>) get(classValue.identity); 522 Version<T> version = classValue.version(); 523 if (e0 != null) { 524 if (e0.version() == version && e0.value() == value) 525 // no value change => no version change needed 526 return; 527 classValue.bumpVersion(); 528 removeStaleEntries(classValue); 529 } 530 Entry<T> e = makeEntry(version, value); 531 put(classValue.identity, e); 532 // Add to the cache, to enable the fast path, next time. 533 checkCacheLoad(); 534 addToCache(classValue, e); 535 } 536 537 /// -------- 538 /// Cache management. 539 /// -------- 540 541 // Statics do not need synchronization. 542 543 /** Load the cache entry at the given (hashed) location. */ loadFromCache(Entry<?>[] cache, int i)544 static Entry<?> loadFromCache(Entry<?>[] cache, int i) { 545 // non-racing cache.length : constant 546 // racing cache[i & (mask)] : null <=> Entry 547 return cache[i & (cache.length-1)]; 548 // invariant: returned value is null or well-constructed (ready to match) 549 } 550 551 /** Look in the cache, at the home location for the given ClassValue. */ probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue)552 static <T> Entry<T> probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue) { 553 return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache)); 554 } 555 556 /** Given that first probe was a collision, retry at nearby locations. */ probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue)557 static <T> Entry<T> probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue) { 558 if (PROBE_LIMIT <= 0) return null; 559 // Probe the cache carefully, in a range of slots. 560 int mask = (cache.length-1); 561 int home = (classValue.hashCodeForCache & mask); 562 Entry<?> e2 = cache[home]; // victim, if we find the real guy 563 if (e2 == null) { 564 return null; // if nobody is at home, no need to search nearby 565 } 566 // assume !classValue.match(e2), but do not assert, because of races 567 int pos2 = -1; 568 for (int i = home + 1; i < home + PROBE_LIMIT; i++) { 569 Entry<?> e = cache[i & mask]; 570 if (e == null) { 571 break; // only search within non-null runs 572 } 573 if (classValue.match(e)) { 574 // relocate colliding entry e2 (from cache[home]) to first empty slot 575 cache[home] = e; 576 if (pos2 >= 0) { 577 cache[i & mask] = Entry.DEAD_ENTRY; 578 } else { 579 pos2 = i; 580 } 581 cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT) 582 ? e2 // put e2 here if it fits 583 : Entry.DEAD_ENTRY); 584 return classValue.castEntry(e); 585 } 586 // Remember first empty slot, if any: 587 if (!e.isLive() && pos2 < 0) pos2 = i; 588 } 589 return null; 590 } 591 592 /** How far out of place is e? */ entryDislocation(Entry<?>[] cache, int pos, Entry<?> e)593 private static int entryDislocation(Entry<?>[] cache, int pos, Entry<?> e) { 594 ClassValue<?> cv = e.classValueOrNull(); 595 if (cv == null) return 0; // entry is not live! 596 int mask = (cache.length-1); 597 return (pos - cv.hashCodeForCache) & mask; 598 } 599 600 /// -------- 601 /// Below this line all functions are private, and assume synchronized access. 602 /// -------- 603 sizeCache(int length)604 private void sizeCache(int length) { 605 assert((length & (length-1)) == 0); // must be power of 2 606 cacheLoad = 0; 607 cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100); 608 cacheArray = new Entry<?>[length]; 609 } 610 611 /** Make sure the cache load stays below its limit, if possible. */ checkCacheLoad()612 private void checkCacheLoad() { 613 if (cacheLoad >= cacheLoadLimit) { 614 reduceCacheLoad(); 615 } 616 } reduceCacheLoad()617 private void reduceCacheLoad() { 618 removeStaleEntries(); 619 if (cacheLoad < cacheLoadLimit) 620 return; // win 621 Entry<?>[] oldCache = getCache(); 622 if (oldCache.length > HASH_MASK) 623 return; // lose 624 sizeCache(oldCache.length * 2); 625 for (Entry<?> e : oldCache) { 626 if (e != null && e.isLive()) { 627 addToCache(e); 628 } 629 } 630 } 631 632 /** Remove stale entries in the given range. 633 * Should be executed under a Map lock. 634 */ removeStaleEntries(Entry<?>[] cache, int begin, int count)635 private void removeStaleEntries(Entry<?>[] cache, int begin, int count) { 636 if (PROBE_LIMIT <= 0) return; 637 int mask = (cache.length-1); 638 int removed = 0; 639 for (int i = begin; i < begin + count; i++) { 640 Entry<?> e = cache[i & mask]; 641 if (e == null || e.isLive()) 642 continue; // skip null and live entries 643 Entry<?> replacement = null; 644 if (PROBE_LIMIT > 1) { 645 // avoid breaking up a non-null run 646 replacement = findReplacement(cache, i); 647 } 648 cache[i & mask] = replacement; 649 if (replacement == null) removed += 1; 650 } 651 cacheLoad = Math.max(0, cacheLoad - removed); 652 } 653 654 /** Clearing a cache slot risks disconnecting following entries 655 * from the head of a non-null run, which would allow them 656 * to be found via reprobes. Find an entry after cache[begin] 657 * to plug into the hole, or return null if none is needed. 658 */ findReplacement(Entry<?>[] cache, int home1)659 private Entry<?> findReplacement(Entry<?>[] cache, int home1) { 660 Entry<?> replacement = null; 661 int haveReplacement = -1, replacementPos = 0; 662 int mask = (cache.length-1); 663 for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) { 664 Entry<?> e2 = cache[i2 & mask]; 665 if (e2 == null) break; // End of non-null run. 666 if (!e2.isLive()) continue; // Doomed anyway. 667 int dis2 = entryDislocation(cache, i2, e2); 668 if (dis2 == 0) continue; // e2 already optimally placed 669 int home2 = i2 - dis2; 670 if (home2 <= home1) { 671 // e2 can replace entry at cache[home1] 672 if (home2 == home1) { 673 // Put e2 exactly where he belongs. 674 haveReplacement = 1; 675 replacementPos = i2; 676 replacement = e2; 677 } else if (haveReplacement <= 0) { 678 haveReplacement = 0; 679 replacementPos = i2; 680 replacement = e2; 681 } 682 // And keep going, so we can favor larger dislocations. 683 } 684 } 685 if (haveReplacement >= 0) { 686 if (cache[(replacementPos+1) & mask] != null) { 687 // Be conservative, to avoid breaking up a non-null run. 688 cache[replacementPos & mask] = (Entry<?>) Entry.DEAD_ENTRY; 689 } else { 690 cache[replacementPos & mask] = null; 691 cacheLoad -= 1; 692 } 693 } 694 return replacement; 695 } 696 697 /** Remove stale entries in the range near classValue. */ removeStaleEntries(ClassValue<?> classValue)698 private void removeStaleEntries(ClassValue<?> classValue) { 699 removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT); 700 } 701 702 /** Remove all stale entries, everywhere. */ removeStaleEntries()703 private void removeStaleEntries() { 704 Entry<?>[] cache = getCache(); 705 removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1); 706 } 707 708 /** Add the given entry to the cache, in its home location, unless it is out of date. */ addToCache(Entry<T> e)709 private <T> void addToCache(Entry<T> e) { 710 ClassValue<T> classValue = e.classValueOrNull(); 711 if (classValue != null) 712 addToCache(classValue, e); 713 } 714 715 /** Add the given entry to the cache, in its home location. */ addToCache(ClassValue<T> classValue, Entry<T> e)716 private <T> void addToCache(ClassValue<T> classValue, Entry<T> e) { 717 if (PROBE_LIMIT <= 0) return; // do not fill cache 718 // Add e to the cache. 719 Entry<?>[] cache = getCache(); 720 int mask = (cache.length-1); 721 int home = classValue.hashCodeForCache & mask; 722 Entry<?> e2 = placeInCache(cache, home, e, false); 723 if (e2 == null) return; // done 724 if (PROBE_LIMIT > 1) { 725 // try to move e2 somewhere else in his probe range 726 int dis2 = entryDislocation(cache, home, e2); 727 int home2 = home - dis2; 728 for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) { 729 if (placeInCache(cache, i2 & mask, e2, true) == null) { 730 return; 731 } 732 } 733 } 734 // Note: At this point, e2 is just dropped from the cache. 735 } 736 737 /** Store the given entry. Update cacheLoad, and return any live victim. 738 * 'Gently' means return self rather than dislocating a live victim. 739 */ placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently)740 private Entry<?> placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently) { 741 Entry<?> e2 = overwrittenEntry(cache[pos]); 742 if (gently && e2 != null) { 743 // do not overwrite a live entry 744 return e; 745 } else { 746 cache[pos] = e; 747 return e2; 748 } 749 } 750 751 /** Note an entry that is about to be overwritten. 752 * If it is not live, quietly replace it by null. 753 * If it is an actual null, increment cacheLoad, 754 * because the caller is going to store something 755 * in its place. 756 */ overwrittenEntry(Entry<T> e2)757 private <T> Entry<T> overwrittenEntry(Entry<T> e2) { 758 if (e2 == null) cacheLoad += 1; 759 else if (e2.isLive()) return e2; 760 return null; 761 } 762 763 /** Percent loading of cache before resize. */ 764 private static final int CACHE_LOAD_LIMIT = 67; // 0..100 765 /** Maximum number of probes to attempt. */ 766 private static final int PROBE_LIMIT = 6; // 1.. 767 // N.B. Set PROBE_LIMIT=0 to disable all fast paths. 768 } 769 } 770