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