Preventing duplicate field access
This commit is contained in:
@@ -178,7 +178,7 @@ public class SimplifyExprentsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expr++ and expr--
|
// expr++ and expr--
|
||||||
if (isIPPorIMM(current, next)) {
|
if (isIPPorIMM(current, next) || isIPPorIMM2(current, next)) {
|
||||||
list.remove(index + 1);
|
list.remove(index + 1);
|
||||||
res = true;
|
res = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -458,6 +458,48 @@ public class SimplifyExprentsHelper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isIPPorIMM2(Exprent first, Exprent second) {
|
||||||
|
|
||||||
|
if (first.type != Exprent.EXPRENT_ASSIGNMENT || second.type != Exprent.EXPRENT_ASSIGNMENT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignmentExprent af = (AssignmentExprent)first;
|
||||||
|
AssignmentExprent as = (AssignmentExprent)second;
|
||||||
|
|
||||||
|
if(as.getRight().type != Exprent.EXPRENT_FUNCTION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionExprent func = (FunctionExprent)as.getRight();
|
||||||
|
|
||||||
|
if(func.getFuncType() != FunctionExprent.FUNCTION_ADD && func.getFuncType() != FunctionExprent.FUNCTION_SUB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Exprent econd = func.getLstOperands().get(0);
|
||||||
|
Exprent econst = func.getLstOperands().get(1);
|
||||||
|
|
||||||
|
if(econst.type != Exprent.EXPRENT_CONST && econd.type == Exprent.EXPRENT_CONST && func.getFuncType() == FunctionExprent.FUNCTION_ADD) {
|
||||||
|
econd = econst;
|
||||||
|
econst = func.getLstOperands().get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(econst.type == Exprent.EXPRENT_CONST && ((ConstExprent)econst).hasValueOne()) {
|
||||||
|
if(af.getLeft().equals(econd) && af.getRight().equals(as.getLeft()) && (af.getLeft().getExprentUse() & Exprent.MULTIPLE_USES) != 0) {
|
||||||
|
int type = func.getFuncType() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_IPP : FunctionExprent.FUNCTION_IMM;
|
||||||
|
|
||||||
|
FunctionExprent ret = new FunctionExprent(type, af.getRight(), func.bytecode);
|
||||||
|
ret.setImplicitType(VarType.VARTYPE_INT);
|
||||||
|
|
||||||
|
af.setRight(ret);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isMonitorExit(Exprent first) {
|
private static boolean isMonitorExit(Exprent first) {
|
||||||
if (first.type == Exprent.EXPRENT_MONITOR) {
|
if (first.type == Exprent.EXPRENT_MONITOR) {
|
||||||
MonitorExprent expr = (MonitorExprent)first;
|
MonitorExprent expr = (MonitorExprent)first;
|
||||||
|
|||||||
@@ -134,8 +134,9 @@ public class DominatorTreeExceptionFilter {
|
|||||||
exit = childid;
|
exit = childid;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// exit = map.containsKey(handler)?-1:mapChild.get(handler); FIXME: Eclipse bug?
|
// after replacing 'new Integer(-1)' with '-1' Eclipse throws a NullPointerException on the following line
|
||||||
exit = map.containsKey(handler) ? -1 : mapChild.get(handler);
|
// could be a bug in Eclipse or some obscure specification glitch, FIXME: needs further investigation
|
||||||
|
exit = map.containsKey(handler) ? new Integer(-1) : mapChild.get(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit != null) {
|
if (exit != null) {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class FieldExprent extends Exprent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getExprentUse() {
|
public int getExprentUse() {
|
||||||
return instance == null ? Exprent.MULTIPLE_USES : instance.getExprentUse() & Exprent.MULTIPLE_USES;
|
return 0; // multiple references to a field considered dangerous in a multithreaded environment, thus no Exprent.MULTIPLE_USES set here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
BIN
testData/classes/pkg/TestFieldSingleAccess.class
Normal file
BIN
testData/classes/pkg/TestFieldSingleAccess.class
Normal file
Binary file not shown.
40
testData/results/TestFieldSingleAccess.dec
Normal file
40
testData/results/TestFieldSingleAccess.dec
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package pkg;
|
||||||
|
|
||||||
|
public final class TestFieldSingleAccess {
|
||||||
|
public Integer field;
|
||||||
|
|
||||||
|
public final void test() {
|
||||||
|
Integer var10000 = this.field;
|
||||||
|
if (var10000 != null) {
|
||||||
|
System.out.println(var10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void test1() {
|
||||||
|
synchronized(this.field) {
|
||||||
|
System.out.println('1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class 'pkg/TestFieldSingleAccess' {
|
||||||
|
method 'test ()V' {
|
||||||
|
1 6
|
||||||
|
5 7
|
||||||
|
8 8
|
||||||
|
c 8
|
||||||
|
f 11
|
||||||
|
}
|
||||||
|
|
||||||
|
method 'test1 ()V' {
|
||||||
|
1 14
|
||||||
|
6 14
|
||||||
|
7 15
|
||||||
|
a 15
|
||||||
|
c 15
|
||||||
|
19 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lines mapping:
|
||||||
@@ -3,7 +3,6 @@ public class TestMethodReferenceSameName {
|
|||||||
|
|
||||||
private void foo() {
|
private void foo() {
|
||||||
TestMethodReferenceSameName.R1 var10000 = this.r;// 5
|
TestMethodReferenceSameName.R1 var10000 = this.r;// 5
|
||||||
this.r.getClass();
|
|
||||||
(var10000::foo).run();
|
(var10000::foo).run();
|
||||||
}// 6
|
}// 6
|
||||||
|
|
||||||
@@ -16,19 +15,18 @@ public class TestMethodReferenceSameName {
|
|||||||
class 'TestMethodReferenceSameName' {
|
class 'TestMethodReferenceSameName' {
|
||||||
method 'foo ()V' {
|
method 'foo ()V' {
|
||||||
1 4
|
1 4
|
||||||
5 5
|
e 5
|
||||||
e 6
|
13 6
|
||||||
13 7
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class 'TestMethodReferenceSameName$R1' {
|
class 'TestMethodReferenceSameName$R1' {
|
||||||
method 'foo ()V' {
|
method 'foo ()V' {
|
||||||
0 11
|
0 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Lines mapping:
|
Lines mapping:
|
||||||
5 <-> 5
|
5 <-> 5
|
||||||
6 <-> 8
|
6 <-> 7
|
||||||
9 <-> 12
|
9 <-> 11
|
||||||
|
|||||||
67
testData/src/pkg/TestFieldSingleAccess.jasm
Normal file
67
testData/src/pkg/TestFieldSingleAccess.jasm
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* This code can be assembled with <a href="https://wiki.openjdk.java.net/display/CodeTools/asmtools">asmtools</a>
|
||||||
|
* using <code>asmtools jasm -g *.jasm</code> command line.
|
||||||
|
*/
|
||||||
|
package pkg;
|
||||||
|
|
||||||
|
super public final class TestFieldSingleAccess
|
||||||
|
version 52:0
|
||||||
|
{
|
||||||
|
|
||||||
|
public Field field:"Ljava/lang/Integer;";
|
||||||
|
|
||||||
|
public Method "<init>":"()V"
|
||||||
|
stack 1 locals 1
|
||||||
|
{
|
||||||
|
aload_0;
|
||||||
|
invokespecial Method java/lang/Object."<init>":"()V";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Method test:"()V"
|
||||||
|
stack 2 locals 1
|
||||||
|
{
|
||||||
|
aload_0;
|
||||||
|
getfield Field field:"Ljava/lang/Integer;";
|
||||||
|
dup;
|
||||||
|
ifnull L17;
|
||||||
|
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
|
||||||
|
swap;
|
||||||
|
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/Object;)V";
|
||||||
|
L17: stack_frame_type same;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Method test1:"()V"
|
||||||
|
stack 2 locals 3
|
||||||
|
{
|
||||||
|
aload_0;
|
||||||
|
getfield Field field:"Ljava/lang/Integer;";
|
||||||
|
dup;
|
||||||
|
astore_1;
|
||||||
|
monitorenter;
|
||||||
|
try t0;
|
||||||
|
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
|
||||||
|
bipush 49;
|
||||||
|
invokevirtual Method java/io/PrintStream.println:"(C)V";
|
||||||
|
aload_1;
|
||||||
|
monitorexit;
|
||||||
|
endtry t0;
|
||||||
|
goto L25;
|
||||||
|
catch t0 #0;
|
||||||
|
catch t1 #0;
|
||||||
|
try t1;
|
||||||
|
stack_frame_type full;
|
||||||
|
locals_map class TestFieldSingleAccess, class java/lang/Object;
|
||||||
|
stack_map class java/lang/Throwable;
|
||||||
|
astore_2;
|
||||||
|
aload_1;
|
||||||
|
monitorexit;
|
||||||
|
endtry t1;
|
||||||
|
aload_2;
|
||||||
|
athrow;
|
||||||
|
L25: stack_frame_type chop1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end Class TestFieldSingleAccess
|
||||||
Reference in New Issue
Block a user