XXX WIP TOTALLYWRONG. pmes are stopping prematurely because returnTo is not being kept across frame dups. if I enable it, i get assert fails on frame.other.
This also always steps into invokestatics, for when two are invoked but not really the same function.
This commit is contained in:
@@ -31,6 +31,7 @@ public class Frame
|
|||||||
private Frame caller;
|
private Frame caller;
|
||||||
public Frame other; // in the other execution for mapping
|
public Frame other; // in the other execution for mapping
|
||||||
public Frame returnTo; // is this the same as caller?
|
public Frame returnTo; // is this the same as caller?
|
||||||
|
public Frame otherStatic;
|
||||||
|
|
||||||
public Frame(Execution execution, Method method)
|
public Frame(Execution execution, Method method)
|
||||||
{
|
{
|
||||||
@@ -118,6 +119,8 @@ public class Frame
|
|||||||
this.ctx = other.ctx;
|
this.ctx = other.ctx;
|
||||||
this.nonStatic = other.nonStatic;
|
this.nonStatic = other.nonStatic;
|
||||||
this.caller = other.caller;
|
this.caller = other.caller;
|
||||||
|
if (other.returnTo != null)
|
||||||
|
this.returnTo = new Frame(other.returnTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Frame dup()
|
public Frame dup()
|
||||||
|
|||||||
@@ -41,23 +41,90 @@ public class ParallellMappingExecutor
|
|||||||
// as not executing
|
// as not executing
|
||||||
if (!f1.isExecuting() || !f2.isExecuting())
|
if (!f1.isExecuting() || !f2.isExecuting())
|
||||||
{
|
{
|
||||||
|
assert f1.returnTo == null || !e.frames.contains(f1.returnTo);
|
||||||
|
assert f2.returnTo == null || !e2.frames.contains(f2.returnTo);
|
||||||
|
|
||||||
|
// I dont know if this is necessary.
|
||||||
|
if (f1.getInstructions().size() > 0)
|
||||||
|
{
|
||||||
|
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
|
||||||
|
|
||||||
|
for (Frame branch : p1.getBranches())
|
||||||
|
{
|
||||||
|
e.frames.remove(branch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f2.getInstructions().size() > 0)
|
||||||
|
{
|
||||||
|
p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
|
||||||
|
|
||||||
|
for (Frame branch : p2.getBranches())
|
||||||
|
{
|
||||||
|
e2.frames.remove(branch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert e.frames.get(0) == f1;
|
assert e.frames.get(0) == f1;
|
||||||
assert e2.frames.get(0) == f2;
|
assert e2.frames.get(0) == f2;
|
||||||
|
|
||||||
e.frames.remove(0);
|
e.frames.remove(0);
|
||||||
e2.frames.remove(0);
|
e2.frames.remove(0);
|
||||||
|
|
||||||
|
//assert (f1.returnTo != null) == (f2.returnTo != null);
|
||||||
|
// boolean exit1 = !f1.isExecuting() && f1.returnTo != null,
|
||||||
|
// exit2 = !f2.isExecuting() && f2.returnTo != null;
|
||||||
|
//
|
||||||
|
// if (exit1 && exit2)
|
||||||
|
// {
|
||||||
|
//removeOrPop(e, f1);
|
||||||
|
//removeOrPop(e2, f2);
|
||||||
|
// }
|
||||||
|
// else if (exit1)
|
||||||
|
// {
|
||||||
|
// removeOrPop(e, f1);
|
||||||
|
// }
|
||||||
|
// else if (exit2)
|
||||||
|
// {
|
||||||
|
// removeOrPop(e2, f2);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// assert false;
|
||||||
|
// }
|
||||||
|
|
||||||
return step();
|
return step();
|
||||||
}
|
}
|
||||||
|
|
||||||
// step frame
|
// step frame
|
||||||
if (step1)
|
if (step1)
|
||||||
f1.execute();
|
f1.execute();
|
||||||
|
else
|
||||||
|
step1 = true;
|
||||||
|
|
||||||
if (step2)
|
if (step2)
|
||||||
f2.execute();
|
f2.execute();
|
||||||
|
else
|
||||||
|
step2 = true;
|
||||||
|
|
||||||
|
Frame oldf1 = f1, oldf2 = f2;
|
||||||
|
|
||||||
f1 = popStack(f1);
|
f1 = popStack(f1);
|
||||||
f2 = popStack(f2);
|
f2 = popStack(f2);
|
||||||
|
|
||||||
|
if (oldf1 != f1 || oldf2 != f2)
|
||||||
|
{
|
||||||
|
// assert oldf1 != f1;
|
||||||
|
// assert oldf2 != f2;
|
||||||
|
//
|
||||||
|
// Method m1 = oldf1.getMethod(), m2 = oldf2.getMethod();
|
||||||
|
//
|
||||||
|
// System.out.println("RETURN MAP " + m1 + " -> " + m2);
|
||||||
|
//
|
||||||
|
// // if one exits and the other doesnt, the functions arent equal
|
||||||
|
// assert oldf1.otherStatic == oldf2;
|
||||||
|
// assert oldf2.otherStatic == oldf1;
|
||||||
|
}
|
||||||
|
|
||||||
// get what each frame is paused/exited on
|
// get what each frame is paused/exited on
|
||||||
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
|
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
|
||||||
@@ -68,77 +135,48 @@ public class ParallellMappingExecutor
|
|||||||
// of the jump
|
// of the jump
|
||||||
if (!f1.isExecuting() || !f2.isExecuting())
|
if (!f1.isExecuting() || !f2.isExecuting())
|
||||||
{
|
{
|
||||||
for (Frame branch : p1.getBranches())
|
|
||||||
{
|
|
||||||
e.frames.remove(branch);
|
|
||||||
}
|
|
||||||
for (Frame branch : p2.getBranches())
|
|
||||||
{
|
|
||||||
e2.frames.remove(branch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println("Something exited " + f1 + " " + f2);
|
|
||||||
|
|
||||||
assert e.frames.get(0) == f1;
|
|
||||||
assert e2.frames.get(0) == f2;
|
|
||||||
|
|
||||||
e.frames.remove(0);
|
|
||||||
e2.frames.remove(0);
|
|
||||||
|
|
||||||
return step();
|
return step();
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame oldf1 = f1, oldf2 = f2;
|
|
||||||
if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && !MappingExecutorUtil.isInlineable(p2.getInstruction()))
|
if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && !MappingExecutorUtil.isInlineable(p2.getInstruction()))
|
||||||
{
|
{
|
||||||
f1 = stepInto(f1);
|
f1 = stepInto(f1);
|
||||||
try
|
|
||||||
{
|
//try
|
||||||
|
//{
|
||||||
step2 = false;
|
step2 = false;
|
||||||
return step();
|
return step();
|
||||||
}
|
// }
|
||||||
finally
|
// finally
|
||||||
{
|
// {
|
||||||
step2 = true;
|
// step2 = true;
|
||||||
}
|
// }
|
||||||
//f1 = popStack(f1);
|
|
||||||
//p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
|
|
||||||
}
|
}
|
||||||
else if (MappingExecutorUtil.isInlineable(p2.getInstruction()) && !MappingExecutorUtil.isInlineable(p1.getInstruction()))
|
else if (MappingExecutorUtil.isInlineable(p2.getInstruction()) && !MappingExecutorUtil.isInlineable(p1.getInstruction()))
|
||||||
{
|
{
|
||||||
f2 = stepInto(f2);
|
f2 = stepInto(f2);
|
||||||
//f2 = popStack(f2);
|
|
||||||
//p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
|
//try
|
||||||
try
|
//{
|
||||||
{
|
|
||||||
step1 = false;
|
step1 = false;
|
||||||
return step();
|
return step();
|
||||||
}
|
// }
|
||||||
finally
|
// finally
|
||||||
{
|
// {
|
||||||
step1 = true;
|
// step1 = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && MappingExecutorUtil.isInlineable(p2.getInstruction()))
|
else if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && MappingExecutorUtil.isInlineable(p2.getInstruction()))
|
||||||
{
|
{
|
||||||
// p1s func might equal p2s func
|
Frame stepf1 = stepInto(f1);
|
||||||
|
Frame stepf2 = stepInto(f2);
|
||||||
|
|
||||||
// step into both at once, and insert to beginning of e.frames
|
stepf1.otherStatic = stepf2;
|
||||||
|
stepf2.otherStatic = stepf1;
|
||||||
|
|
||||||
// when two funcs exit at once, map them then (if static?)
|
System.out.println("STEP " + stepf1.getMethod() + " <-> " + stepf2.getMethod());
|
||||||
|
|
||||||
// f1 = stepInto(f1);
|
return step();
|
||||||
// f1 = popStack(f1);
|
|
||||||
// p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
|
|
||||||
//
|
|
||||||
// f2 = stepInto(f2);
|
|
||||||
// f2 = popStack(f2);
|
|
||||||
// p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p1.getInstruction() instanceof InvokeSpecial && p2.getInstruction() instanceof InvokeStatic)
|
|
||||||
{
|
|
||||||
int i = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert e.paused;
|
assert e.paused;
|
||||||
@@ -171,8 +209,6 @@ public class ParallellMappingExecutor
|
|||||||
List<Method> methods = is.getMethods();
|
List<Method> methods = is.getMethods();
|
||||||
|
|
||||||
assert methods.size() == 1;
|
assert methods.size() == 1;
|
||||||
//if (methods.isEmpty()) // not my method
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
Method to = is.getMethods().get(0);
|
Method to = is.getMethods().get(0);
|
||||||
|
|
||||||
@@ -191,9 +227,6 @@ public class ParallellMappingExecutor
|
|||||||
|
|
||||||
f2.returnTo = new Frame(f); // where to go when we're done
|
f2.returnTo = new Frame(f); // where to go when we're done
|
||||||
|
|
||||||
// step new frame
|
|
||||||
//f2.execute();
|
|
||||||
|
|
||||||
return f2;
|
return f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +241,20 @@ public class ParallellMappingExecutor
|
|||||||
if (!(i.getInstruction() instanceof ReturnInstruction))
|
if (!(i.getInstruction() instanceof ReturnInstruction))
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
|
f = popStackForce(f);
|
||||||
|
|
||||||
|
// step return frame
|
||||||
|
f.execute();
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Frame popStackForce(Frame f)
|
||||||
|
{
|
||||||
|
Execution e = f.getExecution();
|
||||||
|
|
||||||
|
assert f.returnTo != null;
|
||||||
|
|
||||||
assert e.frames.contains(f);
|
assert e.frames.contains(f);
|
||||||
assert !e.frames.contains(f.returnTo);
|
assert !e.frames.contains(f.returnTo);
|
||||||
|
|
||||||
@@ -226,8 +273,30 @@ public class ParallellMappingExecutor
|
|||||||
f.other = null;
|
f.other = null;
|
||||||
|
|
||||||
// step return frame
|
// step return frame
|
||||||
f.returnTo.execute();
|
//f.returnTo.execute();
|
||||||
|
|
||||||
return f.returnTo;
|
return f.returnTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeOrPop(Execution e, Frame f)
|
||||||
|
{
|
||||||
|
// get what each frame is paused/exited on
|
||||||
|
InstructionContext p = f.getInstructions().get(f.getInstructions().size() - 1);
|
||||||
|
|
||||||
|
for (Frame branch : p.getBranches())
|
||||||
|
{
|
||||||
|
e.frames.remove(branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.returnTo != null)
|
||||||
|
{
|
||||||
|
popStackForce(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert e.frames.get(0) == f;
|
||||||
|
|
||||||
|
e.frames.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ public class MapStaticTest
|
|||||||
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
||||||
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
||||||
|
|
||||||
Method m1 = group1.findClass("class183").findMethod("method3685");
|
Method m1 = group1.findClass("client").findMethod("vmethod3096");
|
||||||
Method m2 = group2.findClass("class183").findMethod("method3560");
|
Method m2 = group2.findClass("client").findMethod("vmethod2975");
|
||||||
|
|
||||||
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
|
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ public class MapStaticTest
|
|||||||
map(all, new HashSet(), m1, m2);
|
map(all, new HashSet(), m1, m2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
//@Test
|
||||||
public void testAllDeep() throws IOException
|
public void testAllDeep() throws IOException
|
||||||
{
|
{
|
||||||
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
||||||
|
|||||||
Reference in New Issue
Block a user