Skip to content

Commit 5f70d32

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

File tree

4 files changed

+37
-57
lines changed

4 files changed

+37
-57
lines changed

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

Lines changed: 10 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,13 @@ 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(
66+
String className, int classLoaderKeyId, URL classFile, T typeInfo) {
6967
SharedTypeInfo<T> newValue;
7068
if (namesAreUnique) {
7169
newValue = new SharedTypeInfo<>(className, typeInfo);
7270
} else {
73-
newValue = new DisambiguatingTypeInfo<>(className, typeInfo, loader, classFile);
71+
newValue = new DisambiguatingTypeInfo<>(className, typeInfo, classLoaderKeyId, classFile);
7472
}
7573

7674
int nameHash = className.hashCode();
@@ -117,7 +115,7 @@ public static class SharedTypeInfo<T> {
117115
this.typeInfo = typeInfo;
118116
}
119117

120-
public boolean sameClassLoader(ClassLoader loader) {
118+
public boolean sameClassLoader(int classLoaderKeyId) {
121119
return true;
122120
}
123121

@@ -132,25 +130,18 @@ public final T get() {
132130

133131
/** Includes the classloader and class file resource it originated from. */
134132
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;
133+
private final int classLoaderKeyId;
142134
private final URL classFile;
143135

144-
DisambiguatingTypeInfo(String className, T typeInfo, ClassLoader loader, URL classFile) {
136+
DisambiguatingTypeInfo(String className, T typeInfo, int classLoaderKeyId, URL classFile) {
145137
super(className, typeInfo);
146-
this.loaderId = loaderId(loader);
138+
this.classLoaderKeyId = classLoaderKeyId;
147139
this.classFile = classFile;
148140
}
149141

150-
public boolean sameClassLoader(ClassLoader loader) {
151-
return BOOTSTRAP_LOADER_ID == loaderId
152-
? BOOTSTRAP_LOADER == loader
153-
: loaderId.sameClassLoader(loader);
142+
@Override
143+
public boolean sameClassLoader(int classLoaderKeyId) {
144+
return this.classLoaderKeyId == classLoaderKeyId;
154145
}
155146

156147
public boolean sameClassFile(URL classFile) {
@@ -159,12 +150,6 @@ public boolean sameClassFile(URL classFile) {
159150
&& sameClassFile(this.classFile, classFile);
160151
}
161152

162-
private static LoaderId loaderId(ClassLoader loader) {
163-
return BOOTSTRAP_LOADER == loader
164-
? BOOTSTRAP_LOADER_ID
165-
: loaderIds.computeIfAbsent(loader, LoaderId::new);
166-
}
167-
168153
/** Matches class file resources without triggering network lookups. */
169154
private static boolean sameClassFile(URL lhs, URL rhs) {
170155
return Objects.equals(lhs.getFile(), rhs.getFile())
@@ -173,18 +158,4 @@ private static boolean sameClassFile(URL lhs, URL rhs) {
173158
&& Objects.equals(lhs.getProtocol(), rhs.getProtocol());
174159
}
175160
}
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-
}
190161
}

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.getClassLoaderKeyId(), 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).getClassLoaderKeyId())
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 currentClassLoaderKeyId;
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+
currentClassLoaderKeyId = -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+
currentClassLoaderKeyId = -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 classLoaderKeyId = request.getClassLoaderKeyId();
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(classLoaderKeyId))) {
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, classLoaderKeyId, 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 getClassLoaderKeyId() {
343+
if (currentClassLoaderKeyId < 0) {
344+
currentClassLoaderKeyId = ClassLoaderIndex.getClassLoaderKeyId(currentClassLoader);
345+
}
346+
return currentClassLoaderKeyId;
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 getClassLoaderKeyId();
88

99
URL getClassFile();
1010

0 commit comments

Comments
 (0)