< prev index next >
src/java.base/share/classes/java/lang/reflect/Module.java
Print this page
*** 41,55 ****
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
- import java.util.WeakHashMap;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Stream;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
--- 41,50 ----
*** 252,263 ****
// the modules that this module permanently reads
// (will be final when the modules are defined in reverse topology order)
private volatile Set<Module> reads;
! // created lazily, additional modules that this module reflectively reads
! private volatile WeakSet<Module> transientReads;
/**
* Indicates if this module reads the given module. This method returns
* {@code true} if invoked to test if this module reads itself. It also
--- 247,259 ----
// the modules that this module permanently reads
// (will be final when the modules are defined in reverse topology order)
private volatile Set<Module> reads;
! // additional module (2nd key) that some module (1st key) reflectively reads
! private static final WeakPairMap<Module, Module, Boolean> transientReads
! = new WeakPairMap<>();
/**
* Indicates if this module reads the given module. This method returns
* {@code true} if invoked to test if this module reads itself. It also
*** 296,310 ****
return true;
}
// check if this module reads the other module reflectively
! WeakSet<Module> tr = this.transientReads; // volatile read
! if (tr != null && tr.contains(other))
! return true;
!
! return false;
}
/**
* If the caller's module is this module then update this module to read
* the given module.
--- 292,302 ----
return true;
}
// check if this module reads the other module reflectively
! return transientReads.constainsKeyPair(this, other);
}
/**
* If the caller's module is this module then update this module to read
* the given module.
*** 382,413 ****
// update VM first, just in case it fails
if (syncVM)
addReads0(this, other);
// add reflective read
! WeakSet<Module> tr = this.transientReads;
! if (tr == null) {
! synchronized (this) {
! tr = this.transientReads;
! if (tr == null) {
! tr = new WeakSet<>();
! this.transientReads = tr;
! }
! }
! }
! tr.add(other);
}
// -- exports --
// the packages that are permanently exported
// (will be final when the modules are defined in reverse topology order)
private volatile Map<String, Set<Module>> exports;
! // created lazily, additional exports added at run-time
! private volatile Map<String, WeakSet<Module>> transientExports;
// the special Module to mean exported to all modules
private static final Module EVERYONE_MODULE = new Module(null);
private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
--- 374,397 ----
// update VM first, just in case it fails
if (syncVM)
addReads0(this, other);
// add reflective read
! transientReads.putIfAbsent(this, other, Boolean.TRUE);
}
// -- exports --
// the packages that are permanently exported
// (will be final when the modules are defined in reverse topology order)
private volatile Map<String, Set<Module>> exports;
! // additional exports added at run-time
! // source module (1st key), target module (2nd key), exported packages (value)
! private static final WeakPairMap<Module, Module, Set<String>> transientExports =
! new WeakPairMap<>();
// the special Module to mean exported to all modules
private static final Module EVERYONE_MODULE = new Module(null);
private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
*** 513,545 ****
/**
* Returns {@code true} if this module reflectively exports the given
* package package to the given module.
*/
private boolean isExportedReflectively(String pn, Module other) {
- Map<String, WeakSet<Module>> te = this.transientExports;
- if (te != null) {
- WeakSet<Module> targets = te.get(pn);
-
- if (targets != null) {
-
// exported to all modules
! if (targets.contains(EVERYONE_MODULE))
return true;
if (other != EVERYONE_MODULE) {
// exported to other
! if (targets.contains(other))
return true;
// other is an unnamed module && exported to all unnamed
! if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
return true;
}
}
- }
return false;
}
/**
--- 497,527 ----
/**
* Returns {@code true} if this module reflectively exports the given
* package package to the given module.
*/
private boolean isExportedReflectively(String pn, Module other) {
// exported to all modules
! Set<String> exportedToAll = transientExports.get(this, EVERYONE_MODULE);
! if (exportedToAll != null && exportedToAll.contains(pn))
return true;
if (other != EVERYONE_MODULE) {
// exported to other
! Set<String> exportedToOther = transientExports.get(this, other);
!
! if (exportedToOther != null && exportedToOther.contains(pn))
return true;
// other is an unnamed module && exported to all unnamed
! if (!other.isNamed()) {
! Set<String> exportedToAllUnnamed = transientExports.get(this, ALL_UNNAMED_MODULE);
! if (exportedToAllUnnamed != null && exportedToAllUnnamed.contains(pn))
return true;
}
}
return false;
}
/**
*** 636,673 ****
} else {
addExports0(this, pkgInternalForm, other);
}
}
- // create transientExports if needed
- Map<String, WeakSet<Module>> te = this.transientExports; // read
- if (te == null) {
- synchronized (this) {
- te = this.transientExports;
- if (te == null) {
- te = new ConcurrentHashMap<>();
- this.transientExports = te; // volatile write
- }
- }
- }
-
// add package name to transientExports if absent
! WeakSet<Module> s = te.get(pn);
! if (s == null) {
! s = new WeakSet<>();
! WeakSet<Module> prev = te.putIfAbsent(pn, s);
! if (prev != null)
! s = prev;
! }
! s.add(other);
}
// -- services --
! // created lazily, additional service types that this module uses
! private volatile WeakSet<Class<?>> transientUses;
/**
* If the caller's module is this module then update this module to add a
* service dependence on the given service type. This method is intended
* for use by frameworks that invoke {@link java.util.ServiceLoader
--- 618,639 ----
} else {
addExports0(this, pkgInternalForm, other);
}
}
// add package name to transientExports if absent
! transientExports
! .computeIfAbsent(this, other, (_this, _other) -> new HashSet<>())
! .add(pn);
}
// -- services --
! // additional service type (2nd key) that some module (1st key) uses
! private static final WeakPairMap<Module, Class<?>, Boolean> transientUses
! = new WeakPairMap<>();
/**
* If the caller's module is this module then update this module to add a
* service dependence on the given service type. This method is intended
* for use by frameworks that invoke {@link java.util.ServiceLoader
*** 700,720 ****
if (caller != this) {
throw new IllegalStateException(caller + " != " + this);
}
if (!canUse(st)) {
! WeakSet<Class<?>> uses = this.transientUses;
! if (uses == null) {
! synchronized (this) {
! uses = this.transientUses;
! if (uses == null) {
! uses = new WeakSet<>();
! this.transientUses = uses;
! }
! }
! }
! uses.add(st);
}
}
return this;
--- 666,676 ----
if (caller != this) {
throw new IllegalStateException(caller + " != " + this);
}
if (!canUse(st)) {
! transientUses.putIfAbsent(this, st, Boolean.TRUE);
}
}
return this;
*** 744,758 ****
// uses was declared
if (descriptor.uses().contains(st.getName()))
return true;
// uses added via addUses
! WeakSet<Class<?>> uses = this.transientUses;
! if (uses != null && uses.contains(st))
! return true;
!
! return false;
}
// -- packages --
--- 700,710 ----
// uses was declared
if (descriptor.uses().contains(st.getName()))
return true;
// uses added via addUses
! return transientUses.constainsKeyPair(this, st);
}
// -- packages --
*** 1110,1159 ****
return "unnamed module @" + id;
}
}
- // -- supporting classes --
-
-
- /**
- * A "not-a-Set" set of weakly referenced objects that supports concurrent
- * access.
- */
- private static class WeakSet<E> {
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
- private final Lock readLock = lock.readLock();
- private final Lock writeLock = lock.writeLock();
-
- private final WeakHashMap<E, Boolean> map = new WeakHashMap<>();
-
- /**
- * Adds the specified element to the set.
- */
- void add(E e) {
- writeLock.lock();
- try {
- map.put(e, Boolean.TRUE);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Returns {@code true} if this set contains the specified element.
- */
- boolean contains(E e) {
- readLock.lock();
- try {
- return map.containsKey(e);
- } finally {
- readLock.unlock();
- }
- }
- }
-
-
// -- native methods --
// JVM_DefineModule
private static native void defineModule0(Module module,
String version,
--- 1062,1071 ----
< prev index next >