Skip to content

Commit

Permalink
Refactored method pool to represent method definitions in a more cons…
Browse files Browse the repository at this point in the history
…istent manner.

This refactored implementation offers a better extension point for bridge methods.
  • Loading branch information
Rafael Winterhalter committed Jul 28, 2015
1 parent 68b39d3 commit cefe63a
Show file tree
Hide file tree
Showing 8 changed files with 544 additions and 420 deletions.
Expand Up @@ -3,7 +3,6 @@
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.attribute.FieldAttributeAppender;
import org.objectweb.asm.ClassVisitor;

import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -224,7 +223,7 @@ public TypeWriter.FieldPool.Entry target(FieldDescription fieldDescription) {
Entry entry = entries.get(fieldDescription.asToken());
return entry == null
? new TypeWriter.FieldPool.Entry.ForSimpleField(fieldDescription)
: new TypeWriter.FieldPool.Entry.ForRichField(entry.getAttributeAppender(), entry.getDefaultValue(), fieldDescription);
: entry.bind(fieldDescription);
}

@Override
Expand Down Expand Up @@ -256,12 +255,8 @@ protected Entry(FieldAttributeAppender attributeAppender, Object defaultValue) {
this.defaultValue = defaultValue;
}

public FieldAttributeAppender getAttributeAppender() {
return attributeAppender;
}

public Object getDefaultValue() {
return defaultValue;
protected TypeWriter.FieldPool.Entry bind(FieldDescription fieldDescription) {
return new TypeWriter.FieldPool.Entry.ForRichField(attributeAppender, defaultValue, fieldDescription);
}

@Override
Expand Down
Expand Up @@ -29,9 +29,7 @@ public interface MethodRegistry {
* @param attributeAppenderFactory A method attribute appender to apply to any matched method.
* @return A mutated version of this method registry.
*/
MethodRegistry prepend(LatentMethodMatcher methodMatcher,
Handler handler,
MethodAttributeAppender.Factory attributeAppenderFactory);
MethodRegistry prepend(LatentMethodMatcher methodMatcher, Handler handler, MethodAttributeAppender.Factory attributeAppenderFactory);

/**
* Appends the given method definition to this method registry, i.e. this configuration is applied last.
Expand All @@ -41,9 +39,7 @@ MethodRegistry prepend(LatentMethodMatcher methodMatcher,
* @param attributeAppenderFactory A method attribute appender to apply to any matched method.
* @return A mutated version of this method registry.
*/
MethodRegistry append(LatentMethodMatcher methodMatcher,
Handler handler,
MethodAttributeAppender.Factory attributeAppenderFactory);
MethodRegistry append(LatentMethodMatcher methodMatcher, Handler handler, MethodAttributeAppender.Factory attributeAppenderFactory);

/**
* Prepares this method registry.
Expand All @@ -53,9 +49,7 @@ MethodRegistry append(LatentMethodMatcher methodMatcher,
* @param methodFilter A filter that only matches methods that should be instrumented.
* @return A prepared version of this method registry.
*/
Prepared prepare(InstrumentedType instrumentedType,
MethodLookupEngine methodLookupEngine,
LatentMethodMatcher methodFilter);
Prepared prepare(InstrumentedType instrumentedType, MethodLookupEngine methodLookupEngine, LatentMethodMatcher methodFilter);

/**
* A handler for implementing a method.
Expand Down Expand Up @@ -89,7 +83,7 @@ interface Compiled {
* @param attributeAppender The method attribute appender to apply together with this handler.
* @return A method pool entry representing this handler and the given attribute appender.
*/
TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender);
TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender, MethodDescription methodDescription);
}

