Skip to content

Commit 8d073f5

Browse files
committed
Align ASM5 provider with ASMX provider
1 parent 8dd5e94 commit 8d073f5

File tree

8 files changed

+146
-78
lines changed

8 files changed

+146
-78
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,24 @@
1+
/**
2+
* Copyright 2013-2019 Valery Silaev (http://vsilaev.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package org.apache.commons.javaflow.providers.asm5;
217

3-
import java.io.IOException;
4-
5-
import org.apache.commons.javaflow.spi.Cache;
6-
import org.apache.commons.javaflow.spi.ClassMatcher;
7-
import org.apache.commons.javaflow.spi.ClassMatchers;
818
import org.apache.commons.javaflow.spi.ResourceLoader;
919
import org.apache.commons.javaflow.spi.ResourceTransformationFactory;
10-
import org.apache.commons.javaflow.spi.ResourceTransformer;
11-
import org.apache.commons.javaflow.spi.VetoableResourceLoader;
1220

1321
public abstract class AbstractResourceTransformationFactory implements ResourceTransformationFactory {
14-
15-
public ResourceTransformer createTransformer(ResourceLoader resourceLoader) {
16-
SharedContinuableClassInfos cciShared = CACHED_SHARED_CCI.get(resourceLoader);
17-
return createTransformer(
18-
resourceLoader,
19-
new IContinuableClassInfoResolver(resourceLoader, cciShared),
20-
// Actualize ClassHierarchy per resource loader
21-
cciShared.hierarchy().shareWith(resourceLoader)
22-
);
23-
}
24-
25-
abstract protected ResourceTransformer createTransformer(ResourceLoader resourceLoader,
26-
ContinuableClassInfoResolver resolver,
27-
ClassHierarchy classHierarchy);
28-
29-
public ContinuableClassInfoResolver createResolver(ResourceLoader resourceLoader) {
30-
return new IContinuableClassInfoResolver(
31-
resourceLoader,
32-
CACHED_SHARED_CCI.get(resourceLoader)
33-
);
34-
}
35-
36-
static ClassMatcher createVeto(ResourceLoader resourceLoader) {
37-
if (resourceLoader instanceof VetoableResourceLoader) {
38-
try {
39-
return ((VetoableResourceLoader)resourceLoader).createVeto();
40-
} catch (IOException ex) {
41-
throw new RuntimeException(ex);
42-
}
43-
} else {
44-
return ClassMatchers.MATCH_NONE;
45-
}
46-
}
4722

48-
private static final Cache<ResourceLoader, SharedContinuableClassInfos> CACHED_SHARED_CCI =
49-
new Cache<ResourceLoader, SharedContinuableClassInfos>() {
50-
@Override
51-
protected SharedContinuableClassInfos createValue(ResourceLoader loader) {
52-
return new SharedContinuableClassInfos(
53-
new ClassHierarchy(loader), createVeto(loader)
54-
);
55-
}
56-
};
23+
public abstract ContinuableClassInfoResolver createResolver(ResourceLoader resourceLoader);
5724
}

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/Asm5ResourceTransformationFactory.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import org.apache.commons.javaflow.spi.ResourceLoader;
1919
import org.apache.commons.javaflow.spi.ResourceTransformer;
2020

21-
public class Asm5ResourceTransformationFactory extends AbstractResourceTransformationFactory {
21+
public class Asm5ResourceTransformationFactory extends PartialResourceTransformationFactory {
2222

23-
protected ResourceTransformer createTransformer(ResourceLoader resourceLoader,
24-
ContinuableClassInfoResolver resolver,
25-
ClassHierarchy classHierarchy) {
26-
27-
return new ContinuableClassTransformer(classHierarchy, (IContinuableClassInfoResolver)resolver);
23+
public ResourceTransformer createTransformer(ResourceLoader resourceLoader) {
24+
SharedContinuableClassInfos sharedState = getCached(resourceLoader);
25+
return new ContinuableClassTransformer(
26+
// Actualize ClassHierarchy per resource loader
27+
sharedState.hierarchy().shareWith(resourceLoader),
28+
new IContinuableClassInfoResolver(resourceLoader, sharedState)
29+
);
2830
}
2931

3032
}

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/ContinuableClassInfoResolver.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
public interface ContinuableClassInfoResolver {
2222
ContinuableClassInfo resolve(String className) throws IOException;
2323

24-
ContinuableClassInfo resolve(String className, byte[] classBytes);
25-
2624
boolean isContinuableAnnotation(String annotationClassDescriptor);
2725

2826
void reset(Collection<String> classNames);

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/ContinuableClassTransformer.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,17 @@ class ContinuableClassTransformer extends AbstractResourceTransformer {
4646
}
4747

4848
public byte[] transform(byte[] original, Collection<String> retransformClasses) {
49-
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES) {
50-
@Override
51-
protected String getCommonSuperClass(final String type1, final String type2) {
52-
return classHierarchy.getCommonSuperClass(type1, type2);
53-
}
54-
};
55-
cciResolver.reset(retransformClasses);
49+
ClassReader reader = new ClassReader(original);
50+
ClassWriter writer = new OfflineClassWriter(classHierarchy, reader, ClassWriter.COMPUTE_FRAMES);
5651
ContinuableClassVisitor visitor = new ContinuableClassVisitor(
57-
cw /* BytecodeDebugUtils.decorateClassVisitor(cw, true, * System.err) -- DUMP*/,
52+
writer, /* BytecodeDebugUtils.decorateClassVisitor(cw, true, * System.err) -- DUMP*/
5853
classHierarchy,
5954
cciResolver,
6055
original
6156
);
57+
cciResolver.reset(retransformClasses);
6258
try {
63-
new ClassReader(original).accept(visitor, ClassReader.SKIP_FRAMES);
59+
reader.accept(visitor, ClassReader.SKIP_FRAMES);
6460
} catch (StopException ex) {
6561
// Preliminary stop visiting non-continuable class
6662
return null;
@@ -70,7 +66,7 @@ protected String getCommonSuperClass(final String type1, final String type2) {
7066
return null;
7167
}
7268

73-
byte[] bytecode = cw.toByteArray();
69+
byte[] bytecode = writer.toByteArray();
7470
// BytecodeDebugUtils.dumpClass(bytecode);
7571
return bytecode;
7672
}

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/ContinuableClassVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class ContinuableClassVisitor extends ClassVisitor {
3939

4040
private final ClassHierarchy classHierarchy;
4141
private final IContinuableClassInfoResolver cciResolver;
42-
private final byte[] originalBytes;
43-
42+
43+
private byte[] originalBytes;
4444
private String className;
4545
private IContinuableClassInfo classInfo;
4646
private boolean skipEnchancing = false;
@@ -63,6 +63,7 @@ boolean skipEnchancing() {
6363
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
6464
className = name;
6565
classInfo = cciResolver.resolve(name, originalBytes);
66+
originalBytes = null; // reclaim memory
6667

6768
if (null == classInfo ||
6869
classInfo.isClassProcessed() ||

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/IContinuableClassInfoResolver.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ class IContinuableClassInfoResolver implements ContinuableClassInfoResolver {
4343
this.cciShared = cciShared;
4444
}
4545

46-
public IContinuableClassInfo resolve(String classInternalName, byte[] classBytes) {
47-
IContinuableClassInfo classInfo = getResolved(classInternalName);
48-
if (classInfo == null) {
49-
return resolveContinuableClassInfo(classInternalName, new ClassReader(classBytes));
50-
} else {
51-
return unmask(classInfo);
52-
}
53-
}
54-
5546
public IContinuableClassInfo resolve(String classInternalName) throws IOException {
5647
IContinuableClassInfo classInfo = getResolved(classInternalName);
5748
if (classInfo == null) {
@@ -104,6 +95,15 @@ public void reset(Collection<String> classNames) {
10495
refreshClasses.addAll(classNames);
10596
}
10697

98+
IContinuableClassInfo resolve(String classInternalName, byte[] classBytes) {
99+
IContinuableClassInfo classInfo = getResolved(classInternalName);
100+
if (classInfo == null) {
101+
return resolveContinuableClassInfo(classInternalName, new ClassReader(classBytes));
102+
} else {
103+
return unmask(classInfo);
104+
}
105+
}
106+
107107
ClassMatcher veto() {
108108
return cciShared.veto();
109109
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright 2013-2019 Valery Silaev (http://vsilaev.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.commons.javaflow.providers.asm5;
17+
18+
import org.objectweb.asm.ClassReader;
19+
import org.objectweb.asm.ClassWriter;
20+
21+
public class OfflineClassWriter extends ClassWriter {
22+
private final ClassHierarchy classHierarchy;
23+
24+
public OfflineClassWriter(ClassHierarchy classHierarchy, int flags) {
25+
super(flags);
26+
this.classHierarchy = classHierarchy;
27+
}
28+
29+
public OfflineClassWriter(ClassHierarchy classHierarchy, ClassReader reader, int flags) {
30+
super(reader, flags);
31+
this.classHierarchy = classHierarchy;
32+
}
33+
34+
@Override
35+
protected String getCommonSuperClass(final String type1, final String type2) {
36+
return classHierarchy.getCommonSuperClass(type1, type2);
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Copyright 2013-2019 Valery Silaev (http://vsilaev.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.commons.javaflow.providers.asm5;
17+
18+
import java.io.IOException;
19+
20+
import org.apache.commons.javaflow.spi.Cache;
21+
import org.apache.commons.javaflow.spi.ClassMatcher;
22+
import org.apache.commons.javaflow.spi.ClassMatchers;
23+
import org.apache.commons.javaflow.spi.ResourceLoader;
24+
import org.apache.commons.javaflow.spi.ResourceTransformer;
25+
import org.apache.commons.javaflow.spi.VetoableResourceLoader;
26+
27+
public class PartialResourceTransformationFactory extends AbstractResourceTransformationFactory {
28+
29+
public ResourceTransformer createTransformer(ResourceLoader resourceLoader) {
30+
throw new UnsupportedOperationException();
31+
}
32+
33+
public ContinuableClassInfoResolver createResolver(ResourceLoader resourceLoader) {
34+
return new IContinuableClassInfoResolver(
35+
resourceLoader,
36+
CACHED_SHARED.get(resourceLoader)
37+
);
38+
}
39+
40+
static SharedContinuableClassInfos getCached(ResourceLoader resourceLoader) {
41+
return CACHED_SHARED.get(resourceLoader);
42+
}
43+
44+
static ClassMatcher createVeto(ResourceLoader resourceLoader) {
45+
if (resourceLoader instanceof VetoableResourceLoader) {
46+
try {
47+
return ((VetoableResourceLoader)resourceLoader).createVeto();
48+
} catch (IOException ex) {
49+
throw new RuntimeException(ex);
50+
}
51+
} else {
52+
return ClassMatchers.MATCH_NONE;
53+
}
54+
}
55+
56+
private static final Cache<ResourceLoader, SharedContinuableClassInfos> CACHED_SHARED =
57+
new Cache<ResourceLoader, SharedContinuableClassInfos>() {
58+
@Override
59+
protected SharedContinuableClassInfos createValue(ResourceLoader loader) {
60+
return new SharedContinuableClassInfos(
61+
new ClassHierarchy(loader), createVeto(loader)
62+
);
63+
}
64+
};
65+
66+
}

0 commit comments

Comments
 (0)