Skip to content

Commit

Permalink
Merge pull request #1043 from soot-oss/1035-feature-get-performance-o…
Browse files Browse the repository at this point in the history
…f-bodyinterceptors-runtime-and-memory-consumption

runtime & memory usage to body interceptors
  • Loading branch information
sahilagichani14 authored Aug 29, 2024
2 parents 0d61546 + 27a066a commit 44526c5
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package sootup.core.transform;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2024 Sahil Agichani
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

public class BodyInterceptorMetric {

private long runtime;
private long memoryUsage;

public BodyInterceptorMetric(long runtime, long memoryUsage) {
this.runtime = runtime;
this.memoryUsage = memoryUsage;
}

public long getRuntime() {
return runtime;
}

public void setRuntime(long runtime) {
this.runtime = runtime;
}

public long getMemoryUsage() {
return memoryUsage;
}

public void setMemoryUsage(long memoryUsage) {
this.memoryUsage = memoryUsage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package sootup.core.transform;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2024 Sahil Agichani
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import javax.annotation.Nonnull;
import sootup.core.model.Body;
import sootup.core.views.View;

public class RunTimeBodyInterceptor implements BodyInterceptor {

private BodyInterceptorMetric biMetric = new BodyInterceptorMetric(0L, 0L);

private final BodyInterceptor bodyInterceptor;

public RunTimeBodyInterceptor(BodyInterceptor bodyInterceptor) {
this.bodyInterceptor = bodyInterceptor;
}

public BodyInterceptorMetric getBiMetric() {
return biMetric;
}

public BodyInterceptor getBodyInterceptor() {
return bodyInterceptor;
}

@Override
public void interceptBody(@Nonnull Body.BodyBuilder builder, @Nonnull View view) {
long startTime = System.currentTimeMillis(); // Start time
final int MB = 1024 * 1024;
Runtime runtime = Runtime.getRuntime();
long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();

bodyInterceptor.interceptBody(builder, view);

long endTime = System.currentTimeMillis(); // End time
long duration = endTime - startTime;
long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
long memoryUsed = (usedMemoryAfter - usedMemoryBefore) / MB;

biMetric.setRuntime(biMetric.getRuntime() + duration);
biMetric.setMemoryUsage(biMetric.getMemoryUsage() + memoryUsed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
Expand All @@ -14,12 +16,16 @@
import sootup.core.model.SootMethod;
import sootup.core.model.SourceType;
import sootup.core.transform.BodyInterceptor;
import sootup.core.transform.BodyInterceptorMetric;
import sootup.core.transform.RunTimeBodyInterceptor;
import sootup.core.util.DotExporter;
import sootup.core.util.Utils;
import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.core.interceptors.BytecodeBodyInterceptors;
import sootup.java.core.interceptors.CopyPropagator;
import sootup.java.core.interceptors.DeadAssignmentEliminator;
import sootup.java.core.interceptors.TypeAssigner;
import sootup.java.core.views.JavaView;

@Tag("Java8")
Expand Down Expand Up @@ -121,4 +127,40 @@ public void testExample() {
/* Example to start quickly */
convertMethod("<java.awt.GraphicsEnvironment: java.awt.GraphicsEnvironment createGE()>");
}

/** e.g. to measure Runtime (Time and Memory Usage) of every interceptor */
@Test
public void runTimeOfBodyInterceptorOnJar() {
// Note: mrjar.jar used just for test purpose, you can put any jar file.
String baseDir = "../shared-test-resources/multi-release-jar/mrjar.jar";
// List<BodyInterceptor> bodyInterceptorsList =
// BytecodeBodyInterceptors.Default.getBodyInterceptors();
List<BodyInterceptor> bodyInterceptorsList =
Arrays.asList(new TypeAssigner(), new CopyPropagator());
List<RunTimeBodyInterceptor> runTimeBodyInterceptorsList = new ArrayList<>();
for (BodyInterceptor bodyInterceptor : bodyInterceptorsList) {
RunTimeBodyInterceptor runTimeBodyInterceptor = new RunTimeBodyInterceptor(bodyInterceptor);
runTimeBodyInterceptorsList.add(runTimeBodyInterceptor);
}
AnalysisInputLocation inputLocation =
new JavaClassPathAnalysisInputLocation(
baseDir, SourceType.Library, Collections.unmodifiableList(runTimeBodyInterceptorsList));
JavaView view = new JavaView(inputLocation);
view.getClasses()
.forEach(javaSootClass -> javaSootClass.getMethods().forEach(SootMethod::getBody));
runTimeBodyInterceptorsList.forEach(
runTimeBodyInterceptor -> {
BodyInterceptorMetric biMetric = runTimeBodyInterceptor.getBiMetric();
System.out.println(
runTimeBodyInterceptor.getBodyInterceptor()
+ " took "
+ biMetric.getRuntime()
+ " ms.");
System.out.println(
runTimeBodyInterceptor.getBodyInterceptor()
+ " consumed "
+ biMetric.getMemoryUsage()
+ " MB.");
});
}
}

0 comments on commit 44526c5

Please sign in to comment.