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 // Android-changed: Android stores classValueMap in extData. 191 // ClassValueMap map = type.classValueMap; 192 ClassValueMap map = (ClassValueMap) type.ensureExtDataPresent().classValueMap; 193 if (map == null) return EMPTY_CACHE; 194 Entry<?>[] cache = map.getCache(); 195 return cache; 196 // invariant: returned value is safe to dereference and check for an Entry 197 } 198 199 /** Initial, one-element, empty cache used by all Class instances. Must never be filled. */ 200 private static final Entry<?>[] EMPTY_CACHE = { null }; 201 202 /** 203 * Slow tail of ClassValue.get to retry at nearby locations in the cache, 204 * or take a slow lock and check the hash table. 205 * Called only if the first probe was empty or a collision. 206 * This is a separate method, so compilers can process it independently. 207 */ getFromBackup(Entry<?>[] cache, Class<?> type)208 private T getFromBackup(Entry<?>[] cache, Class<?> type) { 209 Entry<T> e = probeBackupLocations(cache, this); 210 if (e != null) 211 return e.value(); 212 return getFromHashMap(type); 213 } 214 215 // Hack to suppress warnings on the (T) cast, which is a no-op. 216 @SuppressWarnings("unchecked") castEntry(Entry<?> e)217 Entry<T> castEntry(Entry<?> e) { return (Entry<T>) e; } 218 219 /** Called when the fast path of get fails, and cache reprobe also fails. 220 */ getFromHashMap(Class<?> type)221 private T getFromHashMap(Class<?> type) { 222 // The fail-safe recovery is to fall back to the underlying classValueMap. 223 ClassValueMap map = getMap(type); 224 for (;;) { 225 Entry<T> e = map.startEntry(this); 226 if (!e.isPromise()) 227 return e.value(); 228 try { 229 // Try to make a real entry for the promised version. 230 e = makeEntry(e.version(), computeValue(type)); 231 } finally { 232 // Whether computeValue throws or returns normally, 233 // be sure to remove the empty entry. 234 e = map.finishEntry(this, e); 235 } 236 if (e != null) 237 return e.value(); 238 // else try again, in case a racing thread called remove (so e == null) 239 } 240 } 241 242 /** Check that e is non-null, matches this ClassValue, and is live. */ match(Entry<?> e)243 boolean match(Entry<?> e) { 244 // racing e.version : null (blank) => unique Version token => null (GC-ed version) 245 // non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile) 246 return (e != null && e.get() == this.version); 247 // invariant: No false positives on version match. Null is OK for false negative. 248 // invariant: If version matches, then e.value is readable (final set in Entry.<init>) 249 } 250 251 /** Internal hash code for accessing Class.classValueMap.cacheArray. */ 252 final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK; 253 254 /** Value stream for hashCodeForCache. See similar structure in ThreadLocal. */ 255 private static final AtomicInteger nextHashCode = new AtomicInteger(); 256 257 /** Good for power-of-two tables. See similar structure in ThreadLocal. */ 258 private static final int HASH_INCREMENT = 0x61c88647; 259 260 /** Mask a hash code to be positive but not too large, to prevent wraparound. */ 261 static final int HASH_MASK = (-1 >>> 2); 262 263 /** 264 * Private key for retrieval of this object from ClassValueMap. 265 */ 266 static class Identity { 267 } 268 /** 269 * This ClassValue's identity, expressed as an opaque object. 270 * The main object {@code ClassValue.this} is incorrect since 271 * subclasses may override {@code ClassValue.equals}, which 272 * could confuse keys in the ClassValueMap. 273 */ 274 final Identity identity = new Identity(); 275 276 /** 277 * Current version for retrieving this class value from the cache. 278 * Any number of computeValue calls can be cached in association with one version. 279 * But the version changes when a remove (on any type) is executed. 280 * A version change invalidates all cache entries for the affected ClassValue, 281 * by marking them as stale. Stale cache entries do not force another call 282 * to computeValue, but they do require a synchronized visit to a backing map. 283 * <p> 284 * All user-visible state changes on the ClassValue take place under 285 * a lock inside the synchronized methods of ClassValueMap. 286 * Readers (of ClassValue.get) are notified of such state changes 287 * when this.version is bumped to a new token. 288 * This variable must be volatile so that an unsynchronized reader 289 * will receive the notification without delay. 290 * <p> 291 * If version were not volatile, one thread T1 could persistently hold onto 292 * a stale value this.value == V1, while another thread T2 advances 293 * (under a lock) to this.value == V2. This will typically be harmless, 294 * but if T1 and T2 interact causally via some other channel, such that 295 * T1's further actions are constrained (in the JMM) to happen after 296 * the V2 event, then T1's observation of V1 will be an error. 297 * <p> 298 * The practical effect of making this.version be volatile is that it cannot 299 * be hoisted out of a loop (by an optimizing JIT) or otherwise cached. 300 * Some machines may also require a barrier instruction to execute 301 * before this.version. 302 */ 303 private volatile Version<T> version = new Version<>(this); version()304 Version<T> version() { return version; } bumpVersion()305 void bumpVersion() { version = new Version<>(this); } 306 static class Version<T> { 307 private final ClassValue<T> classValue; 308 private final Entry<T> promise = new Entry<>(this); Version(ClassValue<T> classValue)309 Version(ClassValue<T> classValue) { this.classValue = classValue; } classValue()310 ClassValue<T> classValue() { return classValue; } promise()311 Entry<T> promise() { return promise; } isLive()312 boolean isLive() { return classValue.version() == this; } 313 } 314 315 /** One binding of a value to a class via a ClassValue. 316 * States are:<ul> 317 * <li> promise if value == Entry.this 318 * <li> else dead if version == null 319 * <li> else stale if version != classValue.version 320 * <li> else live </ul> 321 * Promises are never put into the cache; they only live in the 322 * backing map while a computeValue call is in flight. 323 * Once an entry goes stale, it can be reset at any time 324 * into the dead state. 325 */ 326 static class Entry<T> extends WeakReference<Version<T>> { 327 final Object value; // usually of type T, but sometimes (Entry)this Entry(Version<T> version, T value)328 Entry(Version<T> version, T value) { 329 super(version); 330 this.value = value; // for a regular entry, value is of type T 331 } assertNotPromise()332 private void assertNotPromise() { assert(!isPromise()); } 333 /** For creating a promise. */ Entry(Version<T> version)334 Entry(Version<T> version) { 335 super(version); 336 this.value = this; // for a promise, value is not of type T, but Entry! 337 } 338 /** Fetch the value. This entry must not be a promise. */ 339 @SuppressWarnings("unchecked") // if !isPromise, type is T value()340 T value() { assertNotPromise(); return (T) value; } isPromise()341 boolean isPromise() { return value == this; } version()342 Version<T> version() { return get(); } classValueOrNull()343 ClassValue<T> classValueOrNull() { 344 Version<T> v = version(); 345 return (v == null) ? null : v.classValue(); 346 } isLive()347 boolean isLive() { 348 Version<T> v = version(); 349 if (v == null) return false; 350 if (v.isLive()) return true; 351 clear(); 352 return false; 353 } refreshVersion(Version<T> v2)354 Entry<T> refreshVersion(Version<T> v2) { 355 assertNotPromise(); 356 @SuppressWarnings("unchecked") // if !isPromise, type is T 357 Entry<T> e2 = new Entry<>(v2, (T) value); 358 clear(); 359 // value = null -- caller must drop 360 return e2; 361 } 362 static final Entry<?> DEAD_ENTRY = new Entry<>(null, null); 363 } 364 365 /** Return the backing map associated with this type. */ getMap(Class<?> type)366 private static ClassValueMap getMap(Class<?> type) { 367 // racing type.classValueMap : null (blank) => unique ClassValueMap 368 // if a null is observed, a map is created (lazily, synchronously, uniquely) 369 // all further access to that map is synchronized 370 // Android-changed: Android stores classValueMap in extData. 371 // ClassValueMap map = type.classValueMap; 372 ClassValueMap map = (ClassValueMap) type.ensureExtDataPresent().classValueMap; 373 if (map != null) return map; 374 return initializeMap(type); 375 } 376 377 private static final Object CRITICAL_SECTION = new Object(); 378 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); initializeMap(Class<?> type)379 private static ClassValueMap initializeMap(Class<?> type) { 380 ClassValueMap map; 381 synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks 382 // happens about once per type 383 // Android-changed: Android stores classValueMap in extData. 384 // if ((map = type.classValueMap) == null) { 385 if ((map = (ClassValueMap) type.ensureExtDataPresent().classValueMap) == null) { 386 map = new ClassValueMap(); 387 // Place a Store fence after construction and before publishing to emulate 388 // ClassValueMap containing final fields. This ensures it can be 389 // published safely in the non-volatile field Class.classValueMap, 390 // since stores to the fields of ClassValueMap will not be reordered 391 // to occur after the store to the field type.classValueMap 392 UNSAFE.storeFence(); 393 394 // Android-changed: Android stores classValueMap in extData. 395 // type.classValueMap = map; 396 type.ensureExtDataPresent().classValueMap = map; 397 } 398 } 399 return map; 400 } 401 makeEntry(Version<T> explicitVersion, T value)402 static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) { 403 // Note that explicitVersion might be different from this.version. 404 return new Entry<>(explicitVersion, value); 405 406 // As soon as the Entry is put into the cache, the value will be 407 // reachable via a data race (as defined by the Java Memory Model). 408 // This race is benign, assuming the value object itself can be 409 // read safely by multiple threads. This is up to the user. 410 // 411 // The entry and version fields themselves can be safely read via 412 // a race because they are either final or have controlled states. 413 // If the pointer from the entry to the version is still null, 414 // or if the version goes immediately dead and is nulled out, 415 // the reader will take the slow path and retry under a lock. 416 } 417 418 // The following class could also be top level and non-public: 419 420 /** A backing map for all ClassValues. 421 * Gives a fully serialized "true state" for each pair (ClassValue cv, Class type). 422 * Also manages an unserialized fast-path cache. 423 */ 424 static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> { 425 private Entry<?>[] cacheArray; 426 private int cacheLoad, cacheLoadLimit; 427 428 /** Number of entries initially allocated to each type when first used with any ClassValue. 429 * It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves. 430 * Must be a power of 2. 431 */ 432 private static final int INITIAL_ENTRIES = 32; 433 434 /** Build a backing map for ClassValues. 435 * Also, create an empty cache array and install it on the class. 436 */ ClassValueMap()437 ClassValueMap() { 438 sizeCache(INITIAL_ENTRIES); 439 } 440 getCache()441 Entry<?>[] getCache() { return cacheArray; } 442 443 /** Initiate a query. Store a promise (placeholder) if there is no value yet. */ 444 synchronized startEntry(ClassValue<T> classValue)445 <T> Entry<T> startEntry(ClassValue<T> classValue) { 446 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 447 Entry<T> e = (Entry<T>) get(classValue.identity); 448 Version<T> v = classValue.version(); 449 if (e == null) { 450 e = v.promise(); 451 // The presence of a promise means that a value is pending for v. 452 // Eventually, finishEntry will overwrite the promise. 453 put(classValue.identity, e); 454 // Note that the promise is never entered into the cache! 455 return e; 456 } else if (e.isPromise()) { 457 // Somebody else has asked the same question. 458 // Let the races begin! 459 if (e.version() != v) { 460 e = v.promise(); 461 put(classValue.identity, e); 462 } 463 return e; 464 } else { 465 // there is already a completed entry here; report it 466 if (e.version() != v) { 467 // There is a stale but valid entry here; make it fresh again. 468 // Once an entry is in the hash table, we don't care what its version is. 469 e = e.refreshVersion(v); 470 put(classValue.identity, e); 471 } 472 // Add to the cache, to enable the fast path, next time. 473 checkCacheLoad(); 474 addToCache(classValue, e); 475 return e; 476 } 477 } 478 479 /** Finish a query. Overwrite a matching placeholder. Drop stale incoming values. */ 480 synchronized finishEntry(ClassValue<T> classValue, Entry<T> e)481 <T> Entry<T> finishEntry(ClassValue<T> classValue, Entry<T> e) { 482 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 483 Entry<T> e0 = (Entry<T>) get(classValue.identity); 484 if (e == e0) { 485 // We can get here during exception processing, unwinding from computeValue. 486 assert(e.isPromise()); 487 remove(classValue.identity); 488 return null; 489 } else if (e0 != null && e0.isPromise() && e0.version() == e.version()) { 490 // If e0 matches the intended entry, there has not been a remove call 491 // between the previous startEntry and now. So now overwrite e0. 492 Version<T> v = classValue.version(); 493 if (e.version() != v) 494 e = e.refreshVersion(v); 495 put(classValue.identity, e); 496 // Add to the cache, to enable the fast path, next time. 497 checkCacheLoad(); 498 addToCache(classValue, e); 499 return e; 500 } else { 501 // Some sort of mismatch; caller must try again. 502 return null; 503 } 504 } 505 506 /** Remove an entry. */ 507 synchronized removeEntry(ClassValue<?> classValue)508 void removeEntry(ClassValue<?> classValue) { 509 Entry<?> e = remove(classValue.identity); 510 if (e == null) { 511 // Uninitialized, and no pending calls to computeValue. No change. 512 } else if (e.isPromise()) { 513 // State is uninitialized, with a pending call to finishEntry. 514 // Since remove is a no-op in such a state, keep the promise 515 // by putting it back into the map. 516 put(classValue.identity, e); 517 } else { 518 // In an initialized state. Bump forward, and de-initialize. 519 classValue.bumpVersion(); 520 // Make all cache elements for this guy go stale. 521 removeStaleEntries(classValue); 522 } 523 } 524 525 /** Change the value for an entry. */ 526 synchronized changeEntry(ClassValue<T> classValue, T value)527 <T> void changeEntry(ClassValue<T> classValue, T value) { 528 @SuppressWarnings("unchecked") // one map has entries for all value types <T> 529 Entry<T> e0 = (Entry<T>) get(classValue.identity); 530 Version<T> version = classValue.version(); 531 if (e0 != null) { 532 if (e0.version() == version && e0.value() == value) 533 // no value change => no version change needed 534 return; 535 classValue.bumpVersion(); 536 removeStaleEntries(classValue); 537 } 538 Entry<T> e = makeEntry(version, value); 539 put(classValue.identity, e); 540 // Add to the cache, to enable the fast path, next time. 541 checkCacheLoad(); 542 addToCache(classValue, e); 543 } 544 545 /// -------- 546 /// Cache management. 547 /// -------- 548 549 // Statics do not need synchronization. 550 551 /** Load the cache entry at the given (hashed) location. */ loadFromCache(Entry<?>[] cache, int i)552 static Entry<?> loadFromCache(Entry<?>[] cache, int i) { 553 // non-racing cache.length : constant 554 // racing cache[i & (mask)] : null <=> Entry 555 return cache[i & (cache.length-1)]; 556 // invariant: returned value is null or well-constructed (ready to match) 557 } 558 559 /** Look in the cache, at the home location for the given ClassValue. */ probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue)560 static <T> Entry<T> probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue) { 561 return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache)); 562 } 563 564 /** Given that first probe was a collision, retry at nearby locations. */ probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue)565 static <T> Entry<T> probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue) { 566 if (PROBE_LIMIT <= 0) return null; 567 // Probe the cache carefully, in a range of slots. 568 int mask = (cache.length-1); 569 int home = (classValue.hashCodeForCache & mask); 570 Entry<?> e2 = cache[home]; // victim, if we find the real guy 571 if (e2 == null) { 572 return null; // if nobody is at home, no need to search nearby 573 } 574 // assume !classValue.match(e2), but do not assert, because of races 575 int pos2 = -1; 576 for (int i = home + 1; i < home + PROBE_LIMIT; i++) { 577 Entry<?> e = cache[i & mask]; 578 if (e == null) { 579 break; // only search within non-null runs 580 } 581 if (classValue.match(e)) { 582 // relocate colliding entry e2 (from cache[home]) to first empty slot 583 cache[home] = e; 584 if (pos2 >= 0) { 585 cache[i & mask] = Entry.DEAD_ENTRY; 586 } else { 587 pos2 = i; 588 } 589 cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT) 590 ? e2 // put e2 here if it fits 591 : Entry.DEAD_ENTRY); 592 return classValue.castEntry(e); 593 } 594 // Remember first empty slot, if any: 595 if (!e.isLive() && pos2 < 0) pos2 = i; 596 } 597 return null; 598 } 599 600 /** How far out of place is e? */ entryDislocation(Entry<?>[] cache, int pos, Entry<?> e)601 private static int entryDislocation(Entry<?>[] cache, int pos, Entry<?> e) { 602 ClassValue<?> cv = e.classValueOrNull(); 603 if (cv == null) return 0; // entry is not live! 604 int mask = (cache.length-1); 605 return (pos - cv.hashCodeForCache) & mask; 606 } 607 608 /// -------- 609 /// Below this line all functions are private, and assume synchronized access. 610 /// -------- 611 sizeCache(int length)612 private void sizeCache(int length) { 613 assert((length & (length-1)) == 0); // must be power of 2 614 cacheLoad = 0; 615 cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100); 616 cacheArray = new Entry<?>[length]; 617 } 618 619 /** Make sure the cache load stays below its limit, if possible. */ checkCacheLoad()620 private void checkCacheLoad() { 621 if (cacheLoad >= cacheLoadLimit) { 622 reduceCacheLoad(); 623 } 624 } reduceCacheLoad()625 private void reduceCacheLoad() { 626 removeStaleEntries(); 627 if (cacheLoad < cacheLoadLimit) 628 return; // win 629 Entry<?>[] oldCache = getCache(); 630 if (oldCache.length > HASH_MASK) 631 return; // lose 632 sizeCache(oldCache.length * 2); 633 for (Entry<?> e : oldCache) { 634 if (e != null && e.isLive()) { 635 addToCache(e); 636 } 637 } 638 } 639 640 /** Remove stale entries in the given range. 641 * Should be executed under a Map lock. 642 */ removeStaleEntries(Entry<?>[] cache, int begin, int count)643 private void removeStaleEntries(Entry<?>[] cache, int begin, int count) { 644 if (PROBE_LIMIT <= 0) return; 645 int mask = (cache.length-1); 646 int removed = 0; 647 for (int i = begin; i < begin + count; i++) { 648 Entry<?> e = cache[i & mask]; 649 if (e == null || e.isLive()) 650 continue; // skip null and live entries 651 Entry<?> replacement = null; 652 if (PROBE_LIMIT > 1) { 653 // avoid breaking up a non-null run 654 replacement = findReplacement(cache, i); 655 } 656 cache[i & mask] = replacement; 657 if (replacement == null) removed += 1; 658 } 659 cacheLoad = Math.max(0, cacheLoad - removed); 660 } 661 662 /** Clearing a cache slot risks disconnecting following entries 663 * from the head of a non-null run, which would allow them 664 * to be found via reprobes. Find an entry after cache[begin] 665 * to plug into the hole, or return null if none is needed. 666 */ findReplacement(Entry<?>[] cache, int home1)667 private Entry<?> findReplacement(Entry<?>[] cache, int home1) { 668 Entry<?> replacement = null; 669 int haveReplacement = -1, replacementPos = 0; 670 int mask = (cache.length-1); 671 for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) { 672 Entry<?> e2 = cache[i2 & mask]; 673 if (e2 == null) break; // End of non-null run. 674 if (!e2.isLive()) continue; // Doomed anyway. 675 int dis2 = entryDislocation(cache, i2, e2); 676 if (dis2 == 0) continue; // e2 already optimally placed 677 int home2 = i2 - dis2; 678 if (home2 <= home1) { 679 // e2 can replace entry at cache[home1] 680 if (home2 == home1) { 681 // Put e2 exactly where he belongs. 682 haveReplacement = 1; 683 replacementPos = i2; 684 replacement = e2; 685 } else if (haveReplacement <= 0) { 686 haveReplacement = 0; 687 replacementPos = i2; 688 replacement = e2; 689 } 690 // And keep going, so we can favor larger dislocations. 691 } 692 } 693 if (haveReplacement >= 0) { 694 if (cache[(replacementPos+1) & mask] != null) { 695 // Be conservative, to avoid breaking up a non-null run. 696 cache[replacementPos & mask] = (Entry<?>) Entry.DEAD_ENTRY; 697 } else { 698 cache[replacementPos & mask] = null; 699 cacheLoad -= 1; 700 } 701 } 702 return replacement; 703 } 704 705 /** Remove stale entries in the range near classValue. */ removeStaleEntries(ClassValue<?> classValue)706 private void removeStaleEntries(ClassValue<?> classValue) { 707 removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT); 708 } 709 710 /** Remove all stale entries, everywhere. */ removeStaleEntries()711 private void removeStaleEntries() { 712 Entry<?>[] cache = getCache(); 713 removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1); 714 } 715 716 /** Add the given entry to the cache, in its home location, unless it is out of date. */ addToCache(Entry<T> e)717 private <T> void addToCache(Entry<T> e) { 718 ClassValue<T> classValue = e.classValueOrNull(); 719 if (classValue != null) 720 addToCache(classValue, e); 721 } 722 723 /** Add the given entry to the cache, in its home location. */ addToCache(ClassValue<T> classValue, Entry<T> e)724 private <T> void addToCache(ClassValue<T> classValue, Entry<T> e) { 725 if (PROBE_LIMIT <= 0) return; // do not fill cache 726 // Add e to the cache. 727 Entry<?>[] cache = getCache(); 728 int mask = (cache.length-1); 729 int home = classValue.hashCodeForCache & mask; 730 Entry<?> e2 = placeInCache(cache, home, e, false); 731 if (e2 == null) return; // done 732 if (PROBE_LIMIT > 1) { 733 // try to move e2 somewhere else in his probe range 734 int dis2 = entryDislocation(cache, home, e2); 735 int home2 = home - dis2; 736 for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) { 737 if (placeInCache(cache, i2 & mask, e2, true) == null) { 738 return; 739 } 740 } 741 } 742 // Note: At this point, e2 is just dropped from the cache. 743 } 744 745 /** Store the given entry. Update cacheLoad, and return any live victim. 746 * 'Gently' means return self rather than dislocating a live victim. 747 */ placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently)748 private Entry<?> placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently) { 749 Entry<?> e2 = overwrittenEntry(cache[pos]); 750 if (gently && e2 != null) { 751 // do not overwrite a live entry 752 return e; 753 } else { 754 cache[pos] = e; 755 return e2; 756 } 757 } 758 759 /** Note an entry that is about to be overwritten. 760 * If it is not live, quietly replace it by null. 761 * If it is an actual null, increment cacheLoad, 762 * because the caller is going to store something 763 * in its place. 764 */ overwrittenEntry(Entry<T> e2)765 private <T> Entry<T> overwrittenEntry(Entry<T> e2) { 766 if (e2 == null) cacheLoad += 1; 767 else if (e2.isLive()) return e2; 768 return null; 769 } 770 771 /** Percent loading of cache before resize. */ 772 private static final int CACHE_LOAD_LIMIT = 67; // 0..100 773 /** Maximum number of probes to attempt. */ 774 private static final int PROBE_LIMIT = 6; // 1.. 775 // N.B. Set PROBE_LIMIT=0 to disable all fast paths. 776 } 777 } 778