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:
Adam
2016-01-31 20:49:54 -05:00
parent 8e73f37eba
commit 9d3ba7e1cf
3 changed files with 133 additions and 61 deletions

View File

@@ -31,6 +31,7 @@ public class Frame
private Frame caller;
public Frame other; // in the other execution for mapping
public Frame returnTo; // is this the same as caller?
public Frame otherStatic;
public Frame(Execution execution, Method method)
{
@@ -118,6 +119,8 @@ public class Frame
this.ctx = other.ctx;
this.nonStatic = other.nonStatic;
this.caller = other.caller;
if (other.returnTo != null)
this.returnTo = new Frame(other.returnTo);
}
public Frame dup()

View File

@@ -41,23 +41,90 @@ public class ParallellMappingExecutor
// as not executing
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 e2.frames.get(0) == f2;
e.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();
}
// step frame
if (step1)
f1.execute();
else
step1 = true;
if (step2)
f2.execute();
else
step2 = true;
Frame oldf1 = f1, oldf2 = f2;
f1 = popStack(f1);
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
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
@@ -68,77 +135,48 @@ public class ParallellMappingExecutor
// of the jump
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();
}
Frame oldf1 = f1, oldf2 = f2;
if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && !MappingExecutorUtil.isInlineable(p2.getInstruction()))
{
f1 = stepInto(f1);
try
{
//try
//{
step2 = false;
return step();
}
finally
{
step2 = true;
}
//f1 = popStack(f1);
//p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
// }
// finally
// {
// step2 = true;
// }
}
else if (MappingExecutorUtil.isInlineable(p2.getInstruction()) && !MappingExecutorUtil.isInlineable(p1.getInstruction()))
{
f2 = stepInto(f2);
//f2 = popStack(f2);
//p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
try
{
//try
//{
step1 = false;
return step();
}
finally
{
step1 = true;
}
// }
// finally
// {
// step1 = true;
// }
}
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);
// 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;
return step();
}
assert e.paused;
@@ -171,8 +209,6 @@ public class ParallellMappingExecutor
List<Method> methods = is.getMethods();
assert methods.size() == 1;
//if (methods.isEmpty()) // not my method
// return null;
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
// step new frame
//f2.execute();
return f2;
}
@@ -208,6 +241,20 @@ public class ParallellMappingExecutor
if (!(i.getInstruction() instanceof ReturnInstruction))
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.returnTo);
@@ -226,8 +273,30 @@ public class ParallellMappingExecutor
f.other = null;
// step return frame
f.returnTo.execute();
//f.returnTo.execute();
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);
}
}
}

View File

@@ -85,8 +85,8 @@ public class MapStaticTest
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
Method m1 = group1.findClass("class183").findMethod("method3685");
Method m2 = group2.findClass("class183").findMethod("method3560");
Method m1 = group1.findClass("client").findMethod("vmethod3096");
Method m2 = group2.findClass("client").findMethod("vmethod2975");
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
@@ -114,7 +114,7 @@ public class MapStaticTest
map(all, new HashSet(), m1, m2);
}
@Test
//@Test
public void testAllDeep() throws IOException
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));