Skip to content

Commit d182ada

Browse files
committed
Use ClassLoaderIndex to index class-loader related information
1 parent c8bb444 commit d182ada

File tree

4 files changed

+36
-57
lines changed

4 files changed

+36
-57
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/TypeInfoCache.java

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package datadog.trace.agent.tooling.bytebuddy;
22

3-
import datadog.trace.api.cache.DDCache;
4-
import datadog.trace.api.cache.DDCaches;
5-
import java.lang.ref.WeakReference;
63
import java.net.URL;
74
import java.util.Arrays;
85
import java.util.Objects;
@@ -65,12 +62,12 @@ public SharedTypeInfo<T> find(String className) {
6562
*
6663
* @return previously shared information for the named type
6764
*/
68-
public SharedTypeInfo<T> share(String className, ClassLoader loader, URL classFile, T typeInfo) {
65+
public SharedTypeInfo<T> share(String className, int classLoaderId, URL classFile, T typeInfo) {
6966
SharedTypeInfo<T> newValue;
7067
if (namesAreUnique) {
7168
newValue = new SharedTypeInfo<>(className, typeInfo);
7269
} else {
73-
newValue = new DisambiguatingTypeInfo<>(className, typeInfo, loader, classFile);
70+
newValue = new DisambiguatingTypeInfo<>(className, typeInfo, classLoaderId, classFile);
7471
}
7572

7673
int nameHash = className.hashCode();
@@ -117,7 +114,7 @@ public static class SharedTypeInfo<T> {
117114
this.typeInfo = typeInfo;
118115
}
119116

120-
public boolean sameClassLoader(ClassLoader loader) {
117+
public boolean sameClassLoader(int classLoaderId) {
121118
return true;
122119
}
123120

@@ -132,25 +129,18 @@ public final T get() {
132129

133130
/** Includes the classloader and class file resource it originated from. */
134131
static final class DisambiguatingTypeInfo<T> extends SharedTypeInfo<T> {
135-
private static final ClassLoader BOOTSTRAP_LOADER = null;
136-
private static final LoaderId BOOTSTRAP_LOADER_ID = null;
137-
138-
private static final DDCache<ClassLoader, LoaderId> loaderIds =
139-
DDCaches.newFixedSizeWeakKeyCache(64);
140-
141-
private final LoaderId loaderId;
132+
private final int classLoaderId;
142133
private final URL classFile;
143134

144-
DisambiguatingTypeInfo(String className, T typeInfo, ClassLoader loader, URL classFile) {
135+
DisambiguatingTypeInfo(String className, T typeInfo, int classLoaderId, URL classFile) {
145136
super(className, typeInfo);
146-
this.loaderId = loaderId(loader);
137+
this.classLoaderId = classLoaderId;
147138
this.classFile = classFile;
148139
}
149140

150-
public boolean sameClassLoader(ClassLoader loader) {
151-
return BOOTSTRAP_LOADER_ID == loaderId
152-
? BOOTSTRAP_LOADER == loader
153-
: loaderId.sameClassLoader(loader);
141+
@Override
142+
public boolean sameClassLoader(int classLoaderId) {
143+
return this.classLoaderId == classLoaderId;
154144
}
155145

156146
public boolean sameClassFile(URL classFile) {
@@ -159,12 +149,6 @@ public boolean sameClassFile(URL classFile) {
159149
&& sameClassFile(this.classFile, classFile);
160150
}
161151

162-
private static LoaderId loaderId(ClassLoader loader) {
163-
return BOOTSTRAP_LOADER == loader
164-
? BOOTSTRAP_LOADER_ID
165-
: loaderIds.computeIfAbsent(loader, LoaderId::new);
166-
}
167-
168152
/** Matches class file resources without triggering network lookups. */
169153
private static boolean sameClassFile(URL lhs, URL rhs) {
170154
return Objects.equals(lhs.getFile(), rhs.getFile())
@@ -173,18 +157,4 @@ private static boolean sameClassFile(URL lhs, URL rhs) {
173157
&& Objects.equals(lhs.getProtocol(), rhs.getProtocol());
174158
}
175159
}
176-
177-
/** Supports classloader comparisons without strongly referencing the classloader. */
178-
static final class LoaderId extends WeakReference<ClassLoader> {
179-
private final int loaderHash;
180-
181-
LoaderId(ClassLoader loader) {
182-
super(loader);
183-
this.loaderHash = System.identityHashCode(loader);
184-
}
185-
186-
boolean sameClassLoader(ClassLoader loader) {
187-
return loaderHash == System.identityHashCode(loader) && loader == get();
188-
}
189-
}
190160
}

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/memoize/Memoizer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ static BitSet doMemoize(TypeDescription type, Map<String, BitSet> localMemos) {
239239

240240
// otherwise share result for this location (other locations may have different results)
241241
if (namesAreUnique || name.startsWith("java.") || !(type instanceof WithLocation)) {
242-
memos.share(name, null, null, memo);
242+
memos.share(name, 0, null, memo);
243243
} else {
244244
WithLocation origin = (WithLocation) type;
245-
memos.share(name, origin.getClassLoader(), origin.getClassFile(), memo);
245+
memos.share(name, origin.getClassLoaderId(), origin.getClassFile(), memo);
246246
}
247247

248248
return memo;
@@ -255,7 +255,7 @@ static boolean potentialMatch(String name) {
255255

256256
private static boolean sameOrigin(TypeDescription type, SharedTypeInfo<BitSet> sharedMemo) {
257257
return !(type instanceof WithLocation)
258-
|| sharedMemo.sameClassLoader(((WithLocation) type).getClassLoader())
258+
|| sharedMemo.sameClassLoader(((WithLocation) type).getClassLoaderId())
259259
|| sharedMemo.sameClassFile(((WithLocation) type).getClassFile());
260260
}
261261

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeFactory.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static datadog.trace.bootstrap.AgentClassLoading.LOCATING_CLASS;
66
import static net.bytebuddy.dynamic.loading.ClassLoadingStrategy.BOOTSTRAP_LOADER;
77

8+
import datadog.instrument.utils.ClassLoaderIndex;
89
import datadog.instrument.utils.ClassNameFilter;
910
import datadog.trace.agent.tooling.InstrumenterMetrics;
1011
import datadog.trace.agent.tooling.bytebuddy.ClassFileLocators;
@@ -101,7 +102,9 @@ final class TypeFactory {
101102

102103
ClassLoader originalClassLoader;
103104

104-
ClassLoader classLoader;
105+
ClassLoader currentClassLoader;
106+
107+
int currentClassLoaderId;
105108

106109
ClassFileLocator classFileLocator;
107110

@@ -111,16 +114,17 @@ final class TypeFactory {
111114

112115
/** Sets the current class-loader context of this type-factory. */
113116
void switchContext(ClassLoader classLoader) {
114-
if (this.classLoader != classLoader || null == classFileLocator) {
115-
this.classLoader = classLoader;
117+
if (currentClassLoader != classLoader || null == classFileLocator) {
118+
currentClassLoader = classLoader;
119+
currentClassLoaderId = -1;
116120
classFileLocator = classFileLocator(classLoader);
117121
// clear local type cache whenever the class-loader context changes
118122
deferredTypes.clear();
119123
}
120124
}
121125

122126
ClassLoader currentContext() {
123-
return classLoader;
127+
return currentClassLoader;
124128
}
125129

126130
void beginInstall() {
@@ -151,7 +155,7 @@ void beginTransform(String name, byte[] bytecode) {
151155
targetBytecode = bytecode;
152156

153157
if (installing) {
154-
originalClassLoader = classLoader;
158+
originalClassLoader = currentClassLoader;
155159
}
156160
}
157161

@@ -187,7 +191,8 @@ void endTransform() {
187191

188192
private void clearReferences() {
189193
if (null != classFileLocator) {
190-
classLoader = null;
194+
currentClassLoader = null;
195+
currentClassLoaderId = -1;
191196
classFileLocator = null;
192197
deferredTypes.clear();
193198
}
@@ -249,13 +254,14 @@ TypeDescription resolveType(LazyType request) {
249254
private TypeDescription lookupType(
250255
LazyType request, TypeInfoCache<TypeDescription> types, TypeParser typeParser) {
251256
String name = request.name;
257+
int classLoaderId = request.getClassLoaderId();
252258
boolean isOutline = typeParser == outlineTypeParser;
253259
long fromTick = InstrumenterMetrics.tick();
254260

255261
// existing type description from same classloader?
256262
SharedTypeInfo<TypeDescription> sharedType = types.find(name);
257263
if (null != sharedType
258-
&& (name.startsWith("java.") || sharedType.sameClassLoader(classLoader))) {
264+
&& (name.startsWith("java.") || sharedType.sameClassLoader(classLoaderId))) {
259265
InstrumenterMetrics.reuseTypeDescription(fromTick, isOutline);
260266
return sharedType.get();
261267
}
@@ -287,7 +293,7 @@ private TypeDescription lookupType(
287293
}
288294

289295
// share result, whether we found it or not
290-
types.share(name, classLoader, classFile, type);
296+
types.share(name, classLoaderId, classFile, type);
291297

292298
return type;
293299
}
@@ -297,17 +303,17 @@ private TypeDescription loadType(String name, TypeParser typeParser) {
297303
LOCATING_CLASS.begin();
298304
try {
299305
Class<?> loadedType;
300-
if (BOOTSTRAP_LOADER == classLoader) {
306+
if (BOOTSTRAP_LOADER == currentClassLoader) {
301307
loadedType = Class.forName(name, false, BOOTSTRAP_LOADER);
302-
} else if (skipLoadClass(classLoader.getClass().getName())) {
308+
} else if (skipLoadClass(currentClassLoader.getClass().getName())) {
303309
return null; // avoid known problematic class-loaders
304310
} else {
305-
loadedType = classLoader.loadClass(name);
311+
loadedType = currentClassLoader.loadClass(name);
306312
}
307313
log.debug(
308314
"Direct loadClass type resolution of {} from class loader {} bypasses transformation",
309315
name,
310-
classLoader);
316+
currentClassLoader);
311317
return typeParser.parse(loadedType);
312318
} catch (Throwable ignored) {
313319
return null;
@@ -333,8 +339,11 @@ final class LazyType extends WithName implements WithLocation {
333339
}
334340

335341
@Override
336-
public ClassLoader getClassLoader() {
337-
return classLoader;
342+
public int getClassLoaderId() {
343+
if (currentClassLoaderId < 0) {
344+
currentClassLoaderId = ClassLoaderIndex.getClassLoaderKeyId(currentClassLoader);
345+
}
346+
return currentClassLoaderId;
338347
}
339348

340349
@Override

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/WithLocation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
/** Provides details of where the resolved type was defined. */
66
public interface WithLocation {
7-
ClassLoader getClassLoader();
7+
int getClassLoaderId();
88

99
URL getClassFile();
1010

0 commit comments

Comments
 (0)