@@ -650,75 +650,59 @@ public static MyLogger dumpStatistics(JumpSolver checker, Set<Statement> soundly
650650
651651 log .info ("### Calculating statistics ###" );
652652
653- Set <Statement > unreachableJumpNodes = checker .getUnreachableJumps (); // LN: BOTTOM
654-
655- int resolved = 0 ; // LN: RESOLVED
656- int unreachable = 0 ; // LN: UNREACHABLE
657- int bottom = unreachableJumpNodes .size (); // LN: BOTTOM
658- int conservative = 0 ; // LN: CONSERVATIVE
659- final int maybeUnsoundJumps = 0 ; // checker.getMaybeUnsoundJumps().size();
660-
661653 if (cfg .getEntrypoints ().stream ().findAny ().isEmpty ()) {
662654 log .warn ("There are no entrypoints." );
663655 return null ;
664656 }
665657
666658 Statement entryPoint = cfg .getEntrypoints ().stream ().findAny ().get ();
659+ int total = cfg .getAllJumps ().size ();
660+ int resolved = 0 ;
661+ int unreachable = 0 ;
662+ int erroneous = 0 ;
663+ int unknown = 0 ;
667664
668665 // we are safe supposing that we have a single entry point
669- for (Statement jumpNode : cfg .getAllJumps ()) {
670- if ((jumpNode instanceof Jump ) || (jumpNode instanceof Jumpi )) {
671- boolean reachableFrom ;
672- int key = cfg .hashCode () + entryPoint .hashCode () + jumpNode .hashCode ();
673-
674- if (MyCache .getInstance ().existsInReachableFrom (key )) {
675- reachableFrom = MyCache .getInstance ().isReachableFrom (key ); // Caching
676- log .debug ("Value cached" );
677- } else {
678- reachableFrom = cfg .reachableFrom (entryPoint , jumpNode );
679- MyCache .getInstance ().addReachableFrom (key , reachableFrom );
680- }
681-
682- Set <StackElement > topStackValuesPerJump = checker .getTopStackValuesPerJump (jumpNode );
683-
684- if (cfg .getAllPushedJumps ().contains (jumpNode ))
685- resolved ++;
686- else if (checker .getMaybeUnsoundJumps ().contains (jumpNode ))
687- conservative ++;
688- else if (checker .getUnreachableJumps ().contains (jumpNode ) || !reachableFrom || topStackValuesPerJump .isEmpty ())
666+ for (Statement jumpNode : cfg .getAllJumps ())
667+ if ((jumpNode instanceof Jump ) || (jumpNode instanceof Jumpi ))
668+ if (!cfg .reachableFrom (entryPoint , jumpNode ) || checker .getUnreachableJumps ().contains (jumpNode ))
669+ // getUnreachableJumps() contains jumps where the whole value state went to bottom
689670 unreachable ++;
671+ else if (checker .getMaybeUnsoundJumps ().contains (jumpNode ))
672+ // getMaybeUnsoundJumps() contains jumps where the whole value state went to top
673+ unknown ++;
674+ else if (cfg .getAllPushedJumps ().contains (jumpNode ))
675+ // stacks of pushed jumps are not stored for optimization
676+ resolved ++;
690677 else {
691- boolean allBot = true , oneTop = false ;
692- for (StackElement e : topStackValuesPerJump ) {
693- allBot &= e .isBottom ();
694- oneTop |= e .isTop ();
695- }
696-
697- if (allBot )
698- bottom ++;
699- else if (oneTop )
700- conservative ++;
678+ Set <StackElement > topStacks = checker .getTopStackValuesPerJump (jumpNode );
679+ if (topStacks .isEmpty ())
680+ unreachable ++;
681+ else if (topStacks .stream ().allMatch (StackElement ::isBottom ))
682+ erroneous ++;
683+ else if (topStacks .stream ().anyMatch (StackElement ::isTop ))
684+ unknown ++;
701685 else
702686 resolved ++;
703687 }
704- }
705- }
706688
707689 log .info ("Total opcodes: {}" , cfg .getOpcodeCount ());
708- log .info ("Total jumps: {}" , cfg . getAllJumps (). size () );
690+ log .info ("Total jumps: {}" , total );
709691 log .info ("Resolved jumps: {}" , resolved );
692+ log .info ("Unknown jumps: {}" , unknown );
710693 log .info ("Unreachable jumps: {}" , unreachable );
711- log .info ("Bottom jumps: {}" , bottom );
712- log .info ("Conservative jumps: {}" , conservative );
694+ log .info ("Erroneous jumps: {}" , erroneous );
695+ int edges = cfg .getEdgesCount ();
696+ log .info ("Edges: {}" , edges );
713697
714698 return MyLogger .newLogger ()
715699 .opcodes (cfg .getOpcodeCount ())
716- .jumps (cfg . getAllJumps (). size () )
717- .preciselyResolvedJumps (resolved )
718- .definitelyUnreachableJumps (unreachable )
719- .maybeUnreachableJumps ( bottom )
720- .unsoundJumps ( conservative )
721- .maybeUnsoundJumps ( maybeUnsoundJumps );
700+ .jumps (total )
701+ .resolvedJumps (resolved )
702+ .unreachableJumps (unreachable )
703+ .erroneousJumps ( erroneous )
704+ .unknownJumps ( unknown )
705+ .edges ( edges );
722706 }
723707
724708 /**
@@ -812,10 +796,20 @@ public static void toFile(String FILE_PATH, String stats) {
812796 if (!idea .exists ()) {
813797 FileWriter myWriter = new FileWriter (idea , true );
814798
815- String init = "Smart Contract, Total Opcodes, Total Jumps, Solved Jumps, Definitely unreachable jumps, Maybe unreachable jumps, Total solved Jumps, "
816- + "Unsound jumps, Maybe unsound jumps, % Total Solved, Time (millis), Time lost to get Storage, Actual time, Notes \n " ;
817-
818- myWriter .write (init + stats );
799+ String header = "Smart Contract, "
800+ + "Total Opcodes, "
801+ + "Total Jumps, "
802+ + "Resolved Jumps, "
803+ + "Unknown jumps, "
804+ + "Unreachable jumps, "
805+ + "Erroneous Jumps, "
806+ + "Edges, "
807+ + "Time (millis), "
808+ + "Time lost to get Storage, "
809+ + "Actual time, "
810+ + "Notes" ;
811+
812+ myWriter .write (header + "\n " + stats );
819813 myWriter .close ();
820814
821815 } else {
0 commit comments