/**
Expand Down Expand Up @@ -122,8 +116,8 @@ public Compiled compile(Implementation.Target implementationTarget) {
}

@Override
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender) {
return new TypeWriter.MethodPool.Entry.ForAbstractMethod(attributeAppender, modifierResolver);
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender, MethodDescription methodDescription) {
return new TypeWriter.MethodPool.Entry.ForDeclaredMethod.WithoutBody(methodDescription, attributeAppender, modifierResolver);
}

@Override
Expand Down Expand Up @@ -228,8 +222,11 @@ protected Compiled(ByteCodeAppender byteCodeAppender, ModifierResolver modifierR
}

@Override
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender) {
return new TypeWriter.MethodPool.Entry.ForImplementation(byteCodeAppender, attributeAppender, modifierResolver);
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender, MethodDescription methodDescription) {
return new TypeWriter.MethodPool.Entry.ForDeclaredMethod.WithBody(methodDescription,
byteCodeAppender,
attributeAppender,
modifierResolver);
}

@Override
Expand Down Expand Up @@ -306,8 +303,11 @@ public Compiled compile(Implementation.Target implementationTarget) {
}

@Override
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender) {
return new TypeWriter.MethodPool.Entry.ForAnnotationDefaultValue(annotationValue, attributeAppender, modifierResolver);
public TypeWriter.MethodPool.Entry assemble(MethodAttributeAppender attributeAppender, MethodDescription methodDescription) {
return new TypeWriter.MethodPool.Entry.ForDeclaredMethod.WithAnnotationDefaultValue(methodDescription,
annotationValue,
attributeAppender,
modifierResolver);
}

@Override
Expand Down Expand Up @@ -651,20 +651,20 @@ public MethodList<?> getInstrumentedMethods() {
public MethodRegistry.Compiled compile(Implementation.Target.Factory implementationTargetFactory) {
Map<Handler, Handler.Compiled> compilationCache = new HashMap<Handler, Handler.Compiled>(implementations.size());
Map<MethodAttributeAppender.Factory, MethodAttributeAppender> attributeAppenderCache = new HashMap<MethodAttributeAppender.Factory, MethodAttributeAppender>(implementations.size());
LinkedHashMap<MethodDescription, TypeWriter.MethodPool.Entry> entries = new LinkedHashMap<MethodDescription, TypeWriter.MethodPool.Entry>(implementations.size());
LinkedHashMap<MethodDescription, Compiled.Entry> entries = new LinkedHashMap<MethodDescription, Compiled.Entry>(implementations.size());
Implementation.Target implementationTarget = implementationTargetFactory.make(finding, getInstrumentedMethods());
for (Map.Entry<MethodDescription, Entry> entry : implementations.entrySet()) {
Handler.Compiled cachedEntry = compilationCache.get(entry.getValue().getHandler());
if (cachedEntry == null) {
cachedEntry = entry.getValue().getHandler().compile(implementationTarget);
compilationCache.put(entry.getValue().getHandler(), cachedEntry);
Handler.Compiled cachedHandler = compilationCache.get(entry.getValue().getHandler());
if (cachedHandler == null) {
cachedHandler = entry.getValue().getHandler().compile(implementationTarget);
compilationCache.put(entry.getValue().getHandler(), cachedHandler);
}
MethodAttributeAppender cachedAttributeAppender = attributeAppenderCache.get(entry.getValue().getAppenderFactory());
if (cachedAttributeAppender == null) {
cachedAttributeAppender = entry.getValue().getAppenderFactory().make(finding.getTypeDescription());
attributeAppenderCache.put(entry.getValue().getAppenderFactory(), cachedAttributeAppender);
}
entries.put(entry.getKey(), cachedEntry.assemble(cachedAttributeAppender));
entries.put(entry.getKey(), new Compiled.Entry(cachedHandler, cachedAttributeAppender));
}
return new Compiled(finding.getTypeDescription(), loadedTypeInitializer, typeInitializer, entries);
}
Expand Down Expand Up @@ -764,11 +764,11 @@ public MethodList<?> getInstrumentedMethods() {
}

@Override
public Entry target(MethodDescription methodDescription) {
public TypeWriter.MethodPool.Entry target(MethodDescription methodDescription) {
Entry entry = implementations.get(methodDescription);
return entry == null
? Entry.ForSkippedMethod.INSTANCE
: entry;
? TypeWriter.MethodPool.Entry.ForInheritedMethod.INSTANCE
: entry.bind(methodDescription);
}

@Override
Expand Down Expand Up @@ -800,6 +800,46 @@ public String toString() {
", implementations=" + implementations +
'}';
}

protected static class Entry {

private final Handler.Compiled compiledHandler;

private final MethodAttributeAppender attributeAppender;

protected Entry(Handler.Compiled compiledHandler, MethodAttributeAppender attributeAppender) {
this.compiledHandler = compiledHandler;
this.attributeAppender = attributeAppender;
}

protected TypeWriter.MethodPool.Entry bind(MethodDescription methodDescription) {
return compiledHandler.assemble(attributeAppender, methodDescription);
}

@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
Entry entry = (Entry) other;
return compiledHandler.equals(entry.compiledHandler)
&& attributeAppender.equals(entry.attributeAppender);
}

@Override
public int hashCode() {
int result = compiledHandler.hashCode();
result = 31 * result + attributeAppender.hashCode();
return result;
}

@Override
public String toString() {
return "MethodRegistry.Default.Compiled.Entry{" +
"compiledHandler=" + compiledHandler +
", attributeAppender=" + attributeAppender +
'}';
}
}
}
}
}

0 comments on commit cefe63a

Please sign in to comment.