diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..ca33835 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: TraceAnalyzer +Bundle-SymbolicName: org.ntlab.traceAnalyzer;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.ntlab.traceanalyzer.Activator +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: org.osgi.framework;version="1.3.0", + org.osgi.util.tracker;version="1.3.1" +Bundle-ActivationPolicy: lazy +Require-Bundle: org.eclipse.ui, + org.eclipse.jface, + org.eclipse.core.runtime;bundle-version="3.8.0", + org.eclipse.core.resources;bundle-version="3.8.1", + org.eclipse.jdt.core;bundle-version="3.8.3", + org.eclipse.jdt.ui;bundle-version="3.8.2" diff --git a/bin/java.policy.applet b/bin/java.policy.applet new file mode 100644 index 0000000..ba9f51d --- /dev/null +++ b/bin/java.policy.applet @@ -0,0 +1,7 @@ +/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/ +/* DO NOT EDIT */ + +grant { + permission java.security.AllPermission; +}; + diff --git a/bin/org/ntlab/deltaExtractor/Alias$AliasType.class b/bin/org/ntlab/deltaExtractor/Alias$AliasType.class new file mode 100644 index 0000000..a6b2540 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/Alias$AliasType.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/Alias.class b/bin/org/ntlab/deltaExtractor/Alias.class new file mode 100644 index 0000000..5aa1582 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/Alias.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/Delta.class b/bin/org/ntlab/deltaExtractor/Delta.class new file mode 100644 index 0000000..d301295 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/Delta.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/DeltaAugmentationInfo.class b/bin/org/ntlab/deltaExtractor/DeltaAugmentationInfo.class new file mode 100644 index 0000000..5902cee --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/DeltaAugmentationInfo.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/DeltaExtractor$1.class b/bin/org/ntlab/deltaExtractor/DeltaExtractor$1.class new file mode 100644 index 0000000..3eaedfd --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/DeltaExtractor$1.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/DeltaExtractor.class b/bin/org/ntlab/deltaExtractor/DeltaExtractor.class new file mode 100644 index 0000000..d1bcad6 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/DeltaExtractor.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/DeltaExtractorJSON.class b/bin/org/ntlab/deltaExtractor/DeltaExtractorJSON.class new file mode 100644 index 0000000..8fa42c5 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/DeltaExtractorJSON.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/ExtractedStructure.class b/bin/org/ntlab/deltaExtractor/ExtractedStructure.class new file mode 100644 index 0000000..f7c028d --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/ExtractedStructure.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/IAliasCollector.class b/bin/org/ntlab/deltaExtractor/IAliasCollector.class new file mode 100644 index 0000000..118674a --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/IAliasCollector.class Binary files differ diff --git a/bin/org/ntlab/deltaExtractor/Test.class b/bin/org/ntlab/deltaExtractor/Test.class new file mode 100644 index 0000000..e95c2f1 --- /dev/null +++ b/bin/org/ntlab/deltaExtractor/Test.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAliasCollector.class b/bin/org/ntlab/deltaViewer/DeltaAliasCollector.class new file mode 100644 index 0000000..525bec5 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAliasCollector.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation$1.class b/bin/org/ntlab/deltaViewer/DeltaAnimation$1.class new file mode 100644 index 0000000..4e30013 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation$1.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation$2.class b/bin/org/ntlab/deltaViewer/DeltaAnimation$2.class new file mode 100644 index 0000000..4049eb0 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation$2.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation$3.class b/bin/org/ntlab/deltaViewer/DeltaAnimation$3.class new file mode 100644 index 0000000..07e120b --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation$3.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation$4.class b/bin/org/ntlab/deltaViewer/DeltaAnimation$4.class new file mode 100644 index 0000000..81236b1 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation$4.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation$5.class b/bin/org/ntlab/deltaViewer/DeltaAnimation$5.class new file mode 100644 index 0000000..ce8e27f --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation$5.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaAnimation.class b/bin/org/ntlab/deltaViewer/DeltaAnimation.class new file mode 100644 index 0000000..663ec9c --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaAnimation.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaGraphAdapter.class b/bin/org/ntlab/deltaViewer/DeltaGraphAdapter.class new file mode 100644 index 0000000..3ebf9f3 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaGraphAdapter.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/DeltaViewer.class b/bin/org/ntlab/deltaViewer/DeltaViewer.class new file mode 100644 index 0000000..8859e20 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/DeltaViewer.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/Edge$TypeName.class b/bin/org/ntlab/deltaViewer/Edge$TypeName.class new file mode 100644 index 0000000..62ec279 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/Edge$TypeName.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/Edge.class b/bin/org/ntlab/deltaViewer/Edge.class new file mode 100644 index 0000000..cfd0862 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/Edge.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/JGraphTSample$1.class b/bin/org/ntlab/deltaViewer/JGraphTSample$1.class new file mode 100644 index 0000000..732c560 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/JGraphTSample$1.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/JGraphTSample$GPanel.class b/bin/org/ntlab/deltaViewer/JGraphTSample$GPanel.class new file mode 100644 index 0000000..7eafc44 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/JGraphTSample$GPanel.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/JGraphTSample.class b/bin/org/ntlab/deltaViewer/JGraphTSample.class new file mode 100644 index 0000000..af8f6dd --- /dev/null +++ b/bin/org/ntlab/deltaViewer/JGraphTSample.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/Vertex.class b/bin/org/ntlab/deltaViewer/Vertex.class new file mode 100644 index 0000000..e0a2fee --- /dev/null +++ b/bin/org/ntlab/deltaViewer/Vertex.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/VertexMethodExecution.class b/bin/org/ntlab/deltaViewer/VertexMethodExecution.class new file mode 100644 index 0000000..98ab6c6 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/VertexMethodExecution.class Binary files differ diff --git a/bin/org/ntlab/deltaViewer/VertexObject.class b/bin/org/ntlab/deltaViewer/VertexObject.class new file mode 100644 index 0000000..3a10185 --- /dev/null +++ b/bin/org/ntlab/deltaViewer/VertexObject.class Binary files differ diff --git a/bin/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.class b/bin/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.class new file mode 100644 index 0000000..3c5e78f --- /dev/null +++ b/bin/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.class Binary files differ diff --git a/bin/org/ntlab/featureLocator/SoftwareReconnaissance.class b/bin/org/ntlab/featureLocator/SoftwareReconnaissance.class new file mode 100644 index 0000000..23d8cb4 --- /dev/null +++ b/bin/org/ntlab/featureLocator/SoftwareReconnaissance.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$1.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$1.class new file mode 100644 index 0000000..6f8568f --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$1.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$2.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$2.class new file mode 100644 index 0000000..4bd8fa1 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter$2.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.class new file mode 100644 index 0000000..d4805f6 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor$1.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor$1.class new file mode 100644 index 0000000..3637801 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor$1.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.class new file mode 100644 index 0000000..c215e9f --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$1.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$1.class new file mode 100644 index 0000000..1017fc2 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$1.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$2.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$2.class new file mode 100644 index 0000000..54ea5fe --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor$2.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.class new file mode 100644 index 0000000..99c7b8c --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$1.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$1.class new file mode 100644 index 0000000..75aa8f2 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$1.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$2.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$2.class new file mode 100644 index 0000000..3acec30 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter$2.class Binary files differ diff --git a/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.class b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.class new file mode 100644 index 0000000..0caa4b4 --- /dev/null +++ b/bin/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.class Binary files differ diff --git a/bin/org/ntlab/trace/ArrayAccess.class b/bin/org/ntlab/trace/ArrayAccess.class new file mode 100644 index 0000000..13971bb --- /dev/null +++ b/bin/org/ntlab/trace/ArrayAccess.class Binary files differ diff --git a/bin/org/ntlab/trace/ArrayCreate.class b/bin/org/ntlab/trace/ArrayCreate.class new file mode 100644 index 0000000..fb8c46c --- /dev/null +++ b/bin/org/ntlab/trace/ArrayCreate.class Binary files differ diff --git a/bin/org/ntlab/trace/ArrayUpdate.class b/bin/org/ntlab/trace/ArrayUpdate.class new file mode 100644 index 0000000..6a62178 --- /dev/null +++ b/bin/org/ntlab/trace/ArrayUpdate.class Binary files differ diff --git a/bin/org/ntlab/trace/AugmentationInfo.class b/bin/org/ntlab/trace/AugmentationInfo.class new file mode 100644 index 0000000..33c0b13 --- /dev/null +++ b/bin/org/ntlab/trace/AugmentationInfo.class Binary files differ diff --git a/bin/org/ntlab/trace/BlockEnter.class b/bin/org/ntlab/trace/BlockEnter.class new file mode 100644 index 0000000..fe69b9a --- /dev/null +++ b/bin/org/ntlab/trace/BlockEnter.class Binary files differ diff --git a/bin/org/ntlab/trace/ClassInfo.class b/bin/org/ntlab/trace/ClassInfo.class new file mode 100644 index 0000000..581ed2c --- /dev/null +++ b/bin/org/ntlab/trace/ClassInfo.class Binary files differ diff --git a/bin/org/ntlab/trace/DeltaViewerSample.class b/bin/org/ntlab/trace/DeltaViewerSample.class new file mode 100644 index 0000000..6596241 --- /dev/null +++ b/bin/org/ntlab/trace/DeltaViewerSample.class Binary files differ diff --git a/bin/org/ntlab/trace/FieldAccess.class b/bin/org/ntlab/trace/FieldAccess.class new file mode 100644 index 0000000..5017132 --- /dev/null +++ b/bin/org/ntlab/trace/FieldAccess.class Binary files differ diff --git a/bin/org/ntlab/trace/FieldUpdate.class b/bin/org/ntlab/trace/FieldUpdate.class new file mode 100644 index 0000000..18bab86 --- /dev/null +++ b/bin/org/ntlab/trace/FieldUpdate.class Binary files differ diff --git a/bin/org/ntlab/trace/IBoundaryChecker.class b/bin/org/ntlab/trace/IBoundaryChecker.class new file mode 100644 index 0000000..c7f607f --- /dev/null +++ b/bin/org/ntlab/trace/IBoundaryChecker.class Binary files differ diff --git a/bin/org/ntlab/trace/IMethodExecutionVisitor.class b/bin/org/ntlab/trace/IMethodExecutionVisitor.class new file mode 100644 index 0000000..1267b54 --- /dev/null +++ b/bin/org/ntlab/trace/IMethodExecutionVisitor.class Binary files differ diff --git a/bin/org/ntlab/trace/IStatementVisitor.class b/bin/org/ntlab/trace/IStatementVisitor.class new file mode 100644 index 0000000..e04850f --- /dev/null +++ b/bin/org/ntlab/trace/IStatementVisitor.class Binary files differ diff --git a/bin/org/ntlab/trace/MethodExecution.class b/bin/org/ntlab/trace/MethodExecution.class new file mode 100644 index 0000000..4436ee3 --- /dev/null +++ b/bin/org/ntlab/trace/MethodExecution.class Binary files differ diff --git a/bin/org/ntlab/trace/MethodExecutionJPDA$IMethodExecutionVisitorJPDA.class b/bin/org/ntlab/trace/MethodExecutionJPDA$IMethodExecutionVisitorJPDA.class new file mode 100644 index 0000000..33d22cd --- /dev/null +++ b/bin/org/ntlab/trace/MethodExecutionJPDA$IMethodExecutionVisitorJPDA.class Binary files differ diff --git a/bin/org/ntlab/trace/MethodExecutionJPDA.class b/bin/org/ntlab/trace/MethodExecutionJPDA.class new file mode 100644 index 0000000..a895333 --- /dev/null +++ b/bin/org/ntlab/trace/MethodExecutionJPDA.class Binary files differ diff --git a/bin/org/ntlab/trace/MethodInvocation.class b/bin/org/ntlab/trace/MethodInvocation.class new file mode 100644 index 0000000..99bf982 --- /dev/null +++ b/bin/org/ntlab/trace/MethodInvocation.class Binary files differ diff --git a/bin/org/ntlab/trace/ObjectReference.class b/bin/org/ntlab/trace/ObjectReference.class new file mode 100644 index 0000000..53c3bb6 --- /dev/null +++ b/bin/org/ntlab/trace/ObjectReference.class Binary files differ diff --git a/bin/org/ntlab/trace/Reference.class b/bin/org/ntlab/trace/Reference.class new file mode 100644 index 0000000..52d021a --- /dev/null +++ b/bin/org/ntlab/trace/Reference.class Binary files differ diff --git a/bin/org/ntlab/trace/Statement.class b/bin/org/ntlab/trace/Statement.class new file mode 100644 index 0000000..e0774e5 --- /dev/null +++ b/bin/org/ntlab/trace/Statement.class Binary files differ diff --git a/bin/org/ntlab/trace/TestTrace$1.class b/bin/org/ntlab/trace/TestTrace$1.class new file mode 100644 index 0000000..5fffd24 --- /dev/null +++ b/bin/org/ntlab/trace/TestTrace$1.class Binary files differ diff --git a/bin/org/ntlab/trace/TestTrace$2.class b/bin/org/ntlab/trace/TestTrace$2.class new file mode 100644 index 0000000..b91c999 --- /dev/null +++ b/bin/org/ntlab/trace/TestTrace$2.class Binary files differ diff --git a/bin/org/ntlab/trace/TestTrace.class b/bin/org/ntlab/trace/TestTrace.class new file mode 100644 index 0000000..0de5693 --- /dev/null +++ b/bin/org/ntlab/trace/TestTrace.class Binary files differ diff --git a/bin/org/ntlab/trace/TestTraceJPDA$1.class b/bin/org/ntlab/trace/TestTraceJPDA$1.class new file mode 100644 index 0000000..4eb9d2a --- /dev/null +++ b/bin/org/ntlab/trace/TestTraceJPDA$1.class Binary files differ diff --git a/bin/org/ntlab/trace/TestTraceJPDA.class b/bin/org/ntlab/trace/TestTraceJPDA.class new file mode 100644 index 0000000..b7948c7 --- /dev/null +++ b/bin/org/ntlab/trace/TestTraceJPDA.class Binary files differ diff --git a/bin/org/ntlab/trace/ThreadInstance.class b/bin/org/ntlab/trace/ThreadInstance.class new file mode 100644 index 0000000..58daff3 --- /dev/null +++ b/bin/org/ntlab/trace/ThreadInstance.class Binary files differ diff --git a/bin/org/ntlab/trace/ThreadInstanceJPDA.class b/bin/org/ntlab/trace/ThreadInstanceJPDA.class new file mode 100644 index 0000000..d150246 --- /dev/null +++ b/bin/org/ntlab/trace/ThreadInstanceJPDA.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$1.class b/bin/org/ntlab/trace/Trace$1.class new file mode 100644 index 0000000..e1257ea --- /dev/null +++ b/bin/org/ntlab/trace/Trace$1.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$10.class b/bin/org/ntlab/trace/Trace$10.class new file mode 100644 index 0000000..4207013 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$10.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$11.class b/bin/org/ntlab/trace/Trace$11.class new file mode 100644 index 0000000..e74cf2c --- /dev/null +++ b/bin/org/ntlab/trace/Trace$11.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$12.class b/bin/org/ntlab/trace/Trace$12.class new file mode 100644 index 0000000..13a2eaa --- /dev/null +++ b/bin/org/ntlab/trace/Trace$12.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$13.class b/bin/org/ntlab/trace/Trace$13.class new file mode 100644 index 0000000..1788c09 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$13.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$2.class b/bin/org/ntlab/trace/Trace$2.class new file mode 100644 index 0000000..e4b8d18 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$2.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$3.class b/bin/org/ntlab/trace/Trace$3.class new file mode 100644 index 0000000..4b9ed5c --- /dev/null +++ b/bin/org/ntlab/trace/Trace$3.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$4.class b/bin/org/ntlab/trace/Trace$4.class new file mode 100644 index 0000000..9611a60 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$4.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$5.class b/bin/org/ntlab/trace/Trace$5.class new file mode 100644 index 0000000..292d623 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$5.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$6.class b/bin/org/ntlab/trace/Trace$6.class new file mode 100644 index 0000000..dde9382 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$6.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$7.class b/bin/org/ntlab/trace/Trace$7.class new file mode 100644 index 0000000..f5be5ac --- /dev/null +++ b/bin/org/ntlab/trace/Trace$7.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$8.class b/bin/org/ntlab/trace/Trace$8.class new file mode 100644 index 0000000..0131a9c --- /dev/null +++ b/bin/org/ntlab/trace/Trace$8.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace$9.class b/bin/org/ntlab/trace/Trace$9.class new file mode 100644 index 0000000..cde0142 --- /dev/null +++ b/bin/org/ntlab/trace/Trace$9.class Binary files differ diff --git a/bin/org/ntlab/trace/Trace.class b/bin/org/ntlab/trace/Trace.class new file mode 100644 index 0000000..e1ff5d4 --- /dev/null +++ b/bin/org/ntlab/trace/Trace.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJPDA$1.class b/bin/org/ntlab/trace/TraceJPDA$1.class new file mode 100644 index 0000000..dc255be --- /dev/null +++ b/bin/org/ntlab/trace/TraceJPDA$1.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJPDA$2.class b/bin/org/ntlab/trace/TraceJPDA$2.class new file mode 100644 index 0000000..aedabff --- /dev/null +++ b/bin/org/ntlab/trace/TraceJPDA$2.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJPDA.class b/bin/org/ntlab/trace/TraceJPDA.class new file mode 100644 index 0000000..ce401b7 --- /dev/null +++ b/bin/org/ntlab/trace/TraceJPDA.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$1.class b/bin/org/ntlab/trace/TraceJSON$1.class new file mode 100644 index 0000000..421593e --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$1.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$2.class b/bin/org/ntlab/trace/TraceJSON$2.class new file mode 100644 index 0000000..2780d62 --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$2.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$3.class b/bin/org/ntlab/trace/TraceJSON$3.class new file mode 100644 index 0000000..0b4006c --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$3.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$4.class b/bin/org/ntlab/trace/TraceJSON$4.class new file mode 100644 index 0000000..ca2e72f --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$4.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$5.class b/bin/org/ntlab/trace/TraceJSON$5.class new file mode 100644 index 0000000..2d296e5 --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$5.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$6.class b/bin/org/ntlab/trace/TraceJSON$6.class new file mode 100644 index 0000000..37eacb9 --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$6.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON$7.class b/bin/org/ntlab/trace/TraceJSON$7.class new file mode 100644 index 0000000..03a247e --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON$7.class Binary files differ diff --git a/bin/org/ntlab/trace/TraceJSON.class b/bin/org/ntlab/trace/TraceJSON.class new file mode 100644 index 0000000..027e6d4 --- /dev/null +++ b/bin/org/ntlab/trace/TraceJSON.class Binary files differ diff --git a/bin/org/ntlab/trace/TracePoint.class b/bin/org/ntlab/trace/TracePoint.class new file mode 100644 index 0000000..7a9f1c4 --- /dev/null +++ b/bin/org/ntlab/trace/TracePoint.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/Activator.class b/bin/org/ntlab/traceanalyzer/Activator.class new file mode 100644 index 0000000..4ebd69f --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/Activator.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeContentProvider.class b/bin/org/ntlab/traceanalyzer/CallTreeContentProvider.class new file mode 100644 index 0000000..96b0b84 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeContentProvider.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeLabelProvider.class b/bin/org/ntlab/traceanalyzer/CallTreeLabelProvider.class new file mode 100644 index 0000000..5d98053 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeLabelProvider.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView$1.class b/bin/org/ntlab/traceanalyzer/CallTreeView$1.class new file mode 100644 index 0000000..e23be9a --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView$1.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView$2.class b/bin/org/ntlab/traceanalyzer/CallTreeView$2.class new file mode 100644 index 0000000..5a70329 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView$2.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView$3$1.class b/bin/org/ntlab/traceanalyzer/CallTreeView$3$1.class new file mode 100644 index 0000000..44b7a04 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView$3$1.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView$3.class b/bin/org/ntlab/traceanalyzer/CallTreeView$3.class new file mode 100644 index 0000000..2bf69fd --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView$3.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView$4.class b/bin/org/ntlab/traceanalyzer/CallTreeView$4.class new file mode 100644 index 0000000..ca6d9c5 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView$4.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/CallTreeView.class b/bin/org/ntlab/traceanalyzer/CallTreeView.class new file mode 100644 index 0000000..612df6b --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/CallTreeView.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/Dictionary.class b/bin/org/ntlab/traceanalyzer/Dictionary.class new file mode 100644 index 0000000..70fabe9 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/Dictionary.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/DictionaryImpl.class b/bin/org/ntlab/traceanalyzer/DictionaryImpl.class new file mode 100644 index 0000000..1540527 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/DictionaryImpl.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/DictionaryService.class b/bin/org/ntlab/traceanalyzer/DictionaryService.class new file mode 100644 index 0000000..488a632 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/DictionaryService.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/DictionaryServiceImpl.class b/bin/org/ntlab/traceanalyzer/DictionaryServiceImpl.class new file mode 100644 index 0000000..cacf9b9 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/DictionaryServiceImpl.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/MarkedMethodExecution.class b/bin/org/ntlab/traceanalyzer/MarkedMethodExecution.class new file mode 100644 index 0000000..bad6593 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/MarkedMethodExecution.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.class b/bin/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.class new file mode 100644 index 0000000..8555035 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/MarkedThread.class b/bin/org/ntlab/traceanalyzer/MarkedThread.class new file mode 100644 index 0000000..706b182 --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/MarkedThread.class Binary files differ diff --git a/bin/org/ntlab/traceanalyzer/MarkedTrace.class b/bin/org/ntlab/traceanalyzer/MarkedTrace.class new file mode 100644 index 0000000..5791f4e --- /dev/null +++ b/bin/org/ntlab/traceanalyzer/MarkedTrace.class Binary files differ diff --git a/build.properties b/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/icons/full/read_obj.gif b/icons/full/read_obj.gif new file mode 100644 index 0000000..c876ebd --- /dev/null +++ b/icons/full/read_obj.gif Binary files differ diff --git a/icons/full/stckframe_obj.gif b/icons/full/stckframe_obj.gif new file mode 100644 index 0000000..f1e585b --- /dev/null +++ b/icons/full/stckframe_obj.gif Binary files differ diff --git a/icons/full/stckframe_obj2.gif b/icons/full/stckframe_obj2.gif new file mode 100644 index 0000000..0fdf558 --- /dev/null +++ b/icons/full/stckframe_obj2.gif Binary files differ diff --git a/icons/full/stckframe_obj3.gif b/icons/full/stckframe_obj3.gif new file mode 100644 index 0000000..ab64f22 --- /dev/null +++ b/icons/full/stckframe_obj3.gif Binary files differ diff --git a/icons/full/threads_obj.gif b/icons/full/threads_obj.gif new file mode 100644 index 0000000..45c23a9 --- /dev/null +++ b/icons/full/threads_obj.gif Binary files differ diff --git a/icons/full/threads_obj2.gif b/icons/full/threads_obj2.gif new file mode 100644 index 0000000..94d122a --- /dev/null +++ b/icons/full/threads_obj2.gif Binary files differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..8f4838f --- /dev/null +++ b/plugin.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/src/org/ntlab/deltaExtractor/Alias.java b/src/org/ntlab/deltaExtractor/Alias.java new file mode 100644 index 0000000..7d83a6e --- /dev/null +++ b/src/org/ntlab/deltaExtractor/Alias.java @@ -0,0 +1,72 @@ +package org.ntlab.deltaExtractor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.Statement; +import org.ntlab.trace.TracePoint; +/** + * �I�u�W�F�N�g�̎Q�Ə��(�G�C���A�X)��\���N���X + * @author Isitani + * + */ +public class Alias { + private String objectId; + private TracePoint occurrencePoint; // ���Y�I�u�W�F�N�g�̎Q�Ƃ��s���Ă�����s�ӏ��ɑΉ�����TracePoint + private AliasType aliasType; + private int index; + + public enum AliasType { + // ���\�b�h�ւ̓��� + FORMAL_PARAMETER, + THIS, + METHOD_INVOCATION, + CONSTRACTOR_INVOCATION, + + // �ǐՃI�u�W�F�N�g�̐؂�ւ� + FIELD, + CONTAINER, + ARRAY_ELEMENT, + ARRAY, + ARRAY_CREATE, + + // ���\�b�h����̏o�� + ACTUAL_ARGUMENT, + RECEIVER, + RETURN_VALUE + } + + public Alias(AliasType aliasType, int index, String objectId, TracePoint occurrencePoint) { + this.aliasType = aliasType; + this.index = index; + this.objectId = objectId; + this.occurrencePoint = occurrencePoint; + } + + public AliasType getAliasType() { + return aliasType; + } + + public int getIndex() { + return index; + } + + public String getObjectId() { + return objectId; + } + + public TracePoint getOccurrencePoint() { + return occurrencePoint; + } + + public MethodExecution getMethodExecution() { + return occurrencePoint.getMethodExecution(); + } + + public String getMethodSignature() { + return occurrencePoint.getMethodExecution().getCallerSideSignature(); + } + + public int getLineNo() { + Statement statement = occurrencePoint.getStatement(); + return statement.getLineNo(); + } + +} \ No newline at end of file diff --git a/src/org/ntlab/deltaExtractor/Delta.java b/src/org/ntlab/deltaExtractor/Delta.java new file mode 100644 index 0000000..ea47d5b --- /dev/null +++ b/src/org/ntlab/deltaExtractor/Delta.java @@ -0,0 +1,27 @@ +package org.ntlab.deltaExtractor; + +import java.util.ArrayList; + +import org.ntlab.trace.Reference; + +public class Delta { + + private ArrayList srcSide = new ArrayList(); + private ArrayList dstSide = new ArrayList(); + + public void addSrcSide(Reference r){ + getSrcSide().add(r); + } + + public void addDstSide(Reference r){ + getDstSide().add(r); + } + + public ArrayList getSrcSide() { + return srcSide; + } + + public ArrayList getDstSide() { + return dstSide; + } +} diff --git a/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java b/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java new file mode 100644 index 0000000..82a373d --- /dev/null +++ b/src/org/ntlab/deltaExtractor/DeltaAugmentationInfo.java @@ -0,0 +1,34 @@ +package org.ntlab.deltaExtractor; + +import org.ntlab.trace.AugmentationInfo; + +public class DeltaAugmentationInfo extends AugmentationInfo { + private Boolean isCoodinator = false; + private Boolean isSetter = true; + private int traceObjectId = 0; + + public void setTraceObjectId(int traceObjectId) { + this.traceObjectId = traceObjectId; + } + + public int getTraceObjectId() { + return traceObjectId; + } + + public void setSetterSide(boolean isSetter) { + this.isSetter = isSetter; + } + + public boolean isSetterSide() { + return isSetter; + } + + public void setCoodinator(boolean isCoodinator) { + this.isCoodinator = isCoodinator; + } + + public boolean isCoodinator() { + return isCoodinator; + } + +} diff --git a/src/org/ntlab/deltaExtractor/DeltaExtractor.java b/src/org/ntlab/deltaExtractor/DeltaExtractor.java new file mode 100644 index 0000000..586c3ff --- /dev/null +++ b/src/org/ntlab/deltaExtractor/DeltaExtractor.java @@ -0,0 +1,1117 @@ +package org.ntlab.deltaExtractor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; + +import org.ntlab.trace.FieldAccess; +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.ObjectReference; +import org.ntlab.trace.Reference; +import org.ntlab.trace.Statement; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TracePoint; + +/** + * �f���^���o�A���S���Y��(�z��ւ̃A�N�Z�X�𐄑�����]���̃o�[�W����) + * extract(...)���\�b�h�Q�Œ��o����B + * + * @author Nitta + * + */ +public class DeltaExtractor { + protected static final int LOST_DECISION_EXTENSION = 0; // ��{�� 0 �ɐݒ�Bfinal�ϐ��̒ǐՃA���S���Y���̕s��C����͕s�v�̂͂��B + protected ArrayList data = new ArrayList(); + protected ArrayList objList = new ArrayList(2); + protected ArrayList methodList = new ArrayList(); + protected ExtractedStructure eStructure = new ExtractedStructure(); + protected ObjectReference srcObject = null; + protected ObjectReference dstObject = null; + protected String returnValue; + protected String threadNo; + protected boolean isLost = false; + protected ArrayList checkList = new ArrayList(); + protected Trace trace = null; + protected int finalCount = 0; // final�ϐ������o�ł��Ȃ��”\��������̂ŁA�R���̉������ł��Ȃ������ꍇ�ł����΂炭�ǐՂ��‚Â��� + + protected static final boolean DEBUG1 = true; + protected static final boolean DEBUG2 = true; + protected final IAliasCollector defaultAliasCollector = new IAliasCollector() { + @Override + public void changeTrackingObject(String from, String to) { + } + @Override + public void addAlias(Alias alias) { + } + }; + + public DeltaExtractor(String traceFile) { + trace = new Trace(traceFile); + } + + public DeltaExtractor(Trace trace) { + this.trace = trace; + } + +// public MethodExecution getMethodExecution(Reference createdReference, MethodExecution before) { +// return trace.getMethodExecution(createdReference, before); +// } +// +// public MethodExecution getMethodExecution(String methodSignature) { +// return trace.getMethodExecution(methodSignature); +// } +// +// public MethodExecution getMethodExecutionBackwardly(String methodSignature) { +// return trace.getMethodExecutionBackwardly(methodSignature); +// } +// +// public MethodExecution getCollectionTypeMethodExecution(Reference r, MethodExecution before) { +// return trace.getCollectionTypeMethodExecution(r, before); +// } +// +// public MethodExecution getArraySetMethodExecution(Reference r, MethodExecution before) { +// return trace.getArraySetMethodExecution(r, before); +// } +// +// public CallTree getLastCallTree(ArrayList refs, +// ArrayList colls, +// ArrayList arrys, +// int endLine, +// Reference[] lastRef) throws TraceFileException { +// return trace.getLastCallTree(refs, colls, arrys, endLine, lastRef); +// } + + /** + * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j + * @param trace�@��͑Ώۃg���[�X + * @param methodExecution �T�����郁�\�b�h���s + * @param objList�@�ǐՒ��̃I�u�W�F�N�g + * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s + * @return ���‚������R�[�f�B�l�[�^ + * @throws TraceFileException + */ + protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution) { + return callerSearch(trace, tracePoint, objList, childMethodExecution, defaultAliasCollector); + } + + /** + * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j + * @param trace�@��͑Ώۃg���[�X + * @param methodExecution �T�����郁�\�b�h���s + * @param objList�@�ǐՒ��̃I�u�W�F�N�g + * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s + * @return ���‚������R�[�f�B�l�[�^ + * @throws TraceFileException + */ + protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution, IAliasCollector aliasCollector) { + MethodExecution methodExecution = tracePoint.getMethodExecution(); + methodExecution.setAugmentation(new DeltaAugmentationInfo()); + eStructure.createParent(methodExecution); + String thisObjectId = methodExecution.getThisObjId(); + ArrayList removeList = new ArrayList(); // �ǐՂ��Ă���I�u�W�F�N�g���ō폜�ΏۂƂȂ��Ă������ + ArrayList creationList = new ArrayList(); // ���̃��\�b�h���s���ɐ������ꂽ�I�u�W�F�N�g + int existsInFields = 0; // ���̃��\�b�h���s���Ńt�B�[���h�ɗR�����Ă���I�u�W�F�N�g�̐�(1�ȏ�Ȃ炱�̃��\�b�h���s����this�Ɉˑ�) + boolean isTrackingThis = false; // �Ăяo�����this�Ɉˑ����� + boolean isSrcSide = true; // �Q�ƌ����Q�Ɛ�̂�����̑��̃I�u�W�F�N�g�̗R�������ǂ���this�I�u�W�F�N�g�ɓ��B������? + ArrayList fieldArrays = new ArrayList(); + ArrayList fieldArrayElements = new ArrayList(); + ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), + Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + + if (childMethodExecution == null) { + // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + + if (childMethodExecution != null && objList.contains(childMethodExecution.getThisObjId())) { + // �Ăяo�����this�Ɉˑ����� + if (thisObjectId.equals(childMethodExecution.getThisObjId())) { + // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + } + + if (childMethodExecution != null && childMethodExecution.isConstructor()) { + // �Ăяo���悪�R���X�g���N�^�������ꍇ + int newIndex = objList.indexOf(childMethodExecution.getThisObjId()); + if (newIndex != -1) { + // �Ăяo���悪�ǐՑΏۂ̃R���X�g���N�^��������field�Ɠ��l�ɏ��� + removeList.add(childMethodExecution.getThisObjId()); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + } + } + + if (childMethodExecution != null && Trace.getMethodName(childMethodExecution.getSignature()).startsWith("access$")) { + // �G���N���[�W���O�C���X�^���X�ɑ΂��郁�\�b�h�Ăяo���������ꍇ + String enclosingObj = childMethodExecution.getArguments().get(0).getId(); // �G���N���[�W���O�C���X�^���X�͑������ɓ����Ă���炵�� + int encIndex = objList.indexOf(enclosingObj); + if (encIndex != -1) { + // thisObject �ɒu����������Afield�Ɠ��l�ɏ��� + removeList.add(enclosingObj); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + } + } + + // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo�� + while (tracePoint.stepBackOver()) { + Statement statement = tracePoint.getStatement(); + // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T�� + if (statement instanceof FieldAccess) { + FieldAccess fs = (FieldAccess)statement; + String refObjectId = fs.getValueObjId(); + int index = objList.indexOf(refObjectId); + if (index != -1) { + String ownerObjectId = fs.getContainerObjId(); + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ + removeList.add(refObjectId); + existsInFields++; // set�������get�����o���Ă���”\�������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + } else { + // ���ڎQ�Ƃ̏ꍇ + if (refObjectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId, + fs.getContainerClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + } else if(refObjectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(ownerObjectId, refObjectId, + fs.getContainerClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + } + objList.set(index, ownerObjectId); + } + } else { + // �ŏI�I�ɃI�u�W�F�N�g�̗R�������‚���Ȃ������ꍇ�ɁA�����ŎQ�Ƃ����z������̗v�f�ɗR�����Ă���”\�������� + String refObjType = fs.getValueClassName(); + if (refObjType.startsWith("[L")) { + // �Q�Ƃ����t�B�[���h���z��̏ꍇ + ObjectReference trackingObj = null; + if ((srcObject.getActualType() != null && refObjType.endsWith(srcObject.getActualType() + ";")) + || (srcObject.getCalleeType() != null && refObjType.endsWith(srcObject.getCalleeType() + ";")) + || (srcObject.getCallerType() != null && refObjType.endsWith(srcObject.getCallerType() + ";"))) { + trackingObj = srcObject; + } else if ((dstObject.getActualType() != null && refObjType.endsWith(dstObject.getActualType() + ";")) + || (dstObject.getCalleeType() != null && refObjType.endsWith(dstObject.getCalleeType() + ";")) + || (dstObject.getCallerType() != null && refObjType.endsWith(dstObject.getCallerType() + ";"))) { + trackingObj = dstObject; + } + if (trackingObj != null) { + // �ǐՒ��̃I�u�W�F�N�g�ɁA�z��v�f�Ɠ����^�����ƒI�u�W�F�N�g�����݂���ꍇ + String ownerObjectId = fs.getContainerObjId(); + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉”\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j + fieldArrays.add(new ObjectReference(refObjectId, refObjType)); + fieldArrayElements.add(trackingObj); + } else { + // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A + // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� + // ��蒼��������B) + } + } + } + } + } else if (statement instanceof MethodInvocation) { + MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + if (!prevChildMethodExecution.equals(childMethodExecution)) { + // �߂�l + ObjectReference ret = prevChildMethodExecution.getReturnValue(); + if (ret != null) { + int retIndex = -1; + retIndex = objList.indexOf(ret.getId()); + if (retIndex != -1) { + // �߂�l���R�������� + prevChildMethodExecution.setAugmentation(new DeltaAugmentationInfo()); + if (prevChildMethodExecution.isConstructor()) { + // �ǐՑΏۂ�constractor���Ă�ł�����(�I�u�W�F�N�g�̐�����������)field�Ɠ��l�ɏ��� + String newObjId = ret.getId(); + creationList.add(newObjId); + removeList.add(newObjId); + existsInFields++; + // objList.remove(callTree.getThisObjId()); + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // getter�Ăяo���Ɠ��l + continue; + } + String retObj = objList.get(retIndex); + if (removeList.contains(retObj)) { + // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������ + removeList.remove(retObj); + existsInFields--; + if (existsInFields == 0) { + removeList.remove(thisObjectId); + } + } + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ� + TracePoint prevChildTracePoint = tracePoint.duplicate(); + prevChildTracePoint.stepBackNoReturn(); + calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex, aliasCollector); // �Ăяo�����T�� + if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId()) + && thisObjectId.equals(prevChildMethodExecution.getThisObjId())) { + // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏��� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + if (isLost) { + checkList.add(objList.get(retIndex)); + isLost = false; + } + } else { + // �ŏI�I�ɃI�u�W�F�N�g�̗R�������‚���Ȃ������ꍇ�ɁA���̖߂�l�Ŏ擾�����z������̗v�f�ɗR�����Ă���”\�������� + String retType = ret.getActualType(); + if (retType.startsWith("[L")) { + // �߂�l���z��̏ꍇ + if ((srcObject.getActualType() != null && retType.endsWith(srcObject.getActualType() + ";")) + || (srcObject.getCalleeType() != null && retType.endsWith(srcObject.getCalleeType() + ";")) + || (srcObject.getCallerType() != null && retType.endsWith(srcObject.getCallerType() + ";"))) { + retType = srcObject.getActualType(); + } else if ((dstObject.getActualType() != null && retType.endsWith(dstObject.getActualType() + ";")) + || (dstObject.getCalleeType() != null && retType.endsWith(dstObject.getCalleeType() + ";")) + || (dstObject.getCallerType() != null && retType.endsWith(dstObject.getCallerType() + ";"))) { + retType = dstObject.getActualType(); + } else { + retType = null; + } + if (retType != null) { + // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A + // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� + // ��蒼��������B + } + } + } + } + } + } + } + // --- ���̎��_�� tracePoint �͌Ăяo�������w���Ă��� --- + + // �R���N�V�����^�Ή� + if (methodExecution.isCollectionType()) { + objList.add(thisObjectId); + } + + // �����̎擾 + ArrayList argments = methodExecution.getArguments(); + + // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z�� + Reference r; + for (int i = 0; i < removeList.size(); i++) { + String removeId = removeList.get(i); + if (argments.contains(new ObjectReference(removeId))) { + removeList.remove(removeId); // �t�B�[���h�ƈ����̗����ɒǐՑΏۂ����݂����ꍇ�A������D�� + } else if(objList.contains(removeId)) { + // �t�B�[���h�ɂ����Ȃ������ꍇ(�������A�I�u�W�F�N�g�̐������t�B�[���h�Ɠ��l�Ɉ���) + objList.remove(removeId); // �ǐՑΏۂ���O�� + if (!removeId.equals(thisObjectId)) { + // �t�B�[���h�ithis ���� removeId �ւ̎Q�Ɓj���f���^�̍\���v�f�ɂȂ� + if (removeId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����? + eStructure.addSrcSide(r); + srcObject = thisObj; + isSrcSide = true; + } else if (removeId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����? + eStructure.addDstSide(r); + dstObject = thisObj; + isSrcSide = false; + } + } + } + } + // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� --- + + // �����T�� + boolean existsInAnArgument = false; + for (int i = 0; i < objList.size(); i++) { + String objectId = objList.get(i); + if (objectId != null) { + ObjectReference trackingObj = new ObjectReference(objectId); + if (argments.contains(trackingObj)) { + // �������R�������� + existsInAnArgument = true; + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); + } else { + // �R�����ǂ��ɂ����‚���Ȃ����� + boolean isSrcSide2 = true; + trackingObj = null; + if (objectId.equals(srcObject.getId())) { + isSrcSide2 = true; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + isSrcSide2 = false; + trackingObj = dstObject; + } + if (trackingObj != null) { + // �܂��z������̗v�f��R���Ƃ��ċ^��(������D��) + for (int j = 0; j < argments.size(); j++) { + ObjectReference argArray = argments.get(j); + if (argArray.getActualType().startsWith("[L") + && (trackingObj.getActualType() != null && (argArray.getActualType().endsWith(trackingObj.getActualType() + ";")) + || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";")) + || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) { + // �^����v������z������̗v�f��R���Ƃ݂Ȃ� + existsInAnArgument = true; + objList.remove(objectId); + objList.add(argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������ + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId())); + r = new Reference(argArray.getId(), trackingObj.getId(), + argArray.getActualType(), trackingObj.getActualType()); + r.setArray(true); + if (isSrcSide2) { + eStructure.addSrcSide(r); + srcObject = new ObjectReference(argArray.getId(), argArray.getActualType()); + } else { + eStructure.addDstSide(r); + dstObject = new ObjectReference(argArray.getId(), argArray.getActualType()); + } + objectId = null; + break; + } + } + if (objectId != null) { + // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������) + int index = fieldArrayElements.indexOf(trackingObj); + if (index != -1) { + // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ� + ObjectReference fieldArray = fieldArrays.get(index); + existsInFields++; + objList.remove(objectId); + r = new Reference(fieldArray.getId(), trackingObj.getId(), + fieldArray.getActualType(), trackingObj.getActualType()); + r.setArray(true); + if (isSrcSide2) { + eStructure.addSrcSide(r); + eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(), + methodExecution.getThisClassName(), fieldArray.getActualType())); + srcObject = thisObj; + isSrcSide = true; + } else { + eStructure.addDstSide(r); + eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(), + methodExecution.getThisClassName(), fieldArray.getActualType())); + dstObject = thisObj; + isSrcSide = false; + } + } + } + if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) { + // �ǂ��ɂ����‚���Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�΁A���̃��\�b�h���Ő������ꂽ���̂ƍl���� + objList.remove(objectId); + if (isSrcSide2) { + eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType())); + srcObject = thisObj; + isSrcSide = true; + } else { + eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType())); + dstObject = thisObj; + isSrcSide = false; + } + } + } + } + } + } + if (existsInAnArgument) { + // ������1�‚ł��ǐՑΏۂ����݂����ꍇ + if (existsInFields > 0 || isTrackingThis) { + // this�I�u�W�F�N�g��ǐՒ��̏ꍇ + if (!Trace.isNull(thisObjectId)) { + objList.add(thisObjectId); // ����ɒT������ꍇ�A��U��菜���� thisObject �𕜊� + } else { + objList.add(null); // ������static�Ăяo���������ꍇ�A����ȏ�ǐՂ��Ȃ� + } + } +// if (existsInFields > 0) { +// // �t�B�[���h��R���Ɏ��ƒI�u�W�F�N�g�����݂����ꍇ +// if (isSrcSide) { +// srcObject = thisObj; +// } else { +// dstObject = thisObj; +// } +// } + if (tracePoint.isValid()) { + finalCount = 0; + return callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + } + } + + for (int i = 0; i < objList.size(); i++) { + objList.remove(null); + } + if (objList.isEmpty()) { + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(true); + } else { + // �R���������ł��Ȃ����� + if (!methodExecution.isStatic()) { + finalCount++; + if (finalCount <= LOST_DECISION_EXTENSION) { + // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��”\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂��� + if (tracePoint.isValid()) { + MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) { + methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^�����‚����� + } + } + } else if (thisObj.getActualType().contains("$")) { + // �����������܂��͖����N���X�̏ꍇ�A���������I�u�W�F�N�g���O�����\�b�h�̓���final�ϐ�����擾�����Ƃ݂Ȃ��A����Ɏ����̒��̃t�B�[���h�̈��Ƃ݂Ȃ� + for (int i = objList.size() - 1; i >= 0; i--) { + String objectId = objList.get(i); + if (objectId != null) { + ObjectReference trackingObj = new ObjectReference(objectId); + boolean isSrcSide2 = true; + trackingObj = null; + if (objectId.equals(srcObject.getId())) { + isSrcSide2 = true; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + isSrcSide2 = false; + trackingObj = dstObject; + } + if (trackingObj != null) { + r = new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType()); + r.setFinalLocal(true); + if (isSrcSide2) { + eStructure.addSrcSide(r); + srcObject = thisObj; + isSrcSide = true; + } else { + eStructure.addDstSide(r); + dstObject = thisObj; + isSrcSide = false; + } + existsInFields++; + objList.remove(objectId); + } + } + } + } + } + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(false); + } + finalCount = 0; + return methodExecution; + } + + /** + * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���) + * @param trace ��͑Ώۃg���[�X + * @param methodExecution �T�����郁�\�b�h���s + * @param objList �ǐՒ��̃I�u�W�F�N�g + * @param isStatic�@�ÓI���\�b�h���ۂ� + * @param index�@objList���̂ǂ̃I�u�W�F�N�g��ǐՂ��Ă��̃��\�b�h���s�ɓ����Ă����̂� + * @throws TraceFileException + */ + protected void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index, IAliasCollector aliasCollector) { + MethodExecution methodExecution = tracePoint.getMethodExecution(); + Boolean isResolved = false; + String objectId = objList.get(index); // calleeSearch() �ł͒ǐՑΏۂ̃I�u�W�F�N�g�͈�‚����A��objList��index�Ԗڂ̗v�f�ȊO�ύX���Ă͂����Ȃ� + String thisObjectId = methodExecution.getThisObjId(); + ArrayList fieldArrays = new ArrayList(); + ArrayList fieldArrayElements = new ArrayList(); + ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), + Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), + Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I��getter�Ăяo���̂͂������A���� + ArrayList argments = methodExecution.getArguments(); + ObjectReference trackingObj = null; + //static���o�R�����null�������Ă��鎞������ + if (objectId != null) { + String returnType = Trace.getReturnType(methodExecution.getSignature()); + if (objectId.equals(srcObject.getId())) { + trackingObj = srcObject; + trackingObj.setCalleeType(returnType); + } else if(objectId.equals(dstObject.getId())) { + trackingObj = dstObject; + trackingObj.setCalleeType(returnType); + } else { + trackingObj = new ObjectReference(objectId, null, returnType); + } + + Reference r; + // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo�� + do { + if (!tracePoint.isValid()) break; + Statement statement = tracePoint.getStatement(); + // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T�� + if (statement instanceof FieldAccess) { + FieldAccess fs = (FieldAccess)statement; + if (objectId != null && objectId.equals(fs.getValueObjId())) { + String ownerObjectId = fs.getContainerObjId(); + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(thisObj, srcObject)); + srcObject = thisObj; + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(thisObj, dstObject)); + dstObject = thisObj; + trackingObj = dstObject; + } + if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = thisObjectId; + objList.set(index, objectId); + } else { + // ���ڎQ�Ƃ̏ꍇ + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(ownerObjectId, objectId, + fs.getContainerClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(ownerObjectId, objectId, + fs.getContainerClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + trackingObj = dstObject; + } + if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = ownerObjectId; + objList.set(index, objectId); + } + isResolved = true; + } else { + // �I�u�W�F�N�g�̗R�������ڌ��‚���Ȃ������ꍇ�ł��A�����ꂩ�̔z��̗v�f�ɗR�����Ă���”\�������� + String refObjType = fs.getValueClassName(); + if (refObjType.startsWith("[L")) { + // �Q�Ƃ����t�B�[���h���z��̏ꍇ + if ((trackingObj.getActualType() != null && refObjType.endsWith(trackingObj.getActualType() + ";")) + || (trackingObj.getCalleeType() != null && refObjType.endsWith(trackingObj.getCalleeType() + ";")) + || (trackingObj.getCallerType() != null && refObjType.endsWith(trackingObj.getCallerType() + ";"))) { + // �z��̗v�f�̕����ǐՒ��̃I�u�W�F�N�g�̌^�ƈ�v�����ꍇ + String ownerObjectId = fs.getContainerObjId(); + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉”\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j + fieldArrays.add(new ObjectReference(fs.getValueObjId(), refObjType)); + fieldArrayElements.add(trackingObj); + } else { + // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A + // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� + // ��蒼��������B) + } + } + } + } + } else if (statement instanceof MethodInvocation) { + // �߂�l + MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + ObjectReference ret = childMethodExecution.getReturnValue(); + if (ret != null && objectId != null && objectId.equals(ret.getId())) { + childMethodExecution.setAugmentation(new DeltaAugmentationInfo()); + ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); + TracePoint childTracePoint = tracePoint.duplicate(); + childTracePoint.stepBackNoReturn(); + calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index, aliasCollector); // �Ăяo���������ɒT�� + if (childMethodExecution.isConstructor()) { + // �R���X�g���N�^�Ăяo���������ꍇ + if (objectId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCreation(true); + eStructure.addSrcSide(r); + srcObject = thisObj; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCreation(true); + eStructure.addDstSide(r); + dstObject = thisObj; + trackingObj = dstObject; + } + if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = thisObjectId; + objList.set(index, objectId); + isResolved = true; + isLost = false; + continue; + } + objectId = objList.get(index); + if (objectId == null) { + // static�Ăяo���̖߂�l�������ꍇ�i���Ԃ�j + trackingObj = null; + isResolved = true; + } else if (objectId.equals(srcObject.getId())) { + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + trackingObj = dstObject; + } + if (isLost) { + checkList.add(objList.get(index)); + isLost = false; + } + } else { + // �I�u�W�F�N�g�̗R�������ڌ��‚���Ȃ������ꍇ�ł��A�ǂ����̔z��̗v�f�ɗR�����Ă���”\�������� + String retType = ret.getActualType(); + if (retType.startsWith("[L")) { + // �߂�l���z��̏ꍇ + if ((trackingObj.getActualType() != null && retType.endsWith(trackingObj.getActualType() + ";")) + || (trackingObj.getCalleeType() != null && retType.endsWith(trackingObj.getCalleeType() + ";")) + || (trackingObj.getCallerType() != null && retType.endsWith(trackingObj.getCallerType() + ";"))) { + // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A + // ���̎��_�ő��̗R���̉”\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ�� + // ��蒼��������B + } + } + } + } + } while (tracePoint.stepBackOver()); + + //�����T�� + if (argments.contains(new ObjectReference(objectId))) { + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v? + isResolved = true; + } + } + + //�R���N�V�����^�Ή� + Reference r; + if (methodExecution.isCollectionType()) { + if (objectId != null) { + // �R���N�V�����^�̏ꍇ�A�����ԁX�̗v�f�𒼐ڕێ����Ă���Ɖ��肷�� + if (objectId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCollection(true); + eStructure.addSrcSide(r); + srcObject = thisObj; + } else if(objectId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCollection(true); + eStructure.addDstSide(r); + dstObject =thisObj; + } + } + objList.set(index, methodExecution.getThisObjId()); + isResolved = true; // �K�v�Ȃ̂ł�? + } + + if (!isResolved && objectId != null) { + // �R�����ǂ��ɂ����‚���Ȃ����� + boolean isSrcSide = true; + if (objectId.equals(srcObject.getId())) { + isSrcSide = true; + } else if (objectId.equals(dstObject.getId())) { + isSrcSide = false; + } + if (trackingObj != null) { + // �܂��z������̗v�f��R���Ƃ��ċ^��(�������D��) + for (int i = 0; i < argments.size(); i++) { + ObjectReference argArray = argments.get(i); + if (argArray.getActualType().startsWith("[L") + && ((trackingObj.getActualType() != null && argArray.getActualType().endsWith(trackingObj.getActualType() + ";")) + || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";")) + || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) { + // �^����v������z������̗v�f��R���Ƃ݂Ȃ� + isResolved = true; + objList.set(index, argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������ + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId())); + r = new Reference(argArray.getId(), trackingObj.getId(), + argArray.getActualType(), trackingObj.getActualType()); + r.setArray(true); + if (isSrcSide) { + eStructure.addSrcSide(r); + srcObject = new ObjectReference(argArray.getId(), argArray.getActualType()); + } else { + eStructure.addDstSide(r); + dstObject = new ObjectReference(argArray.getId(), argArray.getActualType()); + } + objectId = null; + break; + } + } + if (objectId != null) { + // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������) + int indArg = fieldArrayElements.indexOf(trackingObj); + if (indArg != -1) { + // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ� + isResolved = true; + ObjectReference fieldArray = fieldArrays.get(indArg); + objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������ + r = new Reference(fieldArray.getId(), trackingObj.getId(), + fieldArray.getActualType(), trackingObj.getActualType()); + r.setArray(true); + if (isSrcSide) { + eStructure.addSrcSide(r); + eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(), + methodExecution.getThisClassName(), fieldArray.getActualType())); + srcObject = thisObj; + } else { + eStructure.addDstSide(r); + eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(), + methodExecution.getThisClassName(), fieldArray.getActualType())); + dstObject = thisObj; + } + } + } + if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) { + // �ǂ��ɂ����‚���Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�΁A���̃��\�b�h���Ő������ꂽ���̂ƍl���� + isResolved = true; + objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������ + if (isSrcSide) { + eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType())); + srcObject = thisObj; + } else { + eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType())); + dstObject = thisObj; + } + } + } + } + + if (objectId == null && isResolved && !isStatic) { // static �Ăяo������̖߂�l��Ԃ��Ă���ꍇ + objList.set(index, thisObjectId); // ������ǐՂ����� + if (Trace.isNull(srcObject.getId())) { + srcObject = thisObj; + } else if (Trace.isNull(dstObject.getId())) { + dstObject = thisObj; + } + } + + if (isStatic && !isResolved) { // ���͋N���肦�Ȃ�?(get�|�C���g�J�b�g���擾����悤�ɂ�������) + objList.set(index, null); + } + if(!isStatic && !isResolved){ + isLost = true; // final�ϐ�������N���X�ŎQ�Ƃ��Ă���”\�������邪�AcalleeSearch()�͕K���Ăяo�����ɕ��A���Ă����̂ŁA�����ł͉������Ȃ� + } + } + + /** + * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * @param targetRef �ΏۂƂȂ�Q�� + * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @return ���o���� + */ + public ExtractedStructure extract(Reference targetRef, TracePoint before) { + return extract(targetRef, before, defaultAliasCollector); + } + + /** + * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * @param targetRef �ΏۂƂȂ�Q�� + * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i + * @return ���o���� + */ + public ExtractedStructure extract(Reference targetRef, TracePoint before, IAliasCollector aliasCollector) { + TracePoint creationTracePoint; + if (targetRef.isArray()) { + // srcId �̔z��� dstId ���������Ă���”\�������郁�\�b�h���s���擾�i�z���p�̏����j + creationTracePoint = trace.getArraySetTracePoint(targetRef, before); + } else if (targetRef.isCollection()) { + // srcId �̃R���N�V�����^�I�u�W�F�N�g�� dstId ���n����Ă��郁�\�b�h���s���擾�i�R���N�V�����^��p�̏����j + creationTracePoint = trace.getCollectionAddTracePoint(targetRef, before); + } else if (targetRef.isFinalLocal()) { + // srcId �̓����܂��͖����N���X�̃C���X�^���X�� final local �ϐ��ɑ������Ă��� dstId �� �I�u�W�F�N�g���n���ꂽ�”\�������郁�\�b�h���s���擾�ifinal local�̋^��������ꍇ�̏����j + creationTracePoint = trace.getCreationTracePoint(targetRef.getSrcObject(), before); + targetRef = new Reference(creationTracePoint.getMethodExecution().getThisObjId(), targetRef.getDstObjectId(), creationTracePoint.getMethodExecution().getThisClassName(), targetRef.getDstClassName()); + } else { + // �I�u�W�F�N�g�ԎQ�� r ���������ꂽ���\�b�h���s���擾�i�ʏ�j + creationTracePoint = trace.getFieldUpdateTracePoint(targetRef, before); + } + if (creationTracePoint == null) { + return null; + } + return extractSub(creationTracePoint, targetRef, aliasCollector); + } + + /** + * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��) + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint creationTracePoint) { + creationTracePoint = creationTracePoint.duplicate(); + Statement statement = creationTracePoint.getStatement(); + if (statement instanceof FieldUpdate) { + Reference targetRef = ((FieldUpdate)statement).getReference(); + return extractSub(creationTracePoint, targetRef, defaultAliasCollector); + } else { + return null; + } + } + + /** + * �݌v�ύX��̃A���S���Y���̋N�����\�b�h(������) + * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��) + * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint creationTracePoint, IAliasCollector aliasCollector) { + creationTracePoint = creationTracePoint.duplicate(); + Statement statement = creationTracePoint.getStatement(); + if (statement instanceof FieldUpdate) { + Reference targetRef = ((FieldUpdate)statement).getReference(); + return extractSub(creationTracePoint, targetRef, aliasCollector); + } else { + return null; + } + } + + private ExtractedStructure extractSub(TracePoint creationTracePoint, Reference targetRef, IAliasCollector aliasCollector) { + eStructure = new ExtractedStructure(); + ArrayList objList = new ArrayList(); + srcObject = targetRef.getSrcObject(); + dstObject = targetRef.getDstObject(); +if (DEBUG1) { + System.out.println("extract delta of:" + targetRef.getSrcObject().getActualType() + "(" + targetRef.getSrcObjectId() + ")" + " -> " + targetRef.getDstObject().getActualType() + "(" + targetRef.getDstObjectId() + ")"); +} + if (!Trace.isNull(targetRef.getSrcObjectId())) { + objList.add(targetRef.getSrcObjectId()); + } else { + objList.add(null); + } + if (!Trace.isNull(targetRef.getDstObjectId())) { + objList.add(targetRef.getDstObjectId()); + } else { + objList.add(null); + } + return extractSub2(creationTracePoint, objList, aliasCollector); + } + + public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj) { + return extract(tracePoint, argObj, defaultAliasCollector); + } + + public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj, IAliasCollector aliasCollector) { + MethodExecution methodExecution = tracePoint.getMethodExecution(); + eStructure = new ExtractedStructure(); + ArrayList objList = new ArrayList(); + String thisObjectId = methodExecution.getThisObjId(); + objList.add(thisObjectId); + objList.add(argObj.getId()); + srcObject = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), + Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + dstObject = argObj; +if (DEBUG1) { + System.out.println("extract delta of:" + methodExecution.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")"); +} + return extractSub2(tracePoint, objList, aliasCollector); + } + + private ExtractedStructure extractSub2(TracePoint creationTracePoint, ArrayList objList, IAliasCollector aliasCollector) { + eStructure.setCreationMethodExecution(creationTracePoint.getMethodExecution()); + MethodExecution coordinator = callerSearch(trace, creationTracePoint, objList, null, aliasCollector); + eStructure.setCoordinator(coordinator); +if (DEBUG2) { + if (((DeltaAugmentationInfo)coordinator.getAugmentation()).isCoodinator()) { + System.out.println("Coordinator"); + } else { + System.out.println("Warning"); + } + System.out.println("coordinator:" + coordinator.getSignature()); + System.out.println("srcSide:"); + for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) { + Reference ref = eStructure.getDelta().getSrcSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); + } + } + System.out.println("dstSide:"); + for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) { + Reference ref = eStructure.getDelta().getDstSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); + } + } + System.out.println("overCoordinator:"); + MethodExecution parent = coordinator.getParent(); + while (parent != null) { + System.out.println("\t" + parent.getSignature()); + parent = parent.getParent(); + } +} + return eStructure; + } + + /** + * ���ۂ̎Q�ƌ��ƎQ�Ɛ�̃I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p) + * @param srcObj ��������ɂ���Q�ƌ��I�u�W�F�N�g + * @param dstObj ��������ɂ���Q�Ɛ�I�u�W�F�N�g + * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @return�@���o���� + */ + public ExtractedStructure extract(Object srcObj, Object dstObj, TracePoint before) { + return extract(srcObj, dstObj, before, defaultAliasCollector); + } + + /** + * �Q�ƌ��ƎQ�Ɛ�̃I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p) + * @param srcObj ��������ɂ���Q�ƌ��I�u�W�F�N�g + * @param dstObj ��������ɂ���Q�Ɛ�I�u�W�F�N�g + * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @param aliasCollector �f���^���o���ɒǐՂ����I�u�W�F�N�g�̑S�G�C���A�X�����W���郊�X�i + * @return�@���o���� + */ + public ExtractedStructure extract(Object srcObj, Object dstObj, TracePoint before, IAliasCollector aliasCollector) { + Reference targetRef = new Reference(Integer.toString(System.identityHashCode(srcObj)), Integer.toString(System.identityHashCode(dstObj)), null, null); + return extract(targetRef, before, aliasCollector); + } + + /** + * ���\�b�h���s���̃g���[�X�|�C���g�Ǝ��ۂ̎Q�Ɛ�I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p) + * @param tracePoint ���\�b�h���s���̃g���[�X�|�C���g + * @param arg ��������ɂ���Q�Ɛ�I�u�W�F�N�g(���[�J���ϐ�������ɂ��Q�Ɛ�) + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint tracePoint, Object arg) { + return extract(tracePoint, arg, defaultAliasCollector); + } + + /** + * ���\�b�h���s���̃g���[�X�|�C���g�Ǝ��ۂ̎Q�Ɛ�I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p) + * @param tracePoint ���\�b�h���s���̃g���[�X�|�C���g + * @param arg ��������ɂ���Q�Ɛ�I�u�W�F�N�g(���[�J���ϐ�������ɂ��Q�Ɛ�) + * @return ���o���� + */ + public ExtractedStructure extract(TracePoint tracePoint, Object arg, IAliasCollector aliasCollector) { + ObjectReference argObj = new ObjectReference(Integer.toString(System.identityHashCode(arg))); + return extract(tracePoint, argObj, aliasCollector); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾����(�I�����C����͗p) + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̃��\�b�h���s + */ + public MethodExecution getCurrentMethodExecution(Thread thread) { + return trace.getCurrentMethodExecution(thread); + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @return �Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(String methodSignature) { + return trace.getLastMethodExecution(methodSignature); + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�� before �ȑO�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @return�@�Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(String methodSignature, TracePoint before) { + return trace.getLastMethodExecution(methodSignature, before); + } + + public ArrayList getMethodExecutions(String methodSignature) { + return trace.getMethodExecutions(methodSignature); + } + +// public ExtractedStructure extract(MethodExecution caller, MethodExecution callee) { +// eStructure = new ExtractedStructure(); +// ArrayList objList = new ArrayList(); +// String thisObjectId = caller.getThisObjId(); +// objList.add(thisObjectId); +// objList.add(callee.getThisObjId()); +// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(), +// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor())); +// dstObject = new ObjectReference(callee.getThisObjId(), callee.getThisClassName(), +// Trace.getDeclaringType(callee.getSignature(), callee.isConstractor()), Trace.getDeclaringType(callee.getCallerSideSignature(), callee.isConstractor())); +//if (DEBUG1) { +// System.out.println("extract delta of:" + caller.getSignature() + " -> " + callee.getSignature()); +//} +// +// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p���� +// eStructure.setCreationMethodExecution(caller); +// MethodExecution coordinator = callerSearch(trace, caller, objList, null); +// eStructure.setCoordinator(coordinator); +//if (DEBUG2) { +// if (coordinator.isCoodinator()) { +// System.out.println("Coordinator"); +// } else { +// System.out.println("Warning"); +// } +// System.out.println("coordinator:" + coordinator.getSignature()); +// System.out.println("srcSide:"); +// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) { +// Reference ref = eStructure.getDelta().getSrcSide().get(i); +// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { +// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); +// } +// } +// System.out.println("dstSide:"); +// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) { +// Reference ref = eStructure.getDelta().getDstSide().get(i); +// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { +// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); +// } +// } +// System.out.println("overCoordinator:"); +// MethodExecution parent = coordinator.getParent(); +// while (parent != null) { +// System.out.println("\t" + parent.getSignature()); +// parent = parent.getParent(); +// } +//} +// return eStructure; +// } +// +// +// /** +// * ���\�b�h�̈����Ƃ��ăI�u�W�F�N�g���Q�Ƃ����ꍇ�̃f���^�𒊏o���� +// * @param caller �Q�ƌ��̃��\�b�h +// * @param argObj �����Ƃ��ĎQ�Ƃ����I�u�W�F�N�g +// * @return�@���o���� +// */ +// public ExtractedStructure extract(MethodExecution caller, ObjectReference argObj) { +// eStructure = new ExtractedStructure(); +// ArrayList objList = new ArrayList(); +// String thisObjectId = caller.getThisObjId(); +// objList.add(thisObjectId); +// objList.add(argObj.getId()); +// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(), +// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor())); +// dstObject = argObj; +//if (DEBUG1) { +// System.out.println("extract delta of:" + caller.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")"); +//} +// +// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p���� +// eStructure.setCreationMethodExecution(caller); +// MethodExecution coordinator = callerSearch(trace, caller, objList, null); +// eStructure.setCoordinator(coordinator); +//if (DEBUG2) { +// if (coordinator.isCoodinator()) { +// System.out.println("Coordinator"); +// } else { +// System.out.println("Warning"); +// } +// System.out.println("coordinator:" + coordinator.getSignature()); +// System.out.println("srcSide:"); +// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) { +// Reference ref = eStructure.getDelta().getSrcSide().get(i); +// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { +// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); +// } +// } +// System.out.println("dstSide:"); +// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) { +// Reference ref = eStructure.getDelta().getDstSide().get(i); +// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { +// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); +// } +// } +// System.out.println("overCoordinator:"); +// MethodExecution parent = coordinator.getParent(); +// while (parent != null) { +// System.out.println("\t" + parent.getSignature()); +// parent = parent.getParent(); +// } +//} +// return eStructure; +// } +} diff --git a/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java b/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java new file mode 100644 index 0000000..25c38e5 --- /dev/null +++ b/src/org/ntlab/deltaExtractor/DeltaExtractorJSON.java @@ -0,0 +1,622 @@ +package org.ntlab.deltaExtractor; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import org.ntlab.trace.ArrayAccess; +import org.ntlab.trace.ArrayCreate; +import org.ntlab.trace.FieldAccess; +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.ObjectReference; +import org.ntlab.trace.Reference; +import org.ntlab.trace.Statement; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; +import org.ntlab.trace.TracePoint; + +/** + * �f���^���o�A���S���Y��(�z��ւ̃A�N�Z�X�����m�ł���Javassist��JSON�g���[�X�ɑΉ����A�A���S���Y����P����) + * + * @author Nitta + * + */ +public class DeltaExtractorJSON extends DeltaExtractor { + public DeltaExtractorJSON(String traceFile) { + super(new TraceJSON(traceFile)); + } + + public DeltaExtractorJSON(TraceJSON trace) { + super(trace); + } + +// /** +// * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j +// * @param trace�@��͑Ώۃg���[�X +// * @param methodExecution �T�����郁�\�b�h���s +// * @param objList�@�ǐՒ��̃I�u�W�F�N�g +// * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s +// * @return ���‚������R�[�f�B�l�[�^ +// * @throws TraceFileException +// */ +// protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution) { +// return callerSearch(trace, tracePoint, objList, childMethodExecution, new IAliasCollector() { +// @Override +// public void addAlias(Alias alias) { +// } +// @Override +// public void changeTrackingObject(String from, String to) { +// } +// }); +// } + + /** + * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j + * @param trace�@��͑Ώۃg���[�X + * @param methodExecution �T�����郁�\�b�h���s + * @param objList�@�ǐՒ��̃I�u�W�F�N�g + * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s + * @return ���‚������R�[�f�B�l�[�^ + * @throws TraceFileException + */ + protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution, IAliasCollector aliasCollector) { + MethodExecution methodExecution = tracePoint.getMethodExecution(); + methodExecution.setAugmentation(new DeltaAugmentationInfo()); + eStructure.createParent(methodExecution); + String thisObjectId = methodExecution.getThisObjId(); + ArrayList removeList = new ArrayList(); // �ǐՂ��Ă���I�u�W�F�N�g���ō폜�ΏۂƂȂ��Ă������ + ArrayList creationList = new ArrayList(); // ���̃��\�b�h���s���ɐ������ꂽ�I�u�W�F�N�g + int existsInFields = 0; // ���̃��\�b�h���s���Ńt�B�[���h�ɗR�����Ă���I�u�W�F�N�g�̐�(1�ȏ�Ȃ炱�̃��\�b�h���s����this�Ɉˑ�) + boolean isTrackingThis = false; // �Ăяo�����this�Ɉˑ����� + boolean isSrcSide = true; // �Q�ƌ����Q�Ɛ�̂�����̑��̃I�u�W�F�N�g�̗R�������ǂ���this�I�u�W�F�N�g�ɓ��B������? + ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), + Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + + HashMap aliasList = new HashMap<>(); + + if (childMethodExecution == null) { + // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + + if (childMethodExecution != null && objList.contains(childMethodExecution.getThisObjId())) { + // �Ăяo�����this�Ɉˑ����� + if (thisObjectId.equals(childMethodExecution.getThisObjId())) { + // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ��������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, childMethodExecution.getThisObjId(), tracePoint.duplicate())); + } + + if (childMethodExecution != null) { + for (String objId : objList) { + if (!objId.equals(childMethodExecution.getThisObjId())) { + aliasCollector.addAlias(new Alias(Alias.AliasType.ACTUAL_ARGUMENT, -1, objId, tracePoint.duplicate())); // argIndex�͕s�� + } + } + } + + if (childMethodExecution != null && childMethodExecution.isConstructor()) { + // �Ăяo���悪�R���X�g���N�^�������ꍇ + int newIndex = objList.indexOf(childMethodExecution.getThisObjId()); + if (newIndex != -1) { + // �Ăяo���悪�ǐՑΏۂ̃R���X�g���N�^��������field�Ɠ��l�ɏ��� + removeList.add(childMethodExecution.getThisObjId()); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + } + } + + if (childMethodExecution != null && Trace.getMethodName(childMethodExecution.getSignature()).startsWith("access$")) { + // �G���N���[�W���O�C���X�^���X�ɑ΂��郁�\�b�h�Ăяo���������ꍇ + String enclosingObj = childMethodExecution.getArguments().get(0).getId(); // �G���N���[�W���O�C���X�^���X�͑������ɓ����Ă���炵�� + int encIndex = objList.indexOf(enclosingObj); + if (encIndex != -1) { + // thisObject �ɒu����������Afield�Ɠ��l�ɏ��� + removeList.add(enclosingObj); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + } + } + + // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo�� + while (tracePoint.stepBackOver()) { + Statement statement = tracePoint.getStatement(); + // ���ڎQ�ƁA�t�B�[���h�Q�Ƃ���єz��A�N�Z�X�̒T�� + if (statement instanceof FieldAccess) { + FieldAccess fs = (FieldAccess)statement; + String refObjectId = fs.getValueObjId(); + int index = objList.indexOf(refObjectId); + if (index != -1) { + String ownerObjectId = fs.getContainerObjId(); + + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ + removeList.add(refObjectId); + existsInFields++; // set�������get�����o���Ă���”\�������� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + aliasList.put(refObjectId, new Alias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate())); + } else { + // ���ڎQ�Ƃ̏ꍇ + if (refObjectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId, + fs.getContainerClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + } else if(refObjectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(ownerObjectId, refObjectId, + fs.getContainerClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + } + objList.set(index, ownerObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, refObjectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(refObjectId, ownerObjectId); //�ǐՑΏۃI�u�W�F�N�g�̐؂�ւ� + aliasCollector.addAlias(new Alias(Alias.AliasType.CONTAINER, 0, ownerObjectId, tracePoint.duplicate())); + } + } + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + String elementObjectId = aa.getValueObjectId(); + int index = objList.indexOf(elementObjectId); + if (index != -1) { + // �z��A�N�Z�X�̏ꍇ + String arrayObjectId = aa.getArrayObjectId(); + if (elementObjectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(arrayObjectId, elementObjectId, + aa.getArrayClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(arrayObjectId, aa.getArrayClassName()); + } else if(elementObjectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(arrayObjectId, elementObjectId, + aa.getArrayClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(arrayObjectId, aa.getArrayClassName()); + } + objList.set(index, arrayObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_ELEMENT, aa.getIndex(), elementObjectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(elementObjectId, arrayObjectId); //�ǐՑΏۃI�u�W�F�N�g�̐؂�ւ� + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, arrayObjectId, tracePoint.duplicate())); + } + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + String arrayObjectId = ac.getArrayObjectId(); + int index = objList.indexOf(arrayObjectId); + if (index != -1) { + // �z�񐶐��̏ꍇfield�Ɠ��l�ɏ��� + creationList.add(arrayObjectId); + removeList.add(arrayObjectId); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + aliasList.put(arrayObjectId, new Alias(Alias.AliasType.ARRAY_CREATE, 0, arrayObjectId, tracePoint.duplicate())); + } + } else if (statement instanceof MethodInvocation) { + MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + if (!prevChildMethodExecution.equals(childMethodExecution)) { + // �߂�l + ObjectReference ret = prevChildMethodExecution.getReturnValue(); + if (ret != null) { + int retIndex = -1; + retIndex = objList.indexOf(ret.getId()); + if (retIndex != -1) { + // �߂�l���R�������� + prevChildMethodExecution.setAugmentation(new DeltaAugmentationInfo()); + + if (prevChildMethodExecution.isConstructor()) { + // �ǐՑΏۂ�constractor���Ă�ł�����(�I�u�W�F�N�g�̐�����������)field�Ɠ��l�ɏ��� + String newObjId = ret.getId(); + creationList.add(newObjId); + removeList.add(newObjId); + existsInFields++; + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ� + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // getter�Ăяo���Ɠ��l + aliasList.put(newObjId, new Alias(Alias.AliasType.CONSTRACTOR_INVOCATION, 0, newObjId, tracePoint.duplicate())); + continue; + } + String retObj = objList.get(retIndex); + aliasCollector.addAlias(new Alias(Alias.AliasType.METHOD_INVOCATION, 0, retObj, tracePoint.duplicate())); + if (removeList.contains(retObj)) { + // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������ + removeList.remove(retObj); + existsInFields--; + if (existsInFields == 0) { + removeList.remove(thisObjectId); + } + } + ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ� + TracePoint prevChildTracePoint = tracePoint.duplicate(); + prevChildTracePoint.stepBackNoReturn(); + calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex, aliasCollector); // �Ăяo�����T�� + if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId())) { + if ( thisObjectId.equals(prevChildMethodExecution.getThisObjId())) { + // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏��� + removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜�� + isTrackingThis = true; // �Ăяo�����T���O�ɕ��� + } + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, objList.get(retIndex), tracePoint.duplicate())); + } + if (isLost) { + checkList.add(objList.get(retIndex)); + isLost = false; + } + } + } + } + } + } + // --- ���̎��_�� tracePoint �͌Ăяo�������w���Ă��� --- + + // �R���N�V�����^�Ή� + if (methodExecution.isCollectionType()) { + objList.add(thisObjectId); + } + + // �����̎擾 + ArrayList arguments = methodExecution.getArguments(); + + // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z�� + Reference r; + for (int i = 0; i < removeList.size(); i++) { + String removeId = removeList.get(i); + if (arguments.contains(new ObjectReference(removeId))) { + removeList.remove(removeId); // �t�B�[���h�ƈ����̗����ɒǐՑΏۂ����݂����ꍇ�A������D��(���A�P�[�X) + } else if(objList.contains(removeId)) { + // �t�B�[���h�ɂ����Ȃ������ꍇ(�������A�I�u�W�F�N�g�̐������t�B�[���h�Ɠ��l�Ɉ���) + objList.remove(removeId); // �ǐՑΏۂ���O�� + if (!removeId.equals(thisObjectId)) { + // �t�B�[���h�ithis ���� removeId �ւ̎Q�Ɓj���f���^�̍\���v�f�ɂȂ� + if (removeId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����? + eStructure.addSrcSide(r); + srcObject = thisObj; + isSrcSide = true; + } else if (removeId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����? + eStructure.addDstSide(r); + dstObject = thisObj; + isSrcSide = false; + } + aliasCollector.addAlias(aliasList.get(removeId)); + aliasCollector.changeTrackingObject(removeId, thisObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, aliasList.get(removeId).getOccurrencePoint())); + } + } + } + // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� --- + + // �����T�� + boolean existsInAnArgument = false; + for (int i = 0; i < objList.size(); i++) { + String objectId = objList.get(i); + if (objectId != null) { + ObjectReference trackingObj = new ObjectReference(objectId); + if (arguments.contains(trackingObj)) { + // �������R�������� + existsInAnArgument = true; + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(trackingObj), trackingObj.getId(), methodExecution.getEntryPoint())); + } else { + // �R�����ǂ��ɂ����‚���Ȃ����� + boolean isSrcSide2 = true; + trackingObj = null; + if (objectId.equals(srcObject.getId())) { + isSrcSide2 = true; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + isSrcSide2 = false; + trackingObj = dstObject; + } + } + } + } + if (existsInAnArgument) { + // ������1�‚ł��ǐՑΏۂ����݂����ꍇ + if (existsInFields > 0 || isTrackingThis) { + // this�I�u�W�F�N�g��ǐՒ��̏ꍇ + if (!Trace.isNull(thisObjectId)) { + objList.add(thisObjectId); // ����ɒT������ꍇ�A��U��菜���� thisObject �𕜊� + } else { + objList.add(null); // ������static�Ăяo���������ꍇ�A����ȏ�ǐՂ��Ȃ� + } + } + if (tracePoint.isValid()) { + finalCount = 0; + return callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + } + } + + for (int i = 0; i < objList.size(); i++) { + objList.remove(null); + } + if (objList.isEmpty()) { + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(true); + } else { + // �R���������ł��Ȃ����� + if (!methodExecution.isStatic()) { + finalCount++; + if (finalCount <= LOST_DECISION_EXTENSION) { + // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��”\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂��� + if (tracePoint.isValid()) { + MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution, aliasCollector); // �Ăяo����������ɒT�� + if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) { + methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^�����‚����� + } + } + } else if (thisObj.getActualType().contains("$")) { + // �����������܂��͖����N���X�̏ꍇ�A���������I�u�W�F�N�g���O�����\�b�h�̓���final�ϐ�����擾�����Ƃ݂Ȃ��A����Ɏ����̒��̃t�B�[���h�̈��Ƃ݂Ȃ� + for (int i = objList.size() - 1; i >= 0; i--) { + String objectId = objList.get(i); + if (objectId != null) { + ObjectReference trackingObj = new ObjectReference(objectId); + boolean isSrcSide2 = true; + trackingObj = null; + if (objectId.equals(srcObject.getId())) { + isSrcSide2 = true; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + isSrcSide2 = false; + trackingObj = dstObject; + } + if (trackingObj != null) { + r = new Reference(thisObjectId, trackingObj.getId(), + methodExecution.getThisClassName(), trackingObj.getActualType()); + r.setFinalLocal(true); + if (isSrcSide2) { + eStructure.addSrcSide(r); + srcObject = thisObj; + isSrcSide = true; + } else { + eStructure.addDstSide(r); + dstObject = thisObj; + isSrcSide = false; + } + existsInFields++; + objList.remove(objectId); + } + } + } + } + } + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(false); + } + finalCount = 0; + return methodExecution; + } + + /** + * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���) + * @param trace ��͑Ώۃg���[�X + * @param methodExecution �T�����郁�\�b�h���s + * @param objList �ǐՒ��̃I�u�W�F�N�g + * @param isStatic�@�ÓI���\�b�h���ۂ� + * @param index�@objList���̂ǂ̃I�u�W�F�N�g��ǐՂ��Ă��̃��\�b�h���s�ɓ����Ă����̂� + * @throws TraceFileException + */ + protected void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index, IAliasCollector aliasCollector) { + MethodExecution methodExecution = tracePoint.getMethodExecution(); + Boolean isResolved = false; + String objectId = objList.get(index); // calleeSearch() �ł͒ǐՑΏۂ̃I�u�W�F�N�g�͈�‚����A��objList��index�Ԗڂ̗v�f�ȊO�ύX���Ă͂����Ȃ� + String thisObjectId = methodExecution.getThisObjId(); + ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(), + Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), + Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor())); + + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I��getter�Ăяo���̂͂������A���� + ArrayList arguments = methodExecution.getArguments(); + ObjectReference trackingObj = null; + + aliasCollector.addAlias(new Alias(Alias.AliasType.RETURN_VALUE, 0, objectId, tracePoint.duplicate())); + //static���o�R�����null�������Ă��鎞������ + if (objectId != null) { + String returnType = Trace.getReturnType(methodExecution.getSignature()); + if (objectId.equals(srcObject.getId())) { + trackingObj = srcObject; + trackingObj.setCalleeType(returnType); + } else if(objectId.equals(dstObject.getId())) { + trackingObj = dstObject; + trackingObj.setCalleeType(returnType); + } else { + trackingObj = new ObjectReference(objectId, null, returnType); + } + + Reference r; + // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo�� + do { + if (!tracePoint.isValid()) break; + Statement statement = tracePoint.getStatement(); + // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T�� + if (statement instanceof FieldAccess) { + FieldAccess fs = (FieldAccess)statement; + if (objectId != null && objectId.equals(fs.getValueObjId())) { + String ownerObjectId = fs.getContainerObjId(); + if (ownerObjectId.equals(thisObjectId)) { + // �t�B�[���h�Q�Ƃ̏ꍇ + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(thisObj, srcObject)); + srcObject = thisObj; + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(thisObj, dstObject)); + dstObject = thisObj; + trackingObj = dstObject; + } + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, objectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(objectId, ownerObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, ownerObjectId, tracePoint.duplicate())); + if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = thisObjectId; + objList.set(index, objectId); + } else { + // ���ڎQ�Ƃ̏ꍇ + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(ownerObjectId, objectId, + fs.getContainerClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(ownerObjectId, objectId, + fs.getContainerClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName()); + trackingObj = dstObject; + } + aliasCollector.addAlias(new Alias(Alias.AliasType.FIELD, 0, objectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(objectId, ownerObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.CONTAINER, 0, ownerObjectId, tracePoint.duplicate())); + if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = ownerObjectId; + objList.set(index, objectId); + } + isResolved = true; + } + } else if (statement instanceof ArrayAccess) { + ArrayAccess aa = (ArrayAccess)statement; + if (objectId != null && objectId.equals(aa.getValueObjectId())) { + // �z��A�N�Z�X�̏ꍇ + String arrayObjectId = aa.getArrayObjectId(); + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(arrayObjectId, objectId, + aa.getArrayClassName(), srcObject.getActualType())); + srcObject = new ObjectReference(arrayObjectId, aa.getArrayClassName()); + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(arrayObjectId, objectId, + aa.getArrayClassName(), dstObject.getActualType())); + dstObject = new ObjectReference(arrayObjectId, aa.getArrayClassName()); + trackingObj = dstObject; + } + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_ELEMENT, aa.getIndex(), objectId, tracePoint.duplicate())); + aliasCollector.changeTrackingObject(objectId, arrayObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY, 0, arrayObjectId, tracePoint.duplicate())); + objectId = arrayObjectId; + objList.set(index, objectId); + isResolved = true; + } + } else if (statement instanceof ArrayCreate) { + ArrayCreate ac = (ArrayCreate)statement; + if (objectId != null && objectId.equals(ac.getArrayObjectId())) { + // �z�񐶐��̏ꍇ + if (objectId.equals(srcObject.getId())) { + eStructure.addSrcSide(new Reference(thisObj, srcObject)); + srcObject = thisObj; + trackingObj = srcObject; + } else if(objectId.equals(dstObject.getId())) { + eStructure.addDstSide(new Reference(thisObj, dstObject)); + dstObject = thisObj; + trackingObj = dstObject; + } + aliasCollector.addAlias(new Alias(Alias.AliasType.ARRAY_CREATE, 0, ac.getArrayObjectId(), tracePoint.duplicate())); + aliasCollector.changeTrackingObject(ac.getArrayObjectId(), thisObjectId); + aliasCollector.addAlias(new Alias(Alias.AliasType.THIS, 0, thisObjectId, tracePoint.duplicate())); + if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = thisObjectId; + objList.set(index, objectId); + } + } else if (statement instanceof MethodInvocation) { + // �߂�l + MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution(); + ObjectReference ret = childMethodExecution.getReturnValue(); + if (ret != null && objectId != null && objectId.equals(ret.getId())) { + childMethodExecution.setAugmentation(new DeltaAugmentationInfo()); + ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId)); + TracePoint childTracePoint = tracePoint.duplicate(); + childTracePoint.stepBackNoReturn(); + aliasCollector.addAlias(new Alias(Alias.AliasType.METHOD_INVOCATION, 0, ret.getId(), tracePoint.duplicate())); + calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index, aliasCollector); // �Ăяo���������ɒT�� + if (childMethodExecution.isConstructor()) { + // �R���X�g���N�^�Ăяo���������ꍇ + if (objectId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCreation(true); + eStructure.addSrcSide(r); + srcObject = thisObj; + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCreation(true); + eStructure.addDstSide(r); + dstObject = thisObj; + trackingObj = dstObject; + } + if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ + else objectId = thisObjectId; + objList.set(index, objectId); + isResolved = true; + isLost = false; + continue; + } + objectId = objList.get(index); + if (objectId == null) { + // static�Ăяo���̖߂�l�������ꍇ�i���Ԃ�j + trackingObj = null; + isResolved = true; + } else if (objectId.equals(srcObject.getId())) { + trackingObj = srcObject; + } else if (objectId.equals(dstObject.getId())) { + trackingObj = dstObject; + } + if (isLost) { + checkList.add(objList.get(index)); + isLost = false; + } + if (objectId != null) { + if (childMethodExecution.getThisObjId().equals(objectId)) { + aliasCollector.addAlias(new Alias(Alias.AliasType.RECEIVER, 0, objectId, tracePoint.duplicate())); + } + } + } + } + } while (tracePoint.stepBackOver()); + + //�����T�� + if (arguments.contains(new ObjectReference(objectId))) { + ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v? + isResolved = true; + aliasCollector.addAlias(new Alias(Alias.AliasType.FORMAL_PARAMETER, arguments.indexOf(new ObjectReference(objectId)), objectId, methodExecution.getEntryPoint())); + } + } + + //�R���N�V�����^�Ή� + Reference r; + if (methodExecution.isCollectionType()) { + if (objectId != null) { + // �R���N�V�����^�̏ꍇ�A�����ԁX�̗v�f�𒼐ڕێ����Ă���Ɖ��肷�� + if (objectId.equals(srcObject.getId())) { + r = new Reference(thisObj, srcObject); + r.setCollection(true); + eStructure.addSrcSide(r); + srcObject = thisObj; + } else if(objectId.equals(dstObject.getId())) { + r = new Reference(thisObj, dstObject); + r.setCollection(true); + eStructure.addDstSide(r); + dstObject =thisObj; + } + } + objList.set(index, methodExecution.getThisObjId()); + isResolved = true; // �K�v�Ȃ̂ł�? + } + + if (objectId == null && isResolved && !isStatic) { // static �Ăяo������̖߂�l��Ԃ��Ă���ꍇ + objList.set(index, thisObjectId); // ������ǐՂ����� + if (Trace.isNull(srcObject.getId())) { + srcObject = thisObj; + } else if (Trace.isNull(dstObject.getId())) { + dstObject = thisObj; + } + } + + if (isStatic && !isResolved) { // ���͋N���肦�Ȃ�?(get�|�C���g�J�b�g���擾����悤�ɂ�������) + objList.set(index, null); + } + if(!isStatic && !isResolved){ + isLost = true; // final�ϐ�������N���X�ŎQ�Ƃ��Ă���”\�������邪�AcalleeSearch()�͕K���Ăяo�����ɕ��A���Ă����̂ŁA�����ł͉������Ȃ� + } + } +} diff --git a/src/org/ntlab/deltaExtractor/ExtractedStructure.java b/src/org/ntlab/deltaExtractor/ExtractedStructure.java new file mode 100644 index 0000000..dedf499 --- /dev/null +++ b/src/org/ntlab/deltaExtractor/ExtractedStructure.java @@ -0,0 +1,68 @@ +package org.ntlab.deltaExtractor; + +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.Reference; + + +public class ExtractedStructure { + + private Delta delta = new Delta(); + private MethodExecution coordinator = null; + private MethodExecution parent = null; + private MethodExecution creationCallTree; + + public Delta getDelta() { + return delta; + } + + public MethodExecution getCoordinator() { + return coordinator; + } + + /** + * ������ ������ɍ폜���邱�� + * @param coordinator + */ + public void setCoordinator(MethodExecution coordinator) { + this.coordinator = coordinator; + } + + public void createParent(MethodExecution methodExecution) { + coordinator = methodExecution; + parent = null; + } + +// public void addParent(MethodExecution callTree) { +// if (parent == null) +// coordinator.addChild(parent = callTree); +// else +// parent.addChild(parent = callTree); +// } +// +// public void addChild(MethodExecution callTree) { +// if (parent == null) +// coordinator.addChild(callTree); +// else +// parent.addChild(callTree); +// } +// + public void addSrcSide(Reference reference) { + delta.addSrcSide(reference); + } + + public void addDstSide(Reference reference) { + delta.addDstSide(reference); + } + + public void changeParent() { + } + + public void setCreationMethodExecution(MethodExecution callTree) { + creationCallTree = callTree; + } + + public MethodExecution getCreationCallTree() { + return creationCallTree; + } + +} diff --git a/src/org/ntlab/deltaExtractor/IAliasCollector.java b/src/org/ntlab/deltaExtractor/IAliasCollector.java new file mode 100644 index 0000000..66b5388 --- /dev/null +++ b/src/org/ntlab/deltaExtractor/IAliasCollector.java @@ -0,0 +1,21 @@ +package org.ntlab.deltaExtractor; + +/** + * Collect delta aliases interface. + * + * @author Nitta Lab. + */ +public interface IAliasCollector { + + /** + * @param alias Object state in the flow of program execution. + */ + void addAlias(Alias alias); + + /** + * @param fromObjId + * @param toObjId + */ + void changeTrackingObject(String fromObjId, String toObjId); + +} diff --git a/src/org/ntlab/deltaExtractor/Test.java b/src/org/ntlab/deltaExtractor/Test.java new file mode 100644 index 0000000..5cadd9c --- /dev/null +++ b/src/org/ntlab/deltaExtractor/Test.java @@ -0,0 +1,312 @@ +package org.ntlab.deltaExtractor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.ObjectReference; +import org.ntlab.trace.Reference; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; +import org.ntlab.trace.TracePoint; + +public class Test { + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + long time = System.nanoTime(); +// TraceJSON trace = new TraceJSON("traces\\_worstCase.txt"); +// DeltaExtractorJSON s = new DeltaExtractorJSON(trace); +// HashMap threads = trace.getAllThreads(); +// ThreadInstance thread = threads.values().iterator().next(); +// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); +// ExtractedStructure e = s.extract(new Reference(null, null, "worstCase.P", "worstCase.M"), tp); + +// TraceJSON trace = new TraceJSON("traces\\_finalLocal.txt"); +// DeltaExtractorJSON s = new DeltaExtractorJSON(trace); +// HashMap threads = trace.getAllThreads(); +// ThreadInstance thread = threads.values().iterator().next(); +// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); +// ExtractedStructure e = s.extract(new Reference(null, null, "finalLocal.Main$1Test", "finalLocal.Main$A"), tp); + + TraceJSON trace = new TraceJSON("traces\\__arraySample.txt"); + DeltaExtractorJSON s = new DeltaExtractorJSON(trace); + HashMap threads = trace.getAllThreads(); + ThreadInstance thread = threads.values().iterator().next(); + TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); + ExtractedStructure e = s.extract(new Reference(null, null, "arraySample.D", "arraySample.C"), tp); + +// TraceJSON trace = new TraceJSON("traces\\__arraySample.txt"); +// DeltaExtractorJSON s = new DeltaExtractorJSON(trace); +// HashMap threads = trace.getAllThreads(); +// ThreadInstance thread = threads.values().iterator().next(); +// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); +// Reference ref = new Reference(null, null, "[Ljava.lang.Object;", "arraySample.B"); +// ref.setArray(true); +// ExtractedStructure e = s.extract(ref, tp); + +// TraceJSON trace = new TraceJSON("traces\\_threadSample.txt"); +// DeltaExtractor s = new DeltaExtractorJSON(trace); +// HashMap threads = trace.getAllThreads(); +// Iterator it = threads.values().iterator(); +// it.next(); +// it.next(); +// ThreadInstance thread = it.next(); +// TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); +// ExtractedStructure e = s.extract(new Reference(null, null, "threadSample.D", "threadSample.C"), tp); + + // DeltaExtractor s = new DeltaExtractor("documents\\finalLocal.txt"); + // ExtractedStructure es = s.extract(); + // s.extract("framework.RWT.RWTFrame3D", + // "fight3D.CharacterSelectContainer"); +// s.extract("framework.B", "application.SubC"); + // s.extract("application.SubA", "framework.B"); + // FrameworkUsage usage = extractor.extract("framework.B", + // "application.SubC"); + // FrameworkUsage usage = extractor.extract("application.SubA", + // "framework.B"); + // s.extract("framework.model3D.Object3D", + // "javax.media.j3d.TransformGroup"); + // s.extract("fight3D.Character", "fight3D.WeaponModel"); + // s.extract("test.E","test.C"); +// ExtractedStructure e = s.extract(new Reference("finalLocal.Main$1Test", "finalLocal.Main$A", null, null)); + +// --------------- Eclipse Core --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Core.txt"); +// CallTree m = null; +// ExtractedStructure e = null; +// do { +// if (m == null) { +// m = s.getCallTreeBackwardly("public boolean java.util.HashSet.add("); +// } else { +// m = s.getCallTreeBackwardly("public boolean java.util.HashSet.add(", m.getStartLine() - 1); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// System.out.println(m.getSignature() + ":" + argments.size()); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.eclipse.ui.internal.registry.ActionSetDescriptor")) { +// e = s.extract(m, argments.get(i)); +// break; +// } +// } +// } +// } while (m != null); + + +// --------------- Eclipse UI --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-ContextMenu.txt"); +// CallTree m = null; +// ExtractedStructure e = null; +// do { +// if (m == null) { +// m = s.getCallTreeBackwardly("private void org.eclipse.jface.action.ContributionManager.addToGroup("); +// } else { +// m = s.getCallTreeBackwardly("private void org.eclipse.jface.action.ContributionManager.addToGroup(", m.getStartLine() - 1); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// System.out.println(m.getSignature() + ":" + argments.size()); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.eclipse.ui.internal.PluginActionCoolBarContributionItem")) { +// e = s.extract(m, argments.get(i)); +// break; +// } +// } +// } +// } while (m != null); + + /////////////////////////////////////////////////////////////////////////////////// + // // + // ICSME2015���e�p // + // // + /////////////////////////////////////////////////////////////////////////////////// + +// // --------------- Eclipse (2014/12/6 �v���O�����������؎��� �ۑ�1, �ȉ���1��ڂ̃f���^) --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Console2.txt"); +// ExtractedStructure e = null; +// do { +// System.out.println(System.nanoTime() - time); +// if (e == null) { +// e = s.extract(new Reference(null, null, "org.eclipse.jface.action.ActionContributionItem", +// "org.eclipse.ui.console.actions.ClearOutputAction")); +// } else { +// e = s.extract(new Reference(null, null, "org.eclipse.jface.action.ActionContributionItem", +// "org.eclipse.ui.console.actions.ClearOutputAction"), e.getCreationCallTree().getEntryPoint()); +// } +// } while (e != null); + + +// --------------- Eclipse (2014/12/19-20 �v���O�����������؎��� �ۑ�2, �ȉ���2��ڂ̃f���^) --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-JavaEditor.txt"); +// ExtractedStructure e = null; +// do { +// System.out.println(System.nanoTime() - time); +// if (e == null) { +// e = s.extract(new Reference(null, null, "org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer", +// "org.eclipse.jface.text.contentassist.ContentAssistant")); +// } else { +// e = s.extract(new Reference(null, null, "org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer", +// "org.eclipse.jface.text.contentassist.ContentAssistant"), e.getCreationCallTree().getEntryPoint()); +// } +// } while (e != null); + + +// // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�3, �ȉ���1��ڂ̃f���^) --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt"); +// MethodExecution m = null; +// ExtractedStructure e = null; +// do { +// System.out.println(System.nanoTime() - time); +// if (m == null) { +// m = s.getLastMethodExecution("protected void org.tigris.gef.base.SelectionManager.addFig("); +// } else { +// m = s.getLastMethodExecution("protected void org.tigris.gef.base.SelectionManager.addFig(", m.getEntryPoint()); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// System.out.println(m.getSignature() + ":" + argments.size()); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.argouml.uml.diagram.static_structure.ui.FigClass")) { +// e = s.extract(m.getEntryPoint(), argments.get(i)); +// break; +// } +// } +// } +// } while (m != null); + + +// // --------------- ArgoUML (2014/12/19-20 �v���O�����������؎��� �ۑ�4, �ȉ���3��ڂ̃f���^) --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt"); +// MethodExecution m = null; +// ExtractedStructure e = null; +// do { +// System.out.println(System.nanoTime() - time); +// if (m == null) { +// m = s.getLastMethodExecution("public abstract interface boolean java.util.List.add("); +// } else { +// m = s.getLastMethodExecution("public abstract interface boolean java.util.List.add(", m.getEntryPoint()); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// System.out.println(m.getSignature() + ":" + argments.size()); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.argouml.uml.diagram.static_structure.ui.FigClass")) { +// e = s.extract(m.getEntryPoint(), argments.get(i)); +// break; +// } +// } +// } +// } while (m != null); + + /////////////////////////////////////////////////////////////////////////////////// + // // + // SANER2016���e�p // + // // + /////////////////////////////////////////////////////////////////////////////////// + + // --------------- Eclipse SWT (2015/10/31 �A�[�L�e�N�`���������؎��� �ۑ�1) --------------- + // ��1(1st�f���^), �ȉ��̃f���^ +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Console2.txt"); +// MethodExecution m = null; +// ExtractedStructure e = null; +// System.out.println(System.nanoTime() - time); +// do { +// if (m == null) { +// m = s.getLastMethodExecution("public void org.eclipse.jface.action.Action.runWithEvent("); +// } else { +// TracePoint nextTp = m.getEntryPoint(); +// nextTp.stepBackOver(); +// m = s.getLastMethodExecution("public void org.eclipse.jface.action.Action.runWithEvent(", nextTp); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.eclipse.swt.widgets.Event")) { +// System.out.println(System.nanoTime() - time); +// e = s.extract(m.getEntryPoint(), argments.get(i)); +// break; +// } +// } +// } +// } while (e == null); +// System.out.println(System.nanoTime() - time); +// System.out.println("//////////////////////////////////"); +// +// // ��2,3(2nd�f���^), ��1�̑���, �ȉ��̃f���^ +// Reference nextTarget = e.getDelta().getSrcSide().get(6); +// e = s.extract(nextTarget, e.getCoordinator().getEntryPoint()); + + +// // --------------- Eclipse JDT (2015/10/31 �A�[�L�e�N�`���������؎��� �ۑ�2) --------------- +// // ��1,2(1st�f���^), �ȉ��̃f���^(���o�Ƃ��Ă�2��) +// DeltaExtractor s = new DeltaExtractor("documents\\eclipse-Debug1.txt"); +// MethodExecution m = null; +// +// System.out.println(System.nanoTime() - time); +// ExtractedStructure e = null; +// do { +// if (m == null) { +// m = s.getLastMethodExecution("public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent("); +// } else { +// TracePoint nextTp = m.getEntryPoint(); +// nextTp.stepBackOver(); +// m = s.getLastMethodExecution("public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent(", nextTp); +// } +// if (m != null) { +// ArrayList argments = m.getArguments(); +// for (int i = 0; i < argments.size(); i++) { +// if (argments.get(i).getActualType().equals("org.eclipse.jdi.internal.event.BreakpointEventImpl")) { +// System.out.println(System.nanoTime() - time); +// e = s.extract(m.getEntryPoint(), argments.get(i)); +// break; +// } +// } +// } +// } while (e == null); +// Reference nextTarget = e.getDelta().getDstSide().get(3); // EventDispatcher$1 -> EventSetImpl +// e = s.extract(nextTarget, m.getEntryPoint()); +// System.out.println(System.nanoTime() - time); +// System.out.println("//////////////////////////////////"); +// +// // ��3(2nd�f���^), �ȉ��̃f���^ +// MethodExecution m2 = e.getCoordinator().getChildren().get(21); +// e = s.extract(m2.getExitPoint(), new ObjectReference("859038530", "org.eclipse.jdi.internal.jdwp.JdwpCommandPacket")); +// System.out.println(System.nanoTime() - time); +// System.out.println("//////////////////////////////////"); +// +// +// // ��4(3rd�f���^), �ȉ��̃f���^ +// m = e.getCoordinator().getChildren().get(0).getChildren().get(1).getChildren().get(4); +// Reference lastTarget = new Reference(e.getDelta().getDstSide().get(1).getSrcObject(), e.getDelta().getDstSide().get(0).getDstObject()); +// lastTarget.setCollection(true); +// e = s.extract(lastTarget, m.getExitPoint()); + + +// // --------------- ArgoUML + GEF (2014/12/19-20 �v���O�����������؎��� �ۑ�3, �ȉ��̃f���^) --------------- +// DeltaExtractor s = new DeltaExtractor("documents\\ArgoUML-3.txt"); +// MethodExecution m = null; +// ExtractedStructure e = null; +// System.out.println(System.nanoTime() - time); +// m = s.getLastMethodExecution("public void org.argouml.uml.diagram.ui.ActionRemoveFromDiagram.actionPerformed("); +//// m = s.getLastMethodExecution("public java.util.Vector org.tigris.gef.base.SelectionManager.getFigs("); +// if (m != null) { +// System.out.println(System.nanoTime() - time); +// Reference r = new Reference(null, null, "java.util.ArrayList", "org.argouml.uml.diagram.static_structure.ui.SelectionClass"); +// r.setCollection(true); +// e = s.extract(r, m.getEntryPoint()); +// } + + + System.out.println(System.nanoTime() - time); + System.out.println("//////////////////////////////////"); +// // s.extractArg(e.getCoodinator(), 123456789); +// // s.getCallHistory(e.getCoodinator()); + + } +} diff --git a/src/org/ntlab/deltaViewer/DeltaAliasCollector.java b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java new file mode 100644 index 0000000..ed0951e --- /dev/null +++ b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java @@ -0,0 +1,73 @@ +package org.ntlab.deltaViewer; + +import java.util.ArrayList; +import java.util.Collection; + +import org.ntlab.deltaExtractor.Alias; +import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; + +/** + * Collect delta aliases for MagnetRON. + * + * @author Nitta Lab. + */ +public class DeltaAliasCollector implements IAliasCollector { + + private String srcObjId; + private String dstObjId; + private ArrayList aliasList = new ArrayList<>(); + + public DeltaAliasCollector() { + } + + /** + * @param srcObjId + * @param dstObjId + */ + public DeltaAliasCollector(String srcObjId, String dstObjId) { + this.srcObjId = srcObjId; + this.dstObjId = dstObjId; + } + + @Override + public void addAlias(Alias alias) { + switch(alias.getAliasType()) { + case RETURN_VALUE: + aliasList.add(0, alias); + break; + case METHOD_INVOCATION: + aliasList.add(0, alias); + break; + case FORMAL_PARAMETER: + aliasList.add(0, alias); + alias.getOccurrencePoint().getMethodExecution().getThisObjId(); + break; + case ACTUAL_ARGUMENT: + aliasList.add(0, alias); + break; + case THIS: + aliasList.add(0, alias); + break; + case RECEIVER: + aliasList.add(0, alias); + if (alias.getOccurrencePoint().getStatement() instanceof MethodInvocation) { + MethodExecution me = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + } + break; + default: + } + System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo() + " : " + alias.getAliasType().toString()); + } + + @Override + public void changeTrackingObject(String fromObjId, String toObjId) { + System.out.println(fromObjId + " -> " + toObjId); + } + + public Collection getAliasList() { + return this.aliasList; + } + +} diff --git a/src/org/ntlab/deltaViewer/DeltaAnimation.java b/src/org/ntlab/deltaViewer/DeltaAnimation.java new file mode 100644 index 0000000..bc01761 --- /dev/null +++ b/src/org/ntlab/deltaViewer/DeltaAnimation.java @@ -0,0 +1,355 @@ +package org.ntlab.deltaViewer; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.util.Timer; +import java.util.TimerTask; + +import javax.swing.SwingUtilities; + +import com.mxgraph.canvas.mxGraphics2DCanvas; +import com.mxgraph.model.mxICell; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxPoint; + +/** + * Generate delta animation for MagnetRON. + * + * @author Nitta Lab. + */ +public class DeltaAnimation { + + private DeltaGraphAdapter mxgraph; + private mxGraphComponent mxgraphComponent; + + private Graphics2D graphics2D; + private Timer timer; + private static int FINAL_STEP_COUNT = 10; + + private mxICell sourceCell; + + GeneralPath p = new GeneralPath(); + + // X, Y + private mxPoint sourcePoint; + private mxPoint targetPoint; + private mxPoint curPoint; + private mxPoint updatePoint = new mxPoint(); + + // Width, Height + private Dimension targetDimension; + private Dimension curDimension = new Dimension(); + private Dimension updateDimension = new Dimension(); + + private double scale = 1; + + /** + * @param mxgraph + * @param mxgraphComponent + */ + public DeltaAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) { + this.mxgraph = mxgraph; + this.mxgraphComponent = mxgraphComponent; + graphics2D = (Graphics2D)mxgraphComponent.getGraphics(); + } + + /** + * @param zoomLevel Zoom level of MagnetRON view. + */ + public void setScale(double zoomLevel) { + this.scale = zoomLevel; + } + + /** + * Set to move animation sourcell vertex to targetPoint. + * + * @param sourceCell Vertex. + * @param targetPoint XY coordinates. + */ + public void setVertexAnimation(mxICell sourceCell, mxPoint targetPoint) { + this.sourceCell = sourceCell; + this.targetPoint = targetPoint; + curPoint = new mxPoint(sourceCell.getGeometry().getX(), sourceCell.getGeometry().getY()); +// System.out.println("sourcePoint : " + sourceCell.getGeometry().getPoint()); +// System.out.println("targetPoint : " + targetPoint); + calculateResizeLineModel(); + } + + /** + * Set stretch(expand) animation of edge from sourcePoint to targetPoint. + * + * @param sourcePoint Edge sourcePoint. + * @param targetPoint Edge targetPoint. + */ + public void setExpandEdgeAnimation(mxPoint sourcePoint, mxPoint targetPoint) { + this.sourcePoint = new mxPoint(sourcePoint.getX() * scale + 1, sourcePoint.getY() * scale + 1); + this.targetPoint = new mxPoint(targetPoint.getX() * scale, targetPoint.getY() * scale); + curPoint = this.sourcePoint; +// System.out.println("sourcePoint : " + sourcePoint); +// System.out.println("targetPoint : " + targetPoint); + + graphics2D = (Graphics2D)mxgraphComponent.getGraphics(); + graphics2D.setColor(Color.decode("#008000")); + + float width = (float) (1 * scale); + Stroke dashed = new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[]{(float) (3.0f * scale * width), (float) (3.0f * scale * width)}, 0.0f); + graphics2D.setStroke(dashed); + calculateResizeLineModel(); + } + + /** + * Set to move animation sourcell vertex clone to targetPoint, reduce edge length. + * + * @param sourceCell Remove sourceCell vertex clone. + * @param targetPoint + */ + public void setReductionEdgeAnimation(mxICell sourceCell, mxPoint targetPoint) { + this.sourceCell = sourceCell; + this.targetPoint = targetPoint; + curPoint = new mxPoint(sourceCell.getGeometry().getX(), sourceCell.getGeometry().getY()); +// System.out.println("sourcePoint : " + sourceCell.getGeometry().getPoint()); +// System.out.println("targetPoint : " + targetPoint); + calculateResizeLineModel(); + } + + /** + * Set animation resize vertex. + * + * @param sourceCell + * @param targetDimension Vertex (Width, Height) + */ + public void setResizeVertexAnimation(mxICell sourceCell, Dimension targetDimension) { + this.sourceCell = sourceCell; + this.targetDimension = targetDimension; + curDimension.setSize(sourceCell.getGeometry().getWidth(), sourceCell.getGeometry().getHeight()); + calculateResizeVertexModel(); + } + + /** + * Calculate updatePoint every second from curPoint and targetPoint. + */ + public void calculateResizeLineModel() { + mxPoint distancePoint = new mxPoint(); + distancePoint.setX(targetPoint.getX() - curPoint.getX()); + distancePoint.setY(targetPoint.getY() - curPoint.getY()); + updatePoint.setX(distancePoint.getX() / FINAL_STEP_COUNT); + updatePoint.setY(distancePoint.getY() / FINAL_STEP_COUNT); + } + + /** + * Calculate updateDimension every second from curPoint and targetPoint. + */ + public void calculateResizeVertexModel() { + Dimension distanceDimension = new Dimension(); + distanceDimension.setSize(targetDimension.getWidth() - curDimension.getWidth(), targetDimension.getHeight() - curDimension.getWidth()); + updateDimension.setSize(distanceDimension.getWidth() / FINAL_STEP_COUNT, distanceDimension.getHeight() / FINAL_STEP_COUNT); + } + + /** + * Start animation to move sourcell vertex to targetPoint for 10 sec. + */ + public void startVertexAnimation() { + timer = new Timer(); + timer.schedule(new TimerTask() { + int stepCount = 0; + + @Override + public void run() { + if(stepCount < FINAL_STEP_COUNT) { + updateVertexAnimation(); + stepCount++; + if(stepCount >= FINAL_STEP_COUNT){ + timer.cancel(); + } + } + } + }, 0, 100); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Start stretch(expand) animation of edge from sourcePoint to targetPoint for 10 sec. + */ + public void startExpandEdgeAnimation() { + timer = new Timer(); + timer.schedule(new TimerTask() { + int stepCount = 0; + + @Override + public void run() { + if(stepCount < FINAL_STEP_COUNT) { + updateExpandEdgeAnimation(); + stepCount++; + if(stepCount >= FINAL_STEP_COUNT){ + timer.cancel(); + } + } + } + }, 0, 100); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Start move animation sourcell vertex clone to targetPoint, reduce edge length for 10 sec. + */ + public void startReductionEdgeAnimation() { + timer = new Timer(); + timer.schedule(new TimerTask() { + int stepCount = 0; + + @Override + public void run() { + if(stepCount < FINAL_STEP_COUNT) { + updateReductionEdgeAnimation(); + stepCount++; + if(stepCount >= FINAL_STEP_COUNT){ + timer.cancel(); + } + } + } + }, 0, 100); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Start animation resize vertex for 10 sec. + */ + public void startResizeVertexAnimation() { + timer = new Timer(); + timer.schedule(new TimerTask() { + int stepCount = 0; + + @Override + public void run() { + if(stepCount < FINAL_STEP_COUNT) { + updateResizeVertexAnimation(); + stepCount++; + if(stepCount >= FINAL_STEP_COUNT){ + timer.cancel(); + } + } + } + }, 0, 100); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Update animation to move sourcell vertex to targetPoint every second. + */ + private void updateVertexAnimation() { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + curPoint.setX(sourceCell.getGeometry().getX()); + curPoint.setY(sourceCell.getGeometry().getY()); + sourceCell.getGeometry().setX(curPoint.getX() + updatePoint.getX()); + sourceCell.getGeometry().setY(curPoint.getY() + updatePoint.getY()); +// System.out.println(sourceCell.getGeometry().getPoint()); + } finally { + mxgraph.getModel().endUpdate(); + } + mxgraphComponent.refresh(); + } + + /** + * Update stretch(expand) animation of edge length updatePoint every second. + */ + private void updateExpandEdgeAnimation() { + Runnable r = new Runnable() { + public void run() { + p.reset(); + p.moveTo((float)curPoint.getX(), (float)curPoint.getY()); + curPoint.setX(curPoint.getX() + updatePoint.getX()); + curPoint.setY(curPoint.getY() + updatePoint.getY()); +// System.out.println("curPoint : " + curPoint); + p.lineTo((float)curPoint.getX(), (float)curPoint.getY()); + graphics2D.draw(p); + } + }; + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + if (!SwingUtilities.isEventDispatchThread()) { + SwingUtilities.invokeLater(r); + } else { + r.run(); + } + } + + /** + * Update move animation sourcell vertex clone to targetPoint, reduce edge length updatePoint every second. + */ + private void updateReductionEdgeAnimation() { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + curPoint.setX(sourceCell.getGeometry().getX()); + curPoint.setY(sourceCell.getGeometry().getY()); + sourceCell.getGeometry().setX(curPoint.getX() + updatePoint.getX()); + sourceCell.getGeometry().setY(curPoint.getY() + updatePoint.getY()); + // System.out.println(sourceCell.getGeometry().getPoint()); + } finally { + mxgraph.getModel().endUpdate(); + } + mxgraphComponent.refresh(); + } + + /** + * Update animation resize vertex every second. + */ + private void updateResizeVertexAnimation() { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + double preCenterX = sourceCell.getGeometry().getCenterX(); + double preCenterY = sourceCell.getGeometry().getCenterY(); + + curDimension.setSize(sourceCell.getGeometry().getWidth(), sourceCell.getGeometry().getHeight()); + sourceCell.getGeometry().setWidth(curDimension.getWidth() + updateDimension.getWidth()); + sourceCell.getGeometry().setHeight(curDimension.getHeight() + updateDimension.getHeight()); + + double curCenterX = sourceCell.getGeometry().getCenterX(); + double curCenterY = sourceCell.getGeometry().getCenterY(); + double distanceX = (curCenterX - preCenterX); + double distanceY = (curCenterY - preCenterY); + double curX = sourceCell.getGeometry().getX(); + double curY = sourceCell.getGeometry().getY(); + + sourceCell.getGeometry().setX(curX - distanceX); + sourceCell.getGeometry().setY(curY - distanceY); + + for (int i = 0; i < sourceCell.getChildCount(); i++) { + mxICell childCell = sourceCell.getChildAt(i); + System.out.println("child" + childCell); + curX = childCell.getGeometry().getX(); + curY = childCell.getGeometry().getY(); + childCell.getGeometry().setX(curX + distanceX); + childCell.getGeometry().setY(curY + distanceY); + } + } finally { + mxgraph.getModel().endUpdate(); + } + mxgraphComponent.refresh(); + } +} diff --git a/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java b/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java new file mode 100644 index 0000000..b0398ff --- /dev/null +++ b/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java @@ -0,0 +1,152 @@ +package org.ntlab.deltaViewer; + +import org.jgrapht.Graph; +import org.jgrapht.ext.JGraphXAdapter; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.DirectedWeightedPseudograph; + +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxICell; +import com.mxgraph.util.mxConstants; + +/** + * JGraphX(visualize) to JGraphT(model) DeltaGraphAdapter for MagnetRON. + * + * @author Nitta Lab. + */ +public class DeltaGraphAdapter extends JGraphXAdapter { + protected Graph graphT; + + public DeltaGraphAdapter(DirectedWeightedPseudograph graphT) { + super(graphT); + this.graphT = graphT; + } + + /** + * Draw new vertex into the graph. + * + * @param vertex Vertex to be added to the graph. + */ + private mxICell addJGraphTVertex(Object vertex) { + getModel().beginUpdate(); + + try { + // create a new JGraphX vertex at position 0 + mxICell cell = (mxICell) super.insertVertex(defaultParent, null, vertex, 0, 0, 0, 0); + + // update cell size so cell isn't "above" graph + updateCellSize(cell); + + // Save reference between vertex and cell. + getVertexToCellMap().put(vertex, cell); + getCellToVertexMap().put(cell, vertex); + return cell; + } finally { + getModel().endUpdate(); + } + } + + /** + * Draw new egde into the graph. + * + * @param edge Edge to be added to the graph. Source and target vertices are needed. + */ + private mxICell addJGraphTEdge(Object sourceVertex, Object targetVertex, Object edge) { + getModel().beginUpdate(); + + try { + // if the one of the vertices is not drawn, don't draw the edge + if (!(getVertexToCellMap().containsKey(sourceVertex) && getVertexToCellMap().containsKey(targetVertex))) { + return null; + } + + // get mxICells + Object sourceCell = getVertexToCellMap().get(sourceVertex); + Object targetCell = getVertexToCellMap().get(targetVertex); + + // add edge between mxICells + mxICell cell = (mxICell) super.insertEdge(defaultParent, null, edge, sourceCell, targetCell); + + // update cell size so cell isn't "above" graph + updateCellSize(cell); + + // Save reference between vertex and cell. + getEdgeToCellMap().put(edge, cell); + getCellToEdgeMap().put(cell, edge); + return cell; + } finally { + getModel().endUpdate(); + } + } + + /** + * + * @param parent + * @param id Edge id + * @param value Value to display + * @param source + * @param target + * @return + */ + public Object insertDeltaEdge(Object parent, String id, Object value, Object source, Object target) { + // find vertices of edge + Object sourceVertex = getCellToVertexMap().get(source); + Object targetVertex = getCellToVertexMap().get(target); + + if (value == null) { + graphT.addEdge(sourceVertex, targetVertex); + } else { + graphT.addEdge(sourceVertex, targetVertex, value); + } + mxICell cellEdge = addJGraphTEdge(sourceVertex, targetVertex, value); + cellEdge.setId(id); + return cellEdge; + } + + /** + * @param parent + * @param id Vertex id + * @param value Value to display + * @param style + * @return + */ + public Object insertDeltaVertex(Object parent, String id, Object value, String style) { + return insertDeltaVertex(parent, id, value, 0, 0, 0, 0, style); + } + + /** + * @param parent + * @param id Vertex id + * @param value Value to display + * @param x + * @param y + * @param width + * @param height + * @param style + * @return + */ + public Object insertDeltaVertex(Object parent, String id, Object value, double x, double y, double width, double height, String style) { + graphT.addVertex(value); + mxICell cell = addJGraphTVertex(value); + + cell.setId(id); + cell.setParent((mxICell) parent); + ((mxICell) parent).insert(cell); + getCellGeometry(cell).setX(x); + getCellGeometry(cell).setY(y); + getCellGeometry(cell).setWidth(width); + getCellGeometry(cell).setHeight(height); + String[] styles = style.split(";"); + for(String s: styles) { + if(s.contains("fillColor")) { + String[] splitS = s.split("="); + getCellStyle(cell).put(mxConstants.STYLE_FILLCOLOR, splitS[1]); + } + } + return cell; + } + + public Graph getGraph() { + return graphT; + } +} diff --git a/src/org/ntlab/deltaViewer/DeltaViewer.java b/src/org/ntlab/deltaViewer/DeltaViewer.java new file mode 100644 index 0000000..577f851 --- /dev/null +++ b/src/org/ntlab/deltaViewer/DeltaViewer.java @@ -0,0 +1,1008 @@ +package org.ntlab.deltaViewer; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JFrame; + +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.DirectedWeightedPseudograph; +import org.ntlab.deltaExtractor.Alias; +import org.ntlab.deltaExtractor.Delta; +import org.ntlab.deltaExtractor.ExtractedStructure; +import org.ntlab.deltaViewer.Edge.TypeName; +import org.ntlab.deltaExtractor.Alias.AliasType; +import org.ntlab.trace.FieldAccess; +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Reference; +import org.ntlab.trace.Statement; + +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxICell; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxConstants; +import com.mxgraph.util.mxPoint; +import com.mxgraph.view.mxGraphView; + +/** + * Make and display JGraph of extracted delta. + * + * @author Nitta Lab. + */ +public class DeltaViewer { + private static Dimension DEFAULT_SIZE = new Dimension(700, 700); + private static String WINDOW_TITLE = "Delta Viewer"; + + private ExtractedStructure eStructure; + private DeltaAliasCollector deltaAliasCollector; + private List aliasList; + + private Map objectToVertexMap = new HashMap<>(); + private Map methodExecToVertexMap = new LinkedHashMap<>(); + private Map edgeMap = new HashMap<>(); + + private JFrame frame; + private DeltaGraphAdapter mxgraph; + // No clue what this does but it is needed. + private mxICell mxDefaultParent; + + private mxGraphComponent mxgraphComponent; + + private int curNumFrame = 0; + private static Dimension VERTEX_OBJECT_SIZE = new Dimension(70, 70); + private static Dimension VERTEX_METHOD_EXECUTION_SIZE = new Dimension(55, 20); + private mxPoint coordinatorPoint = new mxPoint(DEFAULT_SIZE.getWidth() / 2 - 50, 100); + + private DeltaAnimation deltaAnimation; + + private double scale = 1; + + public DeltaViewer() { + mxgraph = new DeltaGraphAdapter(new DirectedWeightedPseudograph(DefaultEdge.class)); + mxDefaultParent = (mxCell)mxgraph.getDefaultParent(); + mxgraphComponent = new mxGraphComponent(mxgraph); + deltaAnimation = new DeltaAnimation(mxgraph, mxgraphComponent); + } + + public DeltaViewer(ExtractedStructure extractedStructure, DeltaAliasCollector deltaAliasCollector) { + this(); + this.eStructure = extractedStructure; + this.deltaAliasCollector = deltaAliasCollector; + aliasList = new ArrayList<>(deltaAliasCollector.getAliasList()); +// init(); + } + + /** Initialize JFrame, make vertex object and edge object. */ + public void init() { + // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. + if(eStructure != null) { + WINDOW_TITLE = "extract delta of:" + eStructure.getDelta().getSrcSide().get(0).getDstClassName() + "(" + eStructure.getDelta().getSrcSide().get(0).getDstObjectId() + ")" + " -> " + eStructure.getDelta().getDstSide().get(0).getDstClassName() + "(" + eStructure.getDelta().getDstSide().get(0).getDstObjectId() + ")"; + } + + frame = new JFrame(WINDOW_TITLE); + frame.setSize(DEFAULT_SIZE); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + frame.add(mxgraphComponent, BorderLayout.CENTER); + frame.setVisible(true); + + while(coordinatorPoint.getX() - (150 * (eStructure.getDelta().getDstSide().size())) < 0) { + coordinatorPoint.setX(coordinatorPoint.getX() + 150); + } + + makeVertexObject(); + makeEdgeObject(); + + // Fit graph size in visiable JFrame. + mxGraphView view = mxgraphComponent.getGraph().getView(); + int componentWidth = mxgraphComponent.getWidth(); + int viewWidth = (int) view.getGraphBounds().getWidth(); + scale = (double)componentWidth/viewWidth; + view.setScale(scale); + deltaAnimation.setScale(scale); + System.out.println(componentWidth + ", " + viewWidth + ", " + scale); + } + + /** Display graph on JFrame. */ + public void display() { + setCellStyles(); + mxgraphComponent.refresh(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void setExtractedStructure(ExtractedStructure extractedStructure) { + this.eStructure = extractedStructure; + } + + public void setDeltaAliasCollector(DeltaAliasCollector deltaAliasCollector) { + this.deltaAliasCollector = deltaAliasCollector; + } + + public void setFrameSize(int width, int height) { + DEFAULT_SIZE.setSize(width, height); + } + + public void setCoordinatorPoint(double x, double y) { + coordinatorPoint.setX(x); + coordinatorPoint.setY(y); + } + + /** Set cell styles. */ + private void setCellStyles() { + List vertexObject = new ArrayList<>(); + List alignMiddleVertex = new ArrayList<>(); + List alignTopVertex = new ArrayList<>(); + List edgeObject = new ArrayList<>(); + List edgeMethodExec = new ArrayList<>(); + List roundEdge = new ArrayList<>(); + + for (VertexObject vertex: objectToVertexMap.values()) { + vertexObject.add(vertex.getCell()); + if(vertex.getMethodExecutions().size() == 0) { + alignMiddleVertex.add(vertex.getCell()); + } else { + alignTopVertex.add(vertex.getCell()); + } + } + + List vertexMethodExecList = new ArrayList<>(methodExecToVertexMap.values()); + Collections.reverse(vertexMethodExecList); + for (int i = 0; i < vertexMethodExecList.size(); i++) { + switch(i) { + case 0: + ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ff7fbf"); + break; + case 1: + ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ff99cc"); + break; + case 2: + ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffb2d8"); + break; + case 3: + ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffcce5"); + break; + case 4: + ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffe0ef"); + break; + default: + break; + } + } + + for (Edge edge: edgeMap.values()) { + roundEdge.add(edge.getCell()); + switch(edge.getTypeName()) { + case Reference: + edgeObject.add(edge.getCell()); + break; + case Call: + edgeMethodExec.add(edge.getCell()); + break; + default: + break; + } + } + /*Given a cell, we can change it's style attributes, for example the color. NOTE that you have to call the graphComponent.refresh() function, otherwise you won't see the difference! */ + mxgraph.setCellStyles(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_PERIMETER, mxConstants.PERIMETER_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE, true, vertexObject.toArray(new Object[vertexObject.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE, alignMiddleVertex.toArray(new Object[alignMiddleVertex.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP, alignTopVertex.toArray(new Object[alignTopVertex.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_TOPTOBOTTOM, edgeObject.toArray(new Object[edgeObject.size()])); +// mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ENTITY_RELATION, edgeObject.toArray(new Object[edgeObject.size()])); +// mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ORTHOGONAL, edgeObject.toArray(new Object[edgeObject.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_ROUNDED, 1, true, roundEdge.toArray(new Object[roundEdge.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP, roundEdge.toArray(new Object[roundEdge.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_BOTTOM, roundEdge.toArray(new Object[roundEdge.size()])); +// mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.SHAPE_CURVE, edgeObject.toArray(new Object[edgeObject.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#008000", edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); +// mxgraph.setCellStyleFlags(mxConstants.STYLE_AUTOSIZE, 1, true, vertexObject.toArray(new Object[vertexObject.size()])); +// mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ORTHOGONAL, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); +// mxgraph.setCellStyles(mxConstants.STYLE_ELBOW, mxConstants.ELBOW_VERTICAL, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); +} + + private double getXForCell(String id) { + double res = -1; + if (objectToVertexMap.containsKey(id)) { + Object cell = objectToVertexMap.get(id).getCell(); + res = mxgraph.getCellGeometry(cell).getX(); + } + return res; + } + + private double getYForCell(String id) { + double res = -1; + if (objectToVertexMap.containsKey(id)) { + Object cell = objectToVertexMap.get(id).getCell(); + res = mxgraph.getCellGeometry(cell).getY(); + } + return res; + } + + private mxICell getRootParentCell(Object object) { + mxICell cell = (mxICell) object; + if(cell.getParent().getValue() == null) { + return cell; + } + return getRootParentCell(cell.getParent()); + } + + private Point getAbsolutePointforCell(Object object) { + mxICell cell = (mxICell) object; + Point p1 = cell.getGeometry().getPoint(); + if(cell.getParent().getValue() == null) { + return p1; + } + Point p2 = getAbsolutePointforCell(cell.getParent()); + return new Point((int) (p1.getX() + p2.getX()), (int) (p1.getY() + p2.getY())); + } + + /** + * Step to animation of specified alias. + * + * @param alias Alias type and occurance point etc. + */ + public void stepToAnimation(Alias alias) { + try { + stepToAnimation(aliasList.indexOf(alias)); + } catch (IndexOutOfBoundsException e) { + stepToAnimation(-1); + } + } + + /** + * Parent : Step to animation of specified numFrame. + * + * @param numFrame Current animation frame. + */ + public void stepToAnimation(int numFrame) { + try { + Alias alias = aliasList.get(numFrame); + makeAnimation(aliasList.get(curNumFrame + 1), alias); + curNumFrame = aliasList.indexOf(alias); + } catch (IndexOutOfBoundsException e) { + if (numFrame == - 1) { + System.out.println("ERROR : Not exist alias."); + } else { + System.out.println("\r\nLast Animation."); + makeLastAnimation(aliasList.get(aliasList.size() - 1)); + } + } + } + + /** + * Make animation from fromAlias to toAlias. + * + * @param fromAlias + * @param toAlias + */ + private void makeAnimation(Alias fromAlias, Alias toAlias) { + for (int i = aliasList.indexOf(fromAlias); i <= aliasList.indexOf(toAlias); i++) { + Alias alias = aliasList.get(i); + System.out.println("\r\n" + alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo() + " : " + alias.getAliasType().toString()); + switch(alias.getAliasType()) { + case RETURN_VALUE: + moveObjectVertex(alias); + break; + case METHOD_INVOCATION: + removeVertexMethodExecution(alias); + moveObjectVertex(alias); + break; + case FORMAL_PARAMETER: + moveObjectVertex(alias); + break; + case ACTUAL_ARGUMENT: + moveObjectVertex(alias); + break; + case THIS: + if (curNumFrame == 0) { + makeVertexMethodExecution(alias); + } + break; + case RECEIVER: + // Make VertexMethodExecution of called method execution. + MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + if (!methodExecToVertexMap.containsKey(calledMethodExec)) { + makeVertexMethodExecution(alias, calledMethodExec.getSignature(), calledMethodExec); + } + break; + default: + break; + } + } + } + + /** + * Make last animation of extracted delta. + * + * @param alias Last index alias. + */ + private void makeLastAnimation(Alias alias) { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + // Make ObjectEdge and reset position of vertexObject, remove vertexMethodExecution. + for(Statement statement: alias.getMethodExecution().getStatements()) { + if(statement instanceof FieldUpdate) { + FieldUpdate fieldUpdateStatement = (FieldUpdate) statement; + String fieldNames[] = fieldUpdateStatement.getFieldName().split("\\."); + String fieldName = fieldNames[1]; + String sourceObjectId = fieldUpdateStatement.getContainerObjId(); + String targetObjectId = fieldUpdateStatement.getValueObjId(); + mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjectId).getCell(); + mxICell targetCell = (mxICell)objectToVertexMap.get(targetObjectId).getCell(); + Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldUpdateStatement.getFieldName(), fieldName, objectToVertexMap.get(sourceObjectId).getCell(), objectToVertexMap.get(targetObjectId).getCell()); + + edgeMap.put(fieldUpdateStatement.getFieldName(), new Edge(fieldName, TypeName.Reference, edge)); + System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); + System.out.println(targetCell.getParent()); + targetCell.getParent().remove(targetCell); + targetCell.setParent(mxDefaultParent); + targetCell.getGeometry().setX(absolutePointTargetCell.getX()); + targetCell.getGeometry().setY(absolutePointTargetCell.getY()); + + deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(targetObjectId).getInitialX(), objectToVertexMap.get(targetObjectId).getInitialY())); + deltaAnimation.startVertexAnimation(); + System.out.println(targetCell.getParent()); + targetCell.getGeometry().setX(objectToVertexMap.get(targetObjectId).getInitialX()); + targetCell.getGeometry().setY(objectToVertexMap.get(targetObjectId).getInitialY()); + removeCalledVertexMethodExecution(objectToVertexMap.get(sourceObjectId), alias.getMethodExecution().getCallerMethodExecution(), alias.getMethodExecution()); + updateVertexObjectSize(); + display(); + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + + List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); + Collections.reverse(methodExecList); + for(int i = 0; i < methodExecList.size() - 1; i++) { + String objectId = methodExecList.get(i).getThisObjId(); + VertexObject sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex + MethodExecution methodExec = methodExecList.get(i); + for(Statement statement: methodExec.getStatements()) { + if(statement instanceof MethodInvocation) { + MethodExecution calledMethodExec = ((MethodInvocation) statement).getCalledMethodExecution(); + String calledObjectId = calledMethodExec.getThisObjId(); + mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell(); + Point absolutePointCalledCell = getAbsolutePointforCell(calledCell); + System.out.println(objectId + ", " + methodExec.getSignature()); +// objectToVertexMap.get(calledObjectId).resetCellPosition(); + if (methodExecToVertexMap.get(methodExec).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExec).getLocals().contains(objectToVertexMap.get(calledObjectId))) { + calledCell.getParent().remove(calledCell); + calledCell.setParent(mxDefaultParent); + calledCell.getGeometry().setX(absolutePointCalledCell.getX()); + calledCell.getGeometry().setY(absolutePointCalledCell.getY()); + deltaAnimation.setVertexAnimation(calledCell, new mxPoint(objectToVertexMap.get(calledObjectId).getInitialX(), objectToVertexMap.get(calledObjectId).getInitialY())); + deltaAnimation.startVertexAnimation(); + } + removeCalledVertexMethodExecution(sourceVertexObject, methodExec.getCallerMethodExecution(), methodExec); + updateVertexObjectSize(); +// removeVertexMethodExecution(sourceVertexObject, methodExec); + display(); + break; + } + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + + } + + /** Make VertexObject. */ + private void makeVertexObject() { + //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + // ����(0, 0) + double xCor = coordinatorPoint.getX(); + double yCor = coordinatorPoint.getY(); + double time = 150; + + mxgraph.getModel().beginUpdate(); + try { + // Draw vertex object. + // srcSide + Delta delta = eStructure.getDelta(); + int srcSideSize = delta.getSrcSide().size(); + for (int i = srcSideSize - 1; i >= 0; i--) { + Reference ref = delta.getSrcSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + if(!objectToVertexMap.containsKey(ref.getSrcObjectId())) { + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcClassName(), ref.getSrcClassName(), xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. +// mxgraph.updateCellSize(vertex, true); + objectToVertexMap.put(ref.getSrcObjectId(), new VertexObject(ref.getSrcClassName(), vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)))); + } + if(!objectToVertexMap.containsKey(ref.getDstObjectId())) { + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstClassName(), ref.getDstClassName(), xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + objectToVertexMap.put(ref.getDstObjectId(), new VertexObject(ref.getDstClassName(), vertex, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)))); + } + } + } + + // dstSide + int dstSideSize = delta.getDstSide().size(); + for (int i = dstSideSize - 1; i >= 0; i--) { + Reference ref = delta.getDstSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstClassName(), ref.getDstClassName(), xCor - (time * (dstSideSize - i)), yCor + (time * (dstSideSize - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + objectToVertexMap.put(ref.getDstObjectId(), new VertexObject(ref.getDstClassName(), vertex, xCor - (time * (dstSideSize - i)), yCor + (time * (dstSideSize - i)))); + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * SourceVertex move targetVertex. + * + * @param alias + */ + private void moveObjectVertex(Alias alias) { + // sourceVertex + VertexObject sourceVertexObject = objectToVertexMap.get(alias.getObjectId()); + // targetVertex + VertexMethodExecution targetVertexMethodExec = methodExecToVertexMap.get(alias.getMethodExecution()); + + moveObjectVertex(alias, sourceVertexObject, targetVertexMethodExec); + updateVertexObjectSize(); + } + + /** + * Parent : Source VertexObject move target VertexMethodExecution. + * + * @param alias + * @param sourceVertexObject Source VertexObject. + * @param targetVertexMethodExec Target VertexMethodExecution. + */ + private void moveObjectVertex(Alias alias, VertexObject sourceVertexObject, VertexMethodExecution targetVertexMethodExec) { + MethodExecution methodExec = alias.getMethodExecution(); + if (alias.getAliasType().equals(AliasType.RETURN_VALUE) || alias.getAliasType().equals(AliasType.METHOD_INVOCATION)) { + moveLocalObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } else if (alias.getAliasType().equals(AliasType.FORMAL_PARAMETER)) { + moveArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } else if (alias.getAliasType().equals(AliasType.ACTUAL_ARGUMENT)) { + moveActualArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Local position from caller MethodExecution. + * + * @param callerMethodExec Caller MethodExecution. + * @param sourceVertexObject + * @param targetVertexMethodExec + */ + private void moveLocalObjectVertex(MethodExecution callerMethodExec, VertexObject sourceVertexObject, VertexMethodExecution targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); +// mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + MethodExecution callercallerMethodExec = callerMethodExec.getCallerMethodExecution(); + if (methodExecToVertexMap.containsKey(callercallerMethodExec) && methodExecToVertexMap.get(callercallerMethodExec).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callercallerMethodExec).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callercallerMethodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(callercallerMethodExec) && methodExecToVertexMap.get(callercallerMethodExec).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callercallerMethodExec).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callercallerMethodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + int time = targetVertexMethodExec.getLocals().size() + 1; + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + System.out.println(time); + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + + Point absolutePointTargetCell = getAbsolutePointforCell(sourceCell.getParent()); + sourceCell.getGeometry().setX(sourceX - absolutePointTargetCell.getX()); + sourceCell.getGeometry().setY(sourceY - absolutePointTargetCell.getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.startVertexAnimation(); + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + targetVertexMethodExec.getLocals().add(sourceVertexObject); + System.out.println(targetVertexMethodExec.getLabel() + " :Local: " + sourceVertexObject.getLabel()); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. + * + * @param methodExec MethodExecution. + * @param sourceVertexObject + * @param targetVertexMethodExec + */ + private void moveArgumentObjectVertex(MethodExecution methodExec, VertexObject sourceVertexObject, VertexMethodExecution targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); +// mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + int time = targetVertexMethodExec.getArguments().size(); + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + System.out.println(time); + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(sourceX - sourceCell.getParent().getGeometry().getX()); + sourceCell.getGeometry().setY(sourceY - sourceCell.getParent().getGeometry().getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.startVertexAnimation(); + +// sourceCell.setParent(targetCell.getParent()); +// targetCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + targetVertexMethodExec.getArguments().add(sourceVertexObject); + System.out.println(targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. + * + * @param methodExec MethodExecution. + * @param sourceVertexObject + * @param targetVertexMethodExec + */ + private void moveActualArgumentObjectVertex(MethodExecution methodExec, VertexObject sourceVertexObject, VertexMethodExecution targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); +// mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + int time = targetVertexMethodExec.getArguments().size(); + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + System.out.println(time); + if (time == 0) time = 1; + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(sourceX - sourceCell.getParent().getGeometry().getX()); + sourceCell.getGeometry().setY(sourceY - sourceCell.getParent().getGeometry().getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.startVertexAnimation(); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + targetVertexMethodExec.getArguments().add(sourceVertexObject); + System.out.println(targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** Update VertexObject size. */ + private void updateVertexObjectSize() { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology + mxgraph.getModel().beginUpdate(); + try { + for (VertexObject vertexObject: objectToVertexMap.values()) { + mxCell vertexObjectCell = ((mxCell) vertexObject.getCell()); + int time = vertexObjectCell.getChildCount(); + if (time == 0) { + time = 1; + } + + if(vertexObjectCell.getGeometry().getWidth() != VERTEX_OBJECT_SIZE.getWidth() * time) { + Dimension targetDimension = new Dimension(); + targetDimension.setSize(VERTEX_OBJECT_SIZE.getWidth() * time, VERTEX_OBJECT_SIZE.getHeight() * time); + deltaAnimation.setResizeVertexAnimation(vertexObjectCell, targetDimension); + deltaAnimation.startResizeVertexAnimation(); + } + } + }finally { + mxgraph.getModel().endUpdate(); + } + + show(mxDefaultParent); + } + + private void show(mxICell cell) { + for(Object object: mxgraph.getChildCells(cell)) { + System.out.println(object); + } + + } + /** + * Update VertexObject of targetMethodExecCell size have sourceObjectCell. + * + * @param sourceObjectCell + * @param targetMethodExecCell + */ + private void updateVertexObjectSize(mxICell sourceObjectCell, mxICell targetMethodExecCell) { + mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + double preX = parentTargetMethodExecCell.getGeometry().getX(); + double preY = parentTargetMethodExecCell.getGeometry().getY(); + double preCenterX = parentTargetMethodExecCell.getGeometry().getCenterX(); + double preCenterY = parentTargetMethodExecCell.getGeometry().getCenterY(); + parentTargetMethodExecCell.getGeometry().setWidth(parentTargetMethodExecCell.getGeometry().getWidth() * 1.8); + parentTargetMethodExecCell.getGeometry().setHeight(parentTargetMethodExecCell.getGeometry().getHeight() * 1.8); + parentTargetMethodExecCell.getGeometry().setX(preX - (parentTargetMethodExecCell.getGeometry().getCenterX() - preCenterX)); + parentTargetMethodExecCell.getGeometry().setY(preY - (parentTargetMethodExecCell.getGeometry().getCenterY() - preCenterY)); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** Make edge object in JGraphT and draw this in JGraphX. */ + private void makeEdgeObject() { + Map> fieldNameMap = new HashMap<>(); + + // Format field name. + for(Alias alias: aliasList) { + if(alias.getAliasType().equals(AliasType.THIS)) { + for(Statement statement: alias.getMethodExecution().getStatements()) { + if(statement instanceof FieldAccess) { + String fieldNames[] = formatFieldName(((FieldAccess)statement).getFieldName()); + if(fieldNameMap.get(fieldNames[0]) == null) { + fieldNameMap.put(fieldNames[0], new HashSet()); + } + fieldNameMap.get(fieldNames[0]).add(fieldNames[1]); + } + } + } + } + + mxgraph.getModel().beginUpdate(); + try { + // Make object edge in JGraphT and draw this in JGraphX. + Delta delta = eStructure.getDelta(); + int srcSideSize = delta.getSrcSide().size(); + int dstSideSize = delta.getDstSide().size(); + for (int i = srcSideSize - 1; i >= 0; i--) { + Reference ref = delta.getSrcSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + for(String fieldName: fieldNameMap.get(ref.getSrcClassName())) { + // BUG : contains -> equals + if(ref.getDstClassName().contains(fieldName.toUpperCase())) { + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, fieldName, objectToVertexMap.get(ref.getSrcObjectId()).getCell(), objectToVertexMap.get(ref.getDstObjectId()).getCell()); + ((mxCell)edge).setStyle("exitX=1;exitY=1;exitPerimeter=1;entryX=0;entryY=0;entryPerimeter=1;"); + edgeMap.put(ref.getSrcClassName() + "." + fieldName, new Edge(fieldName, TypeName.Reference, edge)); + break; + } + } + } + } + + for (int i = dstSideSize - 1; i >= 0; i--) { + Reference ref = delta.getDstSide().get(i); + if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + for (String fieldName: fieldNameMap.get(ref.getSrcClassName())) { + // BUG : contains -> equals + if (ref.getDstClassName().contains(fieldName.toUpperCase())) { + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, fieldName, objectToVertexMap.get(ref.getSrcObjectId()).getCell(), objectToVertexMap.get(ref.getDstObjectId()).getCell()); + ((mxCell)edge).setStyle("exitX=0;exitY=1;exitPerimeter=1;entryX=1;entryY=0;entryPerimeter=1;"); + edgeMap.put(ref.getSrcClassName() + "." + fieldName, new Edge(fieldName, TypeName.Reference, edge)); + break; + } + } + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Make VertexMethodExecution. + * + * @param alias + */ + private void makeVertexMethodExecution(Alias alias) { + makeVertexMethodExecution(alias, alias.getMethodSignature(), alias.getMethodExecution()); + } + + /** + * Parent : Make VertexMethodExecution. + * + * @param alias + * @param methodSignature Called or this MethodSignature. + * @param methodExec Called or this MethodExecution. + */ + private void makeVertexMethodExecution(Alias alias, String methodSignature, MethodExecution methodExec) { + + if (methodSignature.contains(" ")) { + methodSignature = formatMethodSignature(methodSignature); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + String objectId = alias.getObjectId(); + Object object = objectToVertexMap.get(objectId).getCell(); + double xCor = VERTEX_OBJECT_SIZE.getWidth() * 0.1; + double yCor = VERTEX_OBJECT_SIZE.getHeight() * 0.5; + int time = objectToVertexMap.get(objectId).getMethodExecutions().size(); + + Object vertex = mxgraph.insertDeltaVertex(object, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. + System.out.println((mxICell)vertex); + + VertexMethodExecution vertexMethodExecution = new VertexMethodExecution(methodSignature, vertex, xCor * (time + 1), yCor * (time + 1), VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); +// Object vertex = mxgraph.insertVertex(object, methodSignature, methodSignature, 0, 0, 0, 0, "fillColor=white", true); //creates a white vertex. +// Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. +// VertexMethodExecution vertexMethodExecution = new VertexMethodExecution(methodSignature, vertex, getXForCell(objectId) + (xCor * (time + 1)), getYForCell(objectId) + (yCor * (time + 1)), VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); + methodExecToVertexMap.put(methodExec, vertexMethodExecution); + if(methodExecToVertexMap.size() > 1) { + ((mxICell)vertex).setVisible(false); + } + objectToVertexMap.get(objectId).addMethodExecution(vertexMethodExecution); + } finally { + mxgraph.getModel().endUpdate(); + } + makeEdgeMethodExecution(); + } + + /** + * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param alias + */ + private void removeVertexMethodExecution(Alias alias) { + // sourceVertex + VertexObject sourceVertexObject = objectToVertexMap.get(alias.getObjectId()); + MethodExecution methodExec = alias.getMethodExecution(); + + if(alias.getAliasType().equals(AliasType.METHOD_INVOCATION)) { + MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + removeCalledVertexMethodExecution(sourceVertexObject, methodExec, calledMethodExec); + } else { + removeVertexMethodExecution(sourceVertexObject, methodExec); + } + } + + /** + * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param sourceVertexObject + * @param methodExec + */ + private void removeVertexMethodExecution(VertexObject sourceVertexObject, MethodExecution methodExec) { + // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(methodExec)) { + mxCell targetVertexCell = (mxCell)methodExecToVertexMap.get(methodExec).getCell(); + targetVertexCell.getParent().remove(targetVertexCell); + targetVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {targetVertexCell}); + objectToVertexMap.get(methodExec.getThisObjId()).getMethodExecutions().remove(methodExecToVertexMap.get(methodExec)); + methodExecToVertexMap.remove(methodExec); + edgeMap.remove(methodExec.getSignature()); + updateVertexObjectSize(); + } + } + + /** + * Remove CalledVertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param sourceVertexObject + * @param methodExec + * @param calledMethodExec + */ + private void removeCalledVertexMethodExecution(VertexObject sourceVertexObject, MethodExecution methodExec, MethodExecution calledMethodExec) { + + // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(calledMethodExec)) { + mxICell sourceVertexCell = (mxICell)methodExecToVertexMap.get(methodExec).getCell(); + mxCell targetVertexCell = (mxCell)methodExecToVertexMap.get(calledMethodExec).getCell(); + Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + mxgraph.removeCells(mxgraph.getEdgesBetween(sourceVertexCell, targetVertexCell)); + try { + mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); + Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); + cloneTargetVertexCell.getGeometry().setX(absolutPointTargetVertexCell.getX()); + cloneTargetVertexCell.getGeometry().setY(absolutPointTargetVertexCell.getY()); + cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); + cloneTargetVertexCell.setValue(null); + Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); + ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); + deltaAnimation.setReductionEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointSourceVertexCell.getX(), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight())); + deltaAnimation.startReductionEdgeAnimation(); +// deltaAnimation.setReductionEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); +// deltaAnimation.startReductionEdgeAnimation(); + mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } finally { + mxgraph.getModel().endUpdate(); + } + + targetVertexCell.getParent().remove(targetVertexCell); + targetVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {targetVertexCell}); + objectToVertexMap.get(calledMethodExec.getThisObjId()).getMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); + methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); + methodExecToVertexMap.remove(calledMethodExec); + edgeMap.remove(methodExec.getSignature()); +// updateVertexObjectSize(); + } + } + + + /** Make EdgeMethodExecution. */ + private void makeEdgeMethodExecution() { + List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology + mxgraph.getModel().beginUpdate(); + try { + // BUG : Edge Orientation Reverse. + for (int i = 0; i < methodExecList.size() - 1; i++) { + MethodExecution sourceMethodExec = methodExecList.get(i); + MethodExecution targetMethodExec = methodExecList.get(i + 1); + String methodSignature = sourceMethodExec.getSignature(); + if (!edgeMap.containsKey(methodSignature)) { + mxICell sourceVertexCell = (mxICell)methodExecToVertexMap.get(sourceMethodExec).getCell(); + mxICell targetVertexCell = (mxICell)methodExecToVertexMap.get(targetMethodExec).getCell(); + Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); + Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); + +// System.out.println("start : " + sourceVertexCell.getGeometry().getCenterX() + ", " + (sourceVertexCell.getGeometry().getY() + sourceVertexCell.getGeometry().getHeight()) + ", " + targetVertexCell.getGeometry().getCenterX() + ", " + targetVertexCell.getGeometry().getY()); +// deltaAnimation.setEdgeAnimation(new mxPoint(sourceVertexCell.getGeometry().getCenterX(), sourceVertexCell.getGeometry().getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(targetVertexCell.getGeometry().getCenterX(), targetVertexCell.getGeometry().getY())); + deltaAnimation.setExpandEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); + deltaAnimation.startExpandEdgeAnimation(); + targetVertexCell.setVisible(true); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, methodSignature, null, sourceVertexCell, targetVertexCell); + ((mxCell)edge).setStyle("exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;"); + edgeMap.put(methodSignature, new Edge(methodSignature, TypeName.Call, edge)); + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + private int countChildVertex(VertexObject vertexObject) { + int time = vertexObject.getMethodExecutions().size(); + if(time == 0) { + return 1; + } + for(VertexMethodExecution vertexMethodExecution: vertexObject.getMethodExecutions()) { + for(VertexObject vo: vertexMethodExecution.getLocals()) { + time += countChildVertex(vo); + } + for(VertexObject vo: vertexMethodExecution.getArguments()) { + return countChildVertex(vo); + } + } + System.out.println(vertexObject.getLabel() + ": " + time); + return time; + } + + private String[] formatFieldName(String fieldName) { + String fieldNames[] = fieldName.split("\\."); + String names[] = new String[] {fieldNames[0], fieldNames[fieldNames.length - 1]}; + for(int i = 1; i < fieldNames.length - 1; i++) { + names[0] += "." + fieldNames[i]; + } + return names; + } + + private String formatMethodSignature(String methodSignature) { + // Step1 : split "(" + String[] methodSignatures = methodSignature.split("\\("); + methodSignature = methodSignatures[0]; + // Step2 : split " " + methodSignatures = methodSignature.split(" "); + methodSignature = methodSignatures[1]; + methodSignature += "()"; + return methodSignature; + } +} diff --git a/src/org/ntlab/deltaViewer/Edge.java b/src/org/ntlab/deltaViewer/Edge.java new file mode 100644 index 0000000..547eeb2 --- /dev/null +++ b/src/org/ntlab/deltaViewer/Edge.java @@ -0,0 +1,53 @@ +package org.ntlab.deltaViewer; + +/** + * JGraphX Edge. + * + * @author Nitta Lab. + */ +public class Edge { + String label; + TypeName typeName; + Object cell; + + protected enum TypeName { + Reference, // object reference + Call // method call + } + + /** + * @param label No display label + * @param typeName + * @param cell + */ + public Edge(String label, TypeName typeName, Object cell) { + this.label = label; + this.typeName = typeName; + this.cell = cell; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public TypeName getTypeName() { + return typeName; + } + + public void setTypeName(TypeName typeName) { + this.typeName = typeName; + } + + public Object getCell() { + return cell; + } + + public void setCell(Object cell) { + this.cell = cell; + } + +} diff --git a/src/org/ntlab/deltaViewer/JGraphTSample.java b/src/org/ntlab/deltaViewer/JGraphTSample.java new file mode 100644 index 0000000..f61d6a5 --- /dev/null +++ b/src/org/ntlab/deltaViewer/JGraphTSample.java @@ -0,0 +1,192 @@ +/* + * (C) Copyright 2013-2018, by Barak Naveh and Contributors. + * + * JGraphT : a free Java graph-theory library + * + * See the CONTRIBUTORS.md file distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the + * GNU Lesser General Public License v2.1 or later + * which is available at + * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html. + * + * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later + */ +package org.ntlab.deltaViewer; + +import com.mxgraph.model.mxCell; +import com.mxgraph.swing.*; +import com.mxgraph.util.mxConstants; +import com.mxgraph.util.mxLine; +import com.mxgraph.util.mxPoint; +import com.mxgraph.view.mxGraph; + +import org.jgrapht.ext.*; +import org.jgrapht.graph.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.geom.Ellipse2D; + +/** + * A demo applet that shows how to use JGraphX to visualize JGraphT graphs. Applet based on + * JGraphAdapterDemo. + * + */ +public class JGraphTSample extends JApplet { + private static final Dimension DEFAULT_SIZE = new Dimension(530, 320); + private JGraphXAdapter jgxAdapter; + + /** + * An alternative starting point for this demo, to also allow running this applet as an + * application. + * + * @param args Command line arguments. + */ + /** + * @param args + */ + public static void main(String[] args) + { + //Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. + JFrame frame = new JFrame("Branching graph"); + frame.setSize(500, 500); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + mxGraph mxgraph= new mxGraph(); + mxGraphComponent graphComponent= new mxGraphComponent(mxgraph); + + frame.add(graphComponent, BorderLayout.CENTER); + frame.setVisible(true); + + //No clue what this does but it is needed. + Object mxDefaultParent = mxgraph.getDefaultParent(); + + //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + Object vertex=null; + Object A=null; + Object B=null; + Object C=null; + Object D=null; + Object E=null; + + Object Am=null; + Object Bm=null; + Object Dm=null; + Object Em=null; + + Object b=null; + Object c=null; + Object d=null; + Object e=null; + + Object AmE=null; + Object BmE=null; + Object DmE=null; + mxgraph.getModel().beginUpdate(); + try{ + double xCor=225; + double yCor=100.0; + double width=70; + double height=70; + + A=mxgraph.insertVertex(mxDefaultParent, "A", "A", xCor, yCor, width , height,"fillColor=blue"); //creates a blue vertex + B=mxgraph.insertVertex(mxDefaultParent, "B", "B", xCor-100, yCor+100, width, height,"fillColor=blue"); + C=mxgraph.insertVertex(mxDefaultParent, "C", "C", xCor-200, yCor+200, width , height,"fillColor=blue"); + D=mxgraph.insertVertex(mxDefaultParent, "D", "D", xCor+100, yCor+100, width , height,"fillColor=blue"); + E=mxgraph.insertVertex(mxDefaultParent, "E", "E", xCor+200 , yCor+200, width, height,"fillColor=blue"); + + Am=mxgraph.insertVertex(mxDefaultParent, "Am", "A.m()", getXForCell(mxgraph, "A")+10, yCor+40, width-15 , height-40,"fillColor=blue; alignVertical=middle"); //creates a blue vertex + Bm=mxgraph.insertVertex(mxDefaultParent, "Bm", "B.getC()", getXForCell(mxgraph, "B")+10, yCor+140, width-15, height-50,"fillColor=blue"); + Dm=mxgraph.insertVertex(mxDefaultParent, "Dm", "D.passB()", getXForCell(mxgraph, "D")+10, yCor+140, width-15 , height-50,"fillColor=blue"); + Em=mxgraph.insertVertex(mxDefaultParent, "Em", "E.setC()", getXForCell(mxgraph, "E")+10 , yCor+240, width-15, height-50,"fillColor=blue"); + + b = mxgraph.insertEdge(mxDefaultParent, "b", "b", A, B, "edgeStyle=elbowEdgeStyle;elbow=horizontal;" + + "exitX=0.5;exitY=1;exitPerimeter=1;entryX=-10;entryY=-10;entryPerimeter=1;"); + c = mxgraph.insertEdge(mxDefaultParent, "c", "c", B, C); + d = mxgraph.insertEdge(mxDefaultParent, "d", "d", A, D); + e = mxgraph.insertEdge(mxDefaultParent, "e", "e", D, E); + + AmE = mxgraph.insertEdge(mxDefaultParent, "AmE", "", Am, Bm); + BmE = mxgraph.insertEdge(mxDefaultParent, "BmE", "", Bm, Dm); + DmE = mxgraph.insertEdge(mxDefaultParent, "DmE", "", Dm, Em); + + final Graphics2D g = (Graphics2D)graphComponent.getGraphics(); +// mxGraphics2DCanvas canvas = new mxGraphics2DCanvas(g); +// canvas.paintPolyline(new mxPoint[] {new mxPoint(100,100),new mxPoint(500,500)}, true); + Runnable r = new Runnable() { + public void run() { + g.setColor(Color.GREEN); + Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0); + g.setStroke(dashed); + g.drawLine(0, 0, 500, 500); + } + }; + + if (!SwingUtilities.isEventDispatchThread()) { + SwingUtilities.invokeLater(r); + } else { + r.run(); + } + + + } + finally{ + mxgraph.getModel().endUpdate(); + } + + /*Given a cell, we can change it's style attributes, for example the color. NOTE that you have to call the graphComponent.refresh() function, otherwise you won't see the difference!*/ + mxgraph.setCellStyles(mxConstants.STYLE_FILLCOLOR, "white", new Object[]{A, B, C, D, E, Am, Bm, Dm, Em}); //changes the color to red + mxgraph.setCellStyles(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE, new Object[]{A, B, C, D, E}); + mxgraph.setCellStyles(mxConstants.STYLE_PERIMETER, mxConstants.PERIMETER_ELLIPSE, new Object[]{A, B, C, D, E}); + mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.SHAPE_CURVE, new Object[] {AmE, BmE, DmE, b, c, d, e}); + mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, new Object[] {AmE, BmE, DmE}); + // Adds animation to edge shape and makes "pipe" visible + ((mxCell)b).setAttribute("path", ".flow {" + + "stroke-dasharray: 8;" + + "animation: dash 0.5s linear;" + + "animation-iteration-count: infinite;" + + "}" + + "@keyframes dash {" + + "to {" + + "stroke-dashoffset: -16;" + + "}"); + + graphComponent.refresh(); + + } + + private static double getXForCell(mxGraph graph, String id) { + double res = -1; + graph.clearSelection(); + graph.selectAll(); + Object[] cells = graph.getSelectionCells(); + for (Object object : cells) { + mxCell cell = (mxCell) object; + if (id.equals(cell.getId())) { + res = cell.getGeometry().getX(); + } + } + graph.clearSelection(); + return res; + } + + class GPanel extends JPanel { + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D)g; + int w = this.getWidth(); + int h = this.getHeight(); + for(int i = 0;i < 10;i++){ + Ellipse2D shape = new Ellipse2D.Double(0,0,w,h - i * (w / 10)); + g2.setPaint(new Color(0,0,255,25)); + g2.fill(shape); + } + } + } +} \ No newline at end of file diff --git a/src/org/ntlab/deltaViewer/Vertex.java b/src/org/ntlab/deltaViewer/Vertex.java new file mode 100644 index 0000000..14fd533 --- /dev/null +++ b/src/org/ntlab/deltaViewer/Vertex.java @@ -0,0 +1,109 @@ +package org.ntlab.deltaViewer; + +import com.mxgraph.model.mxICell; + +/** + * JGraphX Vertex. + * + * @author Nitta Lab. + */ +public class Vertex { + String label; + Object cell; + double initialX; + double initialY; + double x; + double y; + double width; + double height; + + public Vertex(String label, Object cell) { + this.label = label; + this.cell = cell; + } + + public Vertex(String label, Object cell, double initialX, double initialY) { + this.label = label; + this.cell = cell; + this.initialX = initialX; + this.initialY = initialY; + } + + public Vertex(String label, Object cell, double x, double y, double width, double height) { + this.label = label; + this.cell = cell; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + ((mxICell)cell).getGeometry().setX(x); + ((mxICell)cell).getGeometry().setY(y); + ((mxICell)cell).getGeometry().setWidth(width); + ((mxICell)cell).getGeometry().setHeight(height); + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public Object getCell() { + return cell; + } + + public void setCell(Object cell) { + this.cell = cell; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + ((mxICell)cell).getGeometry().setX(x); + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + ((mxICell)cell).getGeometry().setY(y); + } + + public double getWidth() { + return width; + } + + public void setWidth(double width) { + this.width = width; + ((mxICell)cell).getGeometry().setWidth(width); + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + ((mxICell)cell).getGeometry().setHeight(height); + } + + public double getInitialX() { + return initialX; + } + + public double getInitialY() { + return initialY; + } + + public void resetCellPosition() { + ((mxICell)cell).getGeometry().setX(initialX); + ((mxICell)cell).getGeometry().setY(initialY); + } +} diff --git a/src/org/ntlab/deltaViewer/VertexMethodExecution.java b/src/org/ntlab/deltaViewer/VertexMethodExecution.java new file mode 100644 index 0000000..eaa5db0 --- /dev/null +++ b/src/org/ntlab/deltaViewer/VertexMethodExecution.java @@ -0,0 +1,40 @@ +package org.ntlab.deltaViewer; + +import java.util.ArrayList; +import java.util.List; + +/** + * Method execution vertex. + * + * @author Nitta Lab. + */ +public class VertexMethodExecution extends Vertex { + protected List locals = new ArrayList<>(); + protected List arguments = new ArrayList<>(); + + + public VertexMethodExecution(String label, Object cell) { + super(label, cell); + } + + public VertexMethodExecution(String label, Object cell, double x, double y, double width, double height) { + super(label, cell, x, y, width, height); + } + + public List getLocals() { + return locals; + } + + public void setLocals(List locals) { + this.locals = locals; + } + + public List getArguments() { + return arguments; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + +} diff --git a/src/org/ntlab/deltaViewer/VertexObject.java b/src/org/ntlab/deltaViewer/VertexObject.java new file mode 100644 index 0000000..3e043eb --- /dev/null +++ b/src/org/ntlab/deltaViewer/VertexObject.java @@ -0,0 +1,39 @@ +package org.ntlab.deltaViewer; + +import java.util.ArrayList; +import java.util.List; + +import com.mxgraph.model.mxICell; + +/** + * Object vertex. + * + * @author Nitta Lab. + */ +public class VertexObject extends Vertex { + protected List methodExecutions = new ArrayList<>(); + + public VertexObject(String label, Object cell) { + super(label, cell); + } + + public VertexObject(String label, Object cell, double initialX, double initialY) { + super(label, cell, initialX, initialY); + } + + public VertexObject(String label, Object cell, double x, double y, double width, double height) { + super(label, cell, x, y, width, height); + } + + public List getMethodExecutions() { + return methodExecutions; + } + + public void setMethodExecutions(List methodExecutions) { + this.methodExecutions = methodExecutions; + } + + public void addMethodExecution(VertexMethodExecution methodExecution) { + this.methodExecutions.add(methodExecution); + } +} diff --git a/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java b/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java new file mode 100644 index 0000000..91ed7a0 --- /dev/null +++ b/src/org/ntlab/featureLocator/ScenarioBasedProbabilisticRanking.java @@ -0,0 +1,107 @@ +package org.ntlab.featureLocator; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.Trace; + +public class ScenarioBasedProbabilisticRanking { + + public static void main(String[] args) { + Trace positiveTraces[] = new Trace[4]; + Trace negativeTraces[] = new Trace[4]; + long starts[] = new long[4]; + long ends[] = new long[4]; + positiveTraces[0] = new Trace("documents\\jEdit1578785TC1-2.trace"); + positiveTraces[1] = new Trace("documents\\jEdit1578785TC2-2.trace"); + positiveTraces[2] = new Trace("documents\\jEdit1578785TC3-2.trace"); + positiveTraces[3] = new Trace("documents\\jEdit1578785TC4-2.trace"); + negativeTraces[0] = new Trace("documents\\jEdit1578785TC1-1.trace"); + negativeTraces[1] = new Trace("documents\\jEdit1578785TC2-1.trace"); + negativeTraces[2] = new Trace("documents\\jEdit1578785TC3-1.trace"); + negativeTraces[3] = new Trace("documents\\jEdit1578785TC4-1.trace"); + starts[0] = 53110313578062L; + ends[0] = 53114687756752L; + starts[1] = 53656181043072L; + ends[1] = 53662323812706L; + starts[2] = 56259479424073L; + ends[2] = 56263910205683L; + starts[3] = 56003167357539L; + ends[3] = 56009513891913L; + HashMap totalExecutionsInPositiveTraces = new HashMap<>(); + HashMap totalExecutionsInNegativeTraces = new HashMap<>(); + HashMap totalExecutionsInsideMark = new HashMap<>(); + HashMap totalExecutionsOutsideMark = new HashMap<>(); + long insideMarkExecutions = 0L; + long outsideMarkExecutions = 0L; + for (int n = 0; n < positiveTraces.length; n++) { + HashMap> positiveExecutions = positiveTraces[n].getAllMethodExecutions(); + for (String method: positiveExecutions.keySet()) { + int positive = positiveExecutions.get(method).size(); + if (totalExecutionsInPositiveTraces.get(method) == null) { + totalExecutionsInPositiveTraces.put(method, positive); + } else { + totalExecutionsInPositiveTraces.put(method, positive + totalExecutionsInPositiveTraces.get(method)); + } + } + HashMap> negativeExecutions = negativeTraces[n].getAllMethodExecutions(); + for (String method: negativeExecutions.keySet()) { + int negatives = negativeExecutions.get(method).size(); + if (totalExecutionsInNegativeTraces.get(method) == null) { + totalExecutionsInNegativeTraces.put(method, negatives); + totalExecutionsOutsideMark.put(method, negatives); + } else { + totalExecutionsInNegativeTraces.put(method, negatives + totalExecutionsInNegativeTraces.get(method)); + totalExecutionsOutsideMark.put(method, negatives + totalExecutionsOutsideMark.get(method)); + } + outsideMarkExecutions += negatives; + } + HashMap> positiveMarkedExecutions = positiveTraces[n].getMarkedMethodExecutions(starts[n], ends[n]); + for (String method: positiveMarkedExecutions.keySet()) { + int marked = positiveMarkedExecutions.get(method).size(); + if (totalExecutionsInsideMark.get(method) == null) { + totalExecutionsInsideMark.put(method, marked); + } else { + totalExecutionsInsideMark.put(method, marked + totalExecutionsInsideMark.get(method)); + } + insideMarkExecutions += marked; + } + HashMap> positiveUnmarkedExecutions = positiveTraces[n].getUnmarkedMethodExecutions(starts[n], ends[n]); + for (String method: positiveUnmarkedExecutions.keySet()) { + int unmarked = positiveUnmarkedExecutions.get(method).size(); + if (totalExecutionsOutsideMark.get(method) == null) { + totalExecutionsOutsideMark.put(method, unmarked); + } else { + totalExecutionsOutsideMark.put(method, unmarked + totalExecutionsOutsideMark.get(method)); + } + outsideMarkExecutions += unmarked; + } + } + + // An approach to feature location in distributed systems (Edwards��, Journal of Systems and Software 2006) + System.out.println("=== An approach to feature location in distributed systems ==="); + HashMap relevanceIndexes = new HashMap<>(); + for (String method: totalExecutionsInPositiveTraces.keySet()) { + if (totalExecutionsInNegativeTraces.get(method) == null) continue; + double positive = (double)totalExecutionsInPositiveTraces.get(method); + double negative = (double)totalExecutionsInNegativeTraces.get(method); + double relevanceIndex = positive / (positive + negative); + relevanceIndexes.put(method, relevanceIndex); + System.out.println(method + ":" + relevanceIndex); + } + + // Scenario-Based Probabilistic Ranking (SPR, Antoniol��, ICSM 2006) + System.out.println("=== Scenario-Based Probabilistic Ranking ==="); + HashMap relevanceIndexesSPR = new HashMap<>(); + for (String method: totalExecutionsInsideMark.keySet()) { + if (totalExecutionsOutsideMark.get(method) == null) continue; + double mark = (double)totalExecutionsInsideMark.get(method) / (double)insideMarkExecutions; + double unmark = (double)totalExecutionsOutsideMark.get(method) / (double)outsideMarkExecutions; + double relevanceIndexSPR = mark / (mark + unmark); + relevanceIndexesSPR.put(method, relevanceIndexSPR); + System.out.println(method + ":" + relevanceIndexSPR); + } + } + +} diff --git a/src/org/ntlab/featureLocator/SoftwareReconnaissance.java b/src/org/ntlab/featureLocator/SoftwareReconnaissance.java new file mode 100644 index 0000000..636559d --- /dev/null +++ b/src/org/ntlab/featureLocator/SoftwareReconnaissance.java @@ -0,0 +1,72 @@ +package org.ntlab.featureLocator; + +import java.util.HashSet; + +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class SoftwareReconnaissance { + + public static void main(String[] args) { + TraceJSON positiveTraces[] = new TraceJSON[4]; + TraceJSON negativeTraces[] = new TraceJSON[4]; + long starts[] = new long[4]; + long ends[] = new long[4]; + positiveTraces[0] = new TraceJSON("traces\\jEdit1578785_1.trace"); +// positiveTraces[1] = new TraceJSON("traces\\jEdit1578785_2.trace"); +// positiveTraces[2] = new TraceJSON("traces\\jEdit1578785_3.trace"); +// positiveTraces[3] = new TraceJSON("traces\\jEdit1578785_4.trace"); + negativeTraces[0] = new TraceJSON("traces\\jEdit1578785_1-.trace"); +// negativeTraces[1] = new TraceJSON("traces\\jEdit1578785_2-.trace"); +// negativeTraces[2] = new TraceJSON("traces\\jEdit1578785_3-.trace"); +// negativeTraces[3] = new TraceJSON("traces\\jEdit1578785_4-.trace"); + starts[0] = 3566549911632580L; + ends[0] = 3566553144549101L; + starts[1] = 3567284882609419L; + ends[1] = 3567287171623594L; + starts[2] = 3567564111762342L; + ends[2] = 3567566517748884L; + starts[3] = 3567871983770827L; + ends[3] = 3567874335777400L; + + HashSet positiveMethods = positiveTraces[0].getAllMethodSignatures(); + HashSet negativeMethods = negativeTraces[0].getAllMethodSignatures(); + System.out.println("=== Software Reconnaissance ==="); + positiveMethods.removeAll(negativeMethods); + for (String method: positiveMethods) { + System.out.println(method); + } + + HashSet positiveBlocks = positiveTraces[0].getAllBlocks(); + HashSet negativeBlocks = negativeTraces[0].getAllBlocks(); + System.out.println("=== Block-wise Software Reconnaissance ==="); + positiveBlocks.removeAll(negativeBlocks); + for (String method: positiveBlocks) { + System.out.println(method); + } + + HashSet positiveFlows = positiveTraces[0].getAllFlows(); + HashSet negativeFlows = negativeTraces[0].getAllFlows(); + System.out.println("=== Flow-wise Software Reconnaissance ==="); + positiveFlows.removeAll(negativeFlows); + for (String method: positiveFlows) { + System.out.println(method); + } + +// System.out.println("=== Marked Software Reconnaissance ==="); +// HashSet markedMethods = positiveTraces[0].getMarkedMethodSignatures(starts[0], ends[0]); +// HashSet unmarkedMethods = negativeTraces[0].getAllMethodSignatures(); +// unmarkedMethods.addAll(negativeTraces[1].getAllMethodSignatures()); +// unmarkedMethods.addAll(negativeTraces[2].getAllMethodSignatures()); +// unmarkedMethods.addAll(negativeTraces[3].getAllMethodSignatures()); +// unmarkedMethods.addAll(positiveTraces[0].getUnmarkedMethodSignatures(starts[0], ends[0])); +// unmarkedMethods.addAll(positiveTraces[1].getUnmarkedMethodSignatures(starts[1], ends[1])); +// unmarkedMethods.addAll(positiveTraces[2].getUnmarkedMethodSignatures(starts[2], ends[2])); +// unmarkedMethods.addAll(positiveTraces[3].getUnmarkedMethodSignatures(starts[3], ends[3])); +// markedMethods.removeAll(unmarkedMethods); +// for (String method: markedMethods) { +// System.out.println(method); +// } + } + +} diff --git a/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java b/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java new file mode 100644 index 0000000..857e263 --- /dev/null +++ b/src/org/ntlab/objectGraphAnalyzer/ObjectCallCounter.java @@ -0,0 +1,237 @@ +package org.ntlab.objectGraphAnalyzer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.AbstractMap.SimpleEntry; + +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class ObjectCallCounter { + + /** + * @param args + */ + public static void main(String[] args) { + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + // �I�u�W�F�N�g�����؂̍쐬 + final HashMap classNames = new HashMap<>(); + final ArrayList> links = new ArrayList<>(); + final HashMap parentOf = new HashMap<>(); + + trace.traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.isConstructor() && methodExecution.getCallerMethodExecution() != null) { + String srcObjId = methodExecution.getCallerMethodExecution().getThisObjId(); + String dstObjId = methodExecution.getThisObjId(); + if (!srcObjId.equals(dstObjId)) { // �e�q�N���X�Ԃ̃��\�b�h�Ăяo�����������ꍇ���l�� + if (Trace.isNull(srcObjId)) { + srcObjId = methodExecution.getCallerMethodExecution().getThisClassName(); + } + classNames.put(srcObjId, methodExecution.getCallerMethodExecution().getThisClassName()); + classNames.put(dstObjId, methodExecution.getThisClassName()); + links.add(new SimpleEntry<>(srcObjId, dstObjId)); + parentOf.put(dstObjId, srcObjId); + } + } + return false; + } + }); + + // �e�I�u�W�F�N�g����������؂̃��[�g�m�[�h�Ɛ[���̌v�Z + final HashMap rootOf = new HashMap<>(); + final HashMap depthOf = new HashMap<>(); + + for (String objId: classNames.keySet()) { + int depth = 0; + String rootObjId = objId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + depth++; + if (depthOf.get(rootObjId) != null) { + depth += depthOf.get(rootObjId); + rootObjId = rootOf.get(rootObjId); + } + } + rootOf.put(objId, rootObjId); + depthOf.put(objId, depth); + } + + // �I�u�W�F�N�g�����؏�ł̊e�Ăяo�������A�Ăяo���񐔂̌v�Z + final HashMap maxCallDistances = new HashMap<>(); + final HashMap totalCallDistances = new HashMap<>(); + final HashMap> callDistances = new HashMap<>(); + final HashMap callCounts = new HashMap<>(); + + trace.traverseStatementsInTrace(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodInvocation c = (MethodInvocation)statement; + String srcObjId = c.getThisObjId(); + String dstObjId = c.getCalledMethodExecution().getThisObjId(); + if (Trace.isNull(srcObjId)) { + srcObjId = c.getThisClassName(); + } + if (Trace.isNull(dstObjId)) { + dstObjId = c.getCalledMethodExecution().getThisClassName(); + } + int distance; + if (rootOf.get(srcObjId) == null) { + rootOf.put(srcObjId, srcObjId); + depthOf.put(srcObjId, 0); + classNames.put(srcObjId, c.getThisClassName()); + } + if (rootOf.get(dstObjId) == null) { + rootOf.put(dstObjId, dstObjId); + depthOf.put(dstObjId, 0); + classNames.put(dstObjId, c.getCalledMethodExecution().getThisClassName()); + } +// if (rootOf.get(srcObjId).equals(rootOf.get(dstObjId))) { + ArrayList srcPath = new ArrayList<>(); + srcPath.add(srcObjId); + String rootObjId = srcObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + srcPath.add(0, rootObjId); + } + + ArrayList dstPath = new ArrayList<>(); + dstPath.add(dstObjId); + rootObjId = dstObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + dstPath.add(0, rootObjId); + } + + int srcDepth = depthOf.get(srcObjId); + int dstDepth = depthOf.get(dstObjId); + int depth = 0; + while (srcPath.get(depth).equals(dstPath.get(depth))) { + depth++; + if (depth >= srcPath.size() || depth >= dstPath.size()) break; + } + distance = srcDepth + dstDepth - 2 * (depth - 1); +// } else { +// if (depthOf.get(dstObjId) != null) { +// distance = depthOf.get(dstObjId) + 2; // �V�X�e���S�̂̃��[�g�܂ł�1�A�V�X�e���S�̂̃��[�g����e�N���X�I�u�W�F�N�g�܂ł�1�Ƃ��� +// } else { +// distance = 2; +// } +// } + if (callDistances.get(dstObjId) == null) { + callDistances.put(dstObjId, new HashMap()); + } + HashMap callDistance = callDistances.get(dstObjId); + if (callDistance.get(srcObjId) == null) { + callDistance.put(srcObjId, distance); + } + if (totalCallDistances.get(dstObjId) != null) { + totalCallDistances.put(dstObjId, totalCallDistances.get(dstObjId) + distance); + } else { + totalCallDistances.put(dstObjId, distance); + } + if (callCounts.get(dstObjId) != null) { + callCounts.put(dstObjId, callCounts.get(dstObjId) + 1); + } else { + callCounts.put(dstObjId, 1); + } + if (maxCallDistances.get(dstObjId) == null || distance > maxCallDistances.get(dstObjId)) { + maxCallDistances.put(dstObjId, distance); + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + return false; + } + }); + + // �I�u�W�F�N�gid�A�N���X���A���Ăяo���񐔁A���Ăяo�������A�ő�Ăяo�������A�Ăяo�����I�u�W�F�N�g���A�Ăяo�����I�u�W�F�N�g�P�ʂ̌Ăяo�������̑��a�̏o�� + for (String objId: callCounts.keySet()) { + int variation = 0; + int sum = 0; + for (String srcObjId: callDistances.get(objId).keySet()) { + sum += callDistances.get(objId).get(srcObjId); + variation++; + } + System.out.println(objId + ":" + classNames.get(objId) + ":" + callCounts.get(objId) + ":" + totalCallDistances.get(objId) + ":" + maxCallDistances.get(objId)+ ":" + variation + ":" + sum); + } + +// final HashMap classNames = new HashMap<>(); +// final HashMap callCounts = new HashMap<>(); +// +// for (ThreadInstance thread: trace.getAllThreads().values()) { +// thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { +// @Override +// public boolean preVisitThread(ThreadInstance thread) { +// return false; +// } +// +// @Override +// public boolean preVisitMethodExecution(MethodExecution methodExecution) { +// String objId = methodExecution.getThisObjId(); +// if (!Trace.isNull(objId)) { +// String key = objId; +// if (classNames.get(key) == null) { +// classNames.put(key, methodExecution.getThisClassName()); +// } +// if (callCounts.get(key) == null) { +// callCounts.put(key, 1); +// } else { +// callCounts.put(key, callCounts.get(key) + 1); +// } +// } else { +// String className = methodExecution.getThisClassName(); +// String key = className; +// if (classNames.get(key) == null) { +// classNames.put(key, className); +// } +// if (callCounts.get(key) == null) { +// callCounts.put(key, 1); +// } else { +// callCounts.put(key, callCounts.get(key) + 1); +// } +// } +// return false; +// } +// +// @Override +// public boolean postVisitThread(ThreadInstance thread) { +// return false; +// } +// +// @Override +// public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { +// return false; +// } +// }); +// } +// +// for (String objId: callCounts.keySet()) { +// System.out.println(objId + ":" + classNames.get(objId) + ":" + callCounts.get(objId)); +// } + } + +} diff --git a/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java b/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java new file mode 100644 index 0000000..cdfaa48 --- /dev/null +++ b/src/org/ntlab/objectGraphAnalyzer/ObjectCreationGraphConstructor.java @@ -0,0 +1,81 @@ +package org.ntlab.objectGraphAnalyzer; + +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; + +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class ObjectCreationGraphConstructor { + + /** + * @param args + */ + public static void main(String[] args) { + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + // �I�u�W�F�N�g�����؂̐��� + final HashMap classNames = new HashMap<>(); + final ArrayList> links = new ArrayList<>(); + final HashMap parentOf = new HashMap<>(); + + trace.traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.isConstructor() && methodExecution.getCallerMethodExecution() != null) { + String srcObjId = methodExecution.getCallerMethodExecution().getThisObjId(); + String dstObjId = methodExecution.getThisObjId(); + if (!srcObjId.equals(dstObjId)) { // �e�q�N���X�Ԃ̃��\�b�h�Ăяo�����������ꍇ���l�� + if (Trace.isNull(srcObjId)) { + srcObjId = methodExecution.getCallerMethodExecution().getThisClassName(); + } + classNames.put(srcObjId, methodExecution.getCallerMethodExecution().getThisClassName()); + classNames.put(dstObjId, methodExecution.getThisClassName()); + links.add(new SimpleEntry<>(srcObjId, dstObjId)); + parentOf.put(dstObjId, srcObjId); + } + } + return false; + } + }); + + String objectLabel; + String objectElements[]; + System.out.println("digraph jEditNormal {"); + for (String objectId: classNames.keySet()) { + objectElements = objectId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " [label=\"" + objectId + ":" + classNames.get(objectId)+ "\"]"); + } + for (SimpleEntry link: links) { + String srcObjId = link.getKey(); + String dstObjId = link.getValue(); + objectElements = srcObjId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " -> " + dstObjId); + } + System.out.println("}"); + } +} diff --git a/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java b/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java new file mode 100644 index 0000000..aeb5721 --- /dev/null +++ b/src/org/ntlab/objectGraphAnalyzer/ObjectGraphReconstructor.java @@ -0,0 +1,138 @@ +package org.ntlab.objectGraphAnalyzer; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class ObjectGraphReconstructor { + + /** + * @param args + */ + public static void main(String[] args) { + final HashMap callCounts = new HashMap<>(); + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + for (ThreadInstance thread: trace.getAllThreads().values()) { + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + String objId = methodExecution.getThisObjId(); + if (!Trace.isNull(objId)) { + String key = objId; + if (callCounts.get(key) == null) { + callCounts.put(key, 1); + } else { + callCounts.put(key, callCounts.get(key) + 1); + } + } else { + String className = methodExecution.getThisClassName(); + String key = className; + if (callCounts.get(key) == null) { + callCounts.put(key, 1); + } else { + callCounts.put(key, callCounts.get(key) + 1); + } + } + return false; + } + + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + + final HashMap classNames = new HashMap<>(); + final HashMap links = new HashMap<>(); + trace.traverseStatementsInTrace(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldUpdate) { + FieldUpdate f = (FieldUpdate)statement; + String linkId = null; + if (!Trace.isNull(f.getContainerObjId())) { + // �ʏ�̃I�u�W�F�N�g�ԎQ�Ƃ̏ꍇ + if (classNames.get(f.getContainerObjId()) == null) { + classNames.put(f.getContainerObjId(), f.getContainerClassName()); + } + linkId = f.getContainerObjId() + ":" + f.getFieldName(); + } else { + // static �t�B�[���h�ɂ��Q�Ƃ̏ꍇ + if (classNames.get(f.getContainerClassName()) == null) { + classNames.put(f.getContainerClassName(), f.getContainerClassName()); + } + linkId = f.getContainerClassName() + ":" + f.getFieldName(); + } + if (!Trace.isNull(f.getValueObjId())) { + // null �ȊO�ւ̎Q�Ƃ̏ꍇ + if (!Trace.isPrimitive(f.getValueClassName())) { + // �Q�ƌ^�̏ꍇ�̂݃����N���� + links.put(linkId, f.getValueObjId()); + if (classNames.get(f.getValueObjId()) == null) { + classNames.put(f.getValueObjId(), f.getValueClassName()); + } + } + } else { + // null �l�̑���̏ꍇ�A�����N���폜 + links.remove(linkId); + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + return false; + } + }); + String objectLabel; + String objectElements[]; + String linkElements[]; + String fieldElements[]; + System.out.println("digraph jEditNormal {"); + for (String objectId: classNames.keySet()) { + if (callCounts.get(objectId) != null && callCounts.get(objectId) >= 200) { + objectElements = objectId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " [label=\"" + objectId + ":" + classNames.get(objectId)+ "\"]"); + } + } + String srcObjId; + String dstObjId; + for (String linkId: links.keySet()) { + linkElements = linkId.split(":"); + srcObjId = linkElements[0]; + dstObjId = links.get(linkId); + if (callCounts.get(srcObjId) != null && callCounts.get(srcObjId) >= 200 + && callCounts.get(dstObjId) != null && callCounts.get(dstObjId) >= 200) { + fieldElements = linkElements[1].split("\\."); + objectElements = srcObjId.split("\\."); + objectLabel = objectElements[objectElements.length - 1].replace("$", "_"); + System.out.println(objectLabel + " -> " + + dstObjId + + " [label=\"" + fieldElements[fieldElements.length - 1] +"\"]"); + } + } + System.out.println("}"); + } +} diff --git a/src/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.java b/src/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.java new file mode 100644 index 0000000..e16252a --- /dev/null +++ b/src/org/ntlab/objectGraphAnalyzer/ObjectLinkCounter.java @@ -0,0 +1,220 @@ +package org.ntlab.objectGraphAnalyzer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.AbstractMap.SimpleEntry; + +import org.ntlab.trace.FieldUpdate; +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.IStatementVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class ObjectLinkCounter { + + /** + * @param args + */ + public static void main(String[] args) { + TraceJSON trace = new TraceJSON("traces\\jEditNormal.trace"); + + // �I�u�W�F�N�g�����؂̍쐬 + final HashMap classNames = new HashMap<>(); + final ArrayList> links = new ArrayList<>(); + final HashMap parentOf = new HashMap<>(); + + trace.traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.isConstructor() && methodExecution.getCallerMethodExecution() != null) { + String srcObjId = methodExecution.getCallerMethodExecution().getThisObjId(); + String dstObjId = methodExecution.getThisObjId(); + if (!srcObjId.equals(dstObjId)) { // �e�q�N���X�Ԃ̃��\�b�h�Ăяo�����������ꍇ���l�� + if (Trace.isNull(srcObjId)) { + srcObjId = methodExecution.getCallerMethodExecution().getThisClassName(); + } + classNames.put(srcObjId, methodExecution.getCallerMethodExecution().getThisClassName()); + classNames.put(dstObjId, methodExecution.getThisClassName()); + links.add(new SimpleEntry<>(srcObjId, dstObjId)); + parentOf.put(dstObjId, srcObjId); + } + } + return false; + } + }); + + // �e�I�u�W�F�N�g����������؂̃��[�g�m�[�h�Ɛ[���̌v�Z + final HashMap rootOf = new HashMap<>(); + final HashMap depthOf = new HashMap<>(); + + for (String objId: classNames.keySet()) { + int depth = 0; + String rootObjId = objId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + depth++; + if (depthOf.get(rootObjId) != null) { + depth += depthOf.get(rootObjId); + rootObjId = rootOf.get(rootObjId); + } + } + rootOf.put(objId, rootObjId); + depthOf.put(objId, depth); + } + + // �I�u�W�F�N�g�����؏�ł̊e�Ăяo�������A�Ăяo���񐔁A�����N�̗L�����v�Z + final HashMap> refs = new HashMap<>(); + final HashMap> callDistances = new HashMap<>(); + final HashMap> linkLessCallCounts = new HashMap<>(); + final HashMap> linkFullCallCounts = new HashMap<>(); + + trace.traverseStatementsInTrace(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldUpdate) { + FieldUpdate f = (FieldUpdate)statement; + String srcObjId = null; + String fieldName = null; + if (!Trace.isNull(f.getContainerObjId())) { + // �ʏ�̃I�u�W�F�N�g�ԎQ�Ƃ̏ꍇ + srcObjId = f.getContainerObjId(); + fieldName = f.getFieldName(); + } else { + // static �t�B�[���h�ɂ��Q�Ƃ̏ꍇ + srcObjId = f.getContainerClassName(); + fieldName = f.getFieldName(); + } + if (!Trace.isNull(f.getValueObjId())) { + // null �ȊO�ւ̎Q�Ƃ̏ꍇ + if (!Trace.isPrimitive(f.getValueClassName())) { + // �Q�ƌ^�̏ꍇ�̂݃����N���� + if (refs.get(srcObjId) == null) { + refs.put(srcObjId, new HashMap()); + } + refs.get(srcObjId).put(fieldName, f.getValueObjId()); + } + } else { + // null �l�̑���̏ꍇ�A�����N���폜 + if (refs.get(srcObjId) != null) { + refs.get(srcObjId).remove(fieldName); + } + } + } else if (statement instanceof MethodInvocation) { + MethodInvocation c = (MethodInvocation)statement; + String srcObjId = c.getThisObjId(); + String dstObjId = c.getCalledMethodExecution().getThisObjId(); + if (Trace.isNull(srcObjId)) { + srcObjId = c.getThisClassName(); + } + if (Trace.isNull(dstObjId)) { + dstObjId = c.getCalledMethodExecution().getThisClassName(); + } + if (callDistances.get(srcObjId) == null) { + callDistances.put(srcObjId, new HashMap()); + } + HashMap callDistance = callDistances.get(srcObjId); + if (callDistance.get(dstObjId) == null) { + // �I�u�W�F�N�g�����؏�ł̋��������߂� + int distance; + if (rootOf.get(srcObjId) == null) { + rootOf.put(srcObjId, srcObjId); + depthOf.put(srcObjId, 0); + classNames.put(srcObjId, c.getThisClassName()); + } + if (rootOf.get(dstObjId) == null) { + rootOf.put(dstObjId, dstObjId); + depthOf.put(dstObjId, 0); + classNames.put(dstObjId, c.getCalledMethodExecution().getThisClassName()); + } + ArrayList srcPath = new ArrayList<>(); + srcPath.add(srcObjId); + String rootObjId = srcObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + srcPath.add(0, rootObjId); + } + + ArrayList dstPath = new ArrayList<>(); + dstPath.add(dstObjId); + rootObjId = dstObjId; + while (parentOf.get(rootObjId) != null) { + rootObjId = parentOf.get(rootObjId); + dstPath.add(0, rootObjId); + } + + int srcDepth = depthOf.get(srcObjId); + int dstDepth = depthOf.get(dstObjId); + int depth = 0; + while (srcPath.get(depth).equals(dstPath.get(depth))) { + depth++; + if (depth >= srcPath.size() || depth >= dstPath.size()) break; + } + distance = srcDepth + dstDepth - 2 * (depth - 1); + callDistance.put(dstObjId, distance); + } + if (refs.get(srcObjId) != null + && refs.get(srcObjId).values().contains(dstObjId)) { + // �Ăяo�����Ƀ����N�����݂��Ă��� + if (linkFullCallCounts.get(srcObjId) == null) { + linkFullCallCounts.put(srcObjId, new HashMap()); + } + HashMap callCount = linkFullCallCounts.get(srcObjId); + if (callCount.get(dstObjId) != null) { + callCount.put(dstObjId, callCount.get(dstObjId) + 1); + } else { + callCount.put(dstObjId, 1); + } + } else { + // �Ăяo�����Ƀ����N�����݂��Ă��Ȃ� + if (linkLessCallCounts.get(srcObjId) == null) { + linkLessCallCounts.put(srcObjId, new HashMap()); + } + HashMap callCount = linkLessCallCounts.get(srcObjId); + if (callCount.get(dstObjId) != null) { + callCount.put(dstObjId, callCount.get(dstObjId) + 1); + } else { + callCount.put(dstObjId, 1); + } + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + return false; + } + }); + + // �I�u�W�F�N�gid�A�N���X���A���Ăяo���񐔁A���Ăяo�������A�ő�Ăяo�������A�Ăяo�����I�u�W�F�N�g���A�Ăяo�����I�u�W�F�N�g�P�ʂ̌Ăяo�������̑��a�̏o�� + for (String srcObjId: callDistances.keySet()) { + for (String dstObjId: callDistances.get(srcObjId).keySet()) { + int callCountWithLink = 0; + int callCountWithoutLink = 0; + if (linkFullCallCounts.get(srcObjId) != null && linkFullCallCounts.get(srcObjId).get(dstObjId) != null) { + callCountWithLink = linkFullCallCounts.get(srcObjId).get(dstObjId); + } + if (linkLessCallCounts.get(srcObjId) != null && linkLessCallCounts.get(srcObjId).get(dstObjId) != null) { + callCountWithoutLink = linkLessCallCounts.get(srcObjId).get(dstObjId); + } + System.out.println(srcObjId + ":" + classNames.get(srcObjId) + ":" + dstObjId + ":" + classNames.get(dstObjId) + ":" + callDistances.get(srcObjId).get(dstObjId) + ":" + callCountWithLink + ":" + callCountWithoutLink); + } + } + } + +} diff --git a/src/org/ntlab/trace/ArrayAccess.java b/src/org/ntlab/trace/ArrayAccess.java new file mode 100644 index 0000000..461283b --- /dev/null +++ b/src/org/ntlab/trace/ArrayAccess.java @@ -0,0 +1,39 @@ +package org.ntlab.trace; + +public class ArrayAccess extends Statement { + private String arrayClassName; + private String arrayObjectId; + private int index; + private String valueClassName; + private String valueObjectId; + + public ArrayAccess(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.arrayClassName = arrayClassName; + this.arrayObjectId = arrayObjectId; + this.index = index; + this.valueClassName = valueClassName; + this.valueObjectId = valueObjectId; + } + + public String getArrayClassName() { + return arrayClassName; + } + + public String getArrayObjectId() { + return arrayObjectId; + } + + public int getIndex() { + return index; + } + + public String getValueClassName() { + return valueClassName; + } + + public String getValueObjectId() { + return valueObjectId; + } +} diff --git a/src/org/ntlab/trace/ArrayCreate.java b/src/org/ntlab/trace/ArrayCreate.java new file mode 100644 index 0000000..e28a81d --- /dev/null +++ b/src/org/ntlab/trace/ArrayCreate.java @@ -0,0 +1,26 @@ +package org.ntlab.trace; + +public class ArrayCreate extends Statement { + private String arrayClassName; + private String arrayObjectId; + private int dimension; + + public ArrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.arrayClassName = arrayClassName; + this.arrayObjectId = arrayObjectId; + this.dimension = dimension; + } + + public String getArrayClassName() { + return arrayClassName; + } + + public String getArrayObjectId() { + return arrayObjectId; + } + + public int getDimension() { + return dimension; + } +} diff --git a/src/org/ntlab/trace/ArrayUpdate.java b/src/org/ntlab/trace/ArrayUpdate.java new file mode 100644 index 0000000..6105fab --- /dev/null +++ b/src/org/ntlab/trace/ArrayUpdate.java @@ -0,0 +1,39 @@ +package org.ntlab.trace; + +public class ArrayUpdate extends Statement { + private String arrayClassName; + private String arrayObjectId; + private int index; + private String valueClassName; + private String valueObjectId; + + public ArrayUpdate(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.arrayClassName = arrayClassName; + this.arrayObjectId = arrayObjectId; + this.index = index; + this.valueClassName = valueClassName; + this.valueObjectId = valueObjectId; + } + + public String getArrayClassName() { + return arrayClassName; + } + + public String getArrayObjectId() { + return arrayObjectId; + } + + public int getIndex() { + return index; + } + + public String getValueClassName() { + return valueClassName; + } + + public String getValueObjectId() { + return valueObjectId; + } +} diff --git a/src/org/ntlab/trace/AugmentationInfo.java b/src/org/ntlab/trace/AugmentationInfo.java new file mode 100644 index 0000000..307568f --- /dev/null +++ b/src/org/ntlab/trace/AugmentationInfo.java @@ -0,0 +1,5 @@ +package org.ntlab.trace; + +abstract public class AugmentationInfo { + +} diff --git a/src/org/ntlab/trace/BlockEnter.java b/src/org/ntlab/trace/BlockEnter.java new file mode 100644 index 0000000..3dc2a3c --- /dev/null +++ b/src/org/ntlab/trace/BlockEnter.java @@ -0,0 +1,20 @@ +package org.ntlab.trace; + +public class BlockEnter extends Statement { + private int blockId; + private int incomings; + + public BlockEnter(int blockId, int incomings, int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.blockId = blockId; + this.incomings = incomings; + } + + public int getBlockId() { + return blockId; + } + + public int getIncomings() { + return incomings; + } +} diff --git a/src/org/ntlab/trace/ClassInfo.java b/src/org/ntlab/trace/ClassInfo.java new file mode 100644 index 0000000..af963f3 --- /dev/null +++ b/src/org/ntlab/trace/ClassInfo.java @@ -0,0 +1,25 @@ +package org.ntlab.trace; + +public class ClassInfo { + private String name; + private String path; + private String loaderPath; + + public ClassInfo(String name, String path, String loaderPath) { + this.name = name; + this.path = path; + this.loaderPath = loaderPath; + } + + public String getName() { + return name; + } + + public String getPath() { + return path; + } + + public String getLoaderPath() { + return loaderPath; + } +} diff --git a/src/org/ntlab/trace/DeltaViewerSample.java b/src/org/ntlab/trace/DeltaViewerSample.java new file mode 100644 index 0000000..46eb159 --- /dev/null +++ b/src/org/ntlab/trace/DeltaViewerSample.java @@ -0,0 +1,625 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +import org.ntlab.deltaExtractor.Alias; +import org.ntlab.deltaExtractor.DeltaExtractorJSON; +import org.ntlab.deltaExtractor.ExtractedStructure; +import org.ntlab.deltaViewer.DeltaAliasCollector; +import org.ntlab.deltaViewer.DeltaViewer; + +/** + * Delta viewer sample for MagnetRON. + * + * @author Nitta Lab. + */ +public class DeltaViewerSample { + + /** + * @param args + */ + public static void main(String[] args) { +// TraceJSON trace = new TraceJSON("traces/_worstCase.txt"); +// TraceJSON trace = new TraceJSON("traces/jEditBenchmark.trace"); +// TraceJSON trace = new TraceJSON("traces/jHotDrawBenchmark.trace"); +// TraceJSON trace = new TraceJSON("traces/ArgoUMLBenchmark.trace"); +// Trace trace = new Trace("traces\\worstCase.txt"); +// Trace trace = new TraceJSON("traces\\_worstCase.txt"); + + // Change! +// TraceJSON trace = new TraceJSON("traces/testTrace2.txt"); +// TraceJSON trace = new TraceJSON("traces/_worstCase.txt"); +// DeltaExtractorJSON dex = new DeltaExtractorJSON(trace); + + // one delta extract +// TraceJSON trace = new TraceJSON("traces/traceSample1.txt"); +// TraceJSON trace = new TraceJSON("traces/traceSample2.txt"); +// TraceJSON trace = new TraceJSON("traces/presenSample.txt"); + TraceJSON trace = new TraceJSON("traces/_worstCase.txt"); + + // Error display MagnetRON. +// TraceJSON trace = new TraceJSON("traces/testTrace3.txt"); +// TraceJSON trace = new TraceJSON("traces/testTrace5.txt"); + DeltaExtractorJSON s = new DeltaExtractorJSON(trace); + HashMap threads = trace.getAllThreads(); + ThreadInstance thread = threads.values().iterator().next(); + TracePoint tp = thread.getRoot().get(thread.getRoot().size() - 1).getExitPoint(); + DeltaAliasCollector dac = new DeltaAliasCollector(); +// ExtractedStructure e = s.extract(new Reference(null, null, "E", "C"), tp, dac); +// ExtractedStructure e = s.extract(new Reference(null, null, "D", "C"), tp, dac); + ExtractedStructure e = s.extract(new Reference(null, null, "worstCase.P", "worstCase.M"), tp, dac); + +// HashSet marked = trace.getMarkedMethodSignatures(1255991806833871L, 1255991808597322L); +// HashSet marked = trace.getMarkedMethodSignatures(1699553004208835L, 1699553004739523L); +// System.out.println("===== Marked Methods ====="); +// for (String method: marked) { +// System.out.println(method); +// } +// HashSet unmarked = trace.getUnmarkedMethodSignatures(1255991806833871L, 1255991808597322L); +// HashSet unmarked = trace.getUnmarkedMethodSignatures(1699553004208835L, 1699553004739523L); +// System.out.println("===== Unmarked Methods ====="); +// for (String method: unmarked) { +// System.out.println(method); +// } + + // Change! +// HashMap threads = trace.getAllThreads(); + for(ThreadInstance ti: threads.values()) { + ArrayList roots = ti.getRoot(); + for(MethodExecution root: roots) { + traverseMethodExecution(root); + } + } + + DeltaViewer dv = new DeltaViewer(e, dac); + List aliasList = new ArrayList<>(dac.getAliasList()); +// dv.setCoordinatorPoint(1200, 100); + dv.init(); + + for(int i = 0; i <= aliasList.size(); i++) { + dv.stepToAnimation(i); + dv.display(); + } + +/* + * ���������� + * +===== Marked Methods ===== +void worstCase.O.passL(worstCase.L) +worstCase.L worstCase.I.getL() +worstCase.L worstCase.K.getL() +worstCase.M worstCase.L.getM() +worstCase.K worstCase.J.getK() +void worstCase.N.passI(worstCase.I) +void worstCase.P.setM(worstCase.M) +===== Unmarked Methods ===== +worstCase.F worstCase.C.getF() +worstCase.E worstCase.D.getE() +worstCase.A() +public worstCase.M() +worstCase.F() +void worstCase.A.m() +public static void worstCase.main.main(java.lang.String[]) +worstCase.G() +worstCase.H() +worstCase.I() +worstCase.B() +worstCase.C() +worstCase.D() +worstCase.E() +worstCase.N() +worstCase.O() +worstCase.P() +worstCase.F worstCase.E.getF() +worstCase.J() +worstCase.K() +worstCase.L() +worstCase.I worstCase.F.getI() +worstCase.H worstCase.G.getH() +worstCase.I worstCase.H.getI() +worstCase.I worstCase.B.getI() + */ +// HashSet all = trace.getAllMethodSignatures(); +// System.out.println("===== All Methods ====="); +// for (String method: all) { +// System.out.println(method); +// } +/* + * ���������� + * +===== All Methods ===== +worstCase.F worstCase.C.getF() +worstCase.E worstCase.D.getE() +worstCase.A() +void worstCase.P.setM(worstCase.M) +public worstCase.M() +worstCase.M worstCase.L.getM() +worstCase.L worstCase.I.getL() +worstCase.L worstCase.K.getL() +void worstCase.N.passI(worstCase.I) +void worstCase.A.m() +worstCase.F() +public static void worstCase.main.main(java.lang.String[]) +worstCase.G() +void worstCase.O.passL(worstCase.L) +worstCase.H() +worstCase.I() +worstCase.B() +worstCase.C() +worstCase.D() +worstCase.E() +worstCase.N() +worstCase.O() +worstCase.K worstCase.J.getK() +worstCase.F worstCase.E.getF() +worstCase.P() +worstCase.J() +worstCase.K() +worstCase.I worstCase.F.getI() +worstCase.I worstCase.H.getI() +worstCase.H worstCase.G.getH() +worstCase.L() +worstCase.I worstCase.B.getI() + */ + +// ArrayList specified = trace.getMethodExecutions("void"); +// System.out.println("===== Specified Methods ====="); +// for (MethodExecution method: specified) { +// System.out.println(method.getSignature()); +// } +/* + * ���������� + * +===== Specified Methods ===== +void worstCase.A.m() +void worstCase.N.passI(worstCase.I) +void worstCase.O.passL(worstCase.L) +void worstCase.P.setM(worstCase.M) * + */ +// HashMap> allExecutions = trace.getAllMethodExecutions(); +// System.out.println("===== All Methods and Executions ====="); +// for (String method: allExecutions.keySet()) { +// System.out.println(method + ":" + allExecutions.get(method).size()); +// } +/* + * ���������� + * +===== All Methods and Executions ===== +worstCase.F worstCase.C.getF():1 +worstCase.E worstCase.D.getE():1 +worstCase.A():1 +void worstCase.P.setM(worstCase.M):1 +public worstCase.M():1 +worstCase.M worstCase.L.getM():1 +worstCase.L worstCase.I.getL():1 +worstCase.L worstCase.K.getL():1 +void worstCase.N.passI(worstCase.I):1 +void worstCase.A.m():1 +worstCase.F():1 +public static void worstCase.main.main(java.lang.String[]):1 +worstCase.G():1 +void worstCase.O.passL(worstCase.L):1 +worstCase.H():1 +worstCase.I():1 +worstCase.B():1 +worstCase.C():1 +worstCase.D():1 +worstCase.E():1 +worstCase.N():1 +worstCase.O():1 +worstCase.K worstCase.J.getK():1 +worstCase.F worstCase.E.getF():1 +worstCase.P():1 +worstCase.J():1 +worstCase.K():1 +worstCase.I worstCase.F.getI():1 +worstCase.I worstCase.H.getI():1 +worstCase.H worstCase.G.getH():1 +worstCase.L():1 +worstCase.I worstCase.B.getI():1 + */ +// System.out.println("===== All Statements Forward ====="); +// trace.traverseStatementsInTrace(new IStatementVisitor() { +// @Override +// public boolean preVisitStatement(Statement statement) { +// if (statement instanceof FieldUpdate) { +// if(trace.isNull((((FieldUpdate) statement).getValueObjId()))) { +// +// } +// } +// System.out.println("pre:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); +// return false; +// } +// @Override +// public boolean postVisitStatement(Statement statement) { +// System.out.println("post:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); +// return false; +// } +// }); +/* + * ���������� + * +===== All Statements Forward ===== +pre:org.ntlab.trace.BlockEnter:1699552992988213 +post:org.ntlab.trace.BlockEnter:1699552992988213 +pre:org.ntlab.trace.MethodInvocation:1699552993730471 +pre:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.MethodInvocation:1699553000173135 +post:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.FieldUpdate:1699553000682666 +post:org.ntlab.trace.FieldUpdate:1699553000682666 +pre:org.ntlab.trace.MethodInvocation:1699553001472175 +pre:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.MethodInvocation:1699553003026510 +post:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.MethodInvocation:1699553001472175 +pre:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.MethodInvocation:1699552993730471 +pre:org.ntlab.trace.MethodInvocation:1699553003253243 +pre:org.ntlab.trace.BlockEnter:1699553003273695 +post:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.FieldAccess:1699553003299083 +post:org.ntlab.trace.FieldAccess:1699553003299083 +pre:org.ntlab.trace.FieldAccess:1699553003355502 +post:org.ntlab.trace.FieldAccess:1699553003355502 +pre:org.ntlab.trace.MethodInvocation:1699553003386885 +pre:org.ntlab.trace.BlockEnter:1699553003400637 +post:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.FieldAccess:1699553003436956 +post:org.ntlab.trace.FieldAccess:1699553003436956 +pre:org.ntlab.trace.MethodInvocation:1699553003482444 +pre:org.ntlab.trace.BlockEnter:1699553003500427 +post:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.FieldAccess:1699553003526169 +post:org.ntlab.trace.FieldAccess:1699553003526169 +pre:org.ntlab.trace.MethodInvocation:1699553003556141 +pre:org.ntlab.trace.BlockEnter:1699553003570951 +post:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.MethodInvocation:1699553003556141 +pre:org.ntlab.trace.MethodInvocation:1699553003668273 +pre:org.ntlab.trace.BlockEnter:1699553003688020 +post:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.MethodInvocation:1699553003482444 +pre:org.ntlab.trace.MethodInvocation:1699553003805088 +pre:org.ntlab.trace.BlockEnter:1699553003818135 +post:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.FieldAccess:1699553003846345 +post:org.ntlab.trace.FieldAccess:1699553003846345 +pre:org.ntlab.trace.MethodInvocation:1699553003896769 +pre:org.ntlab.trace.BlockEnter:1699553003912989 +post:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.MethodInvocation:1699553003896769 +pre:org.ntlab.trace.MethodInvocation:1699553004012075 +pre:org.ntlab.trace.BlockEnter:1699553004029706 +post:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553003386885 +pre:org.ntlab.trace.MethodInvocation:1699553004208835 +pre:org.ntlab.trace.BlockEnter:1699553004228229 +post:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.FieldAccess:1699553004257849 +post:org.ntlab.trace.FieldAccess:1699553004257849 +pre:org.ntlab.trace.MethodInvocation:1699553004302631 +pre:org.ntlab.trace.BlockEnter:1699553004326962 +post:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.FieldAccess:1699553004373507 +post:org.ntlab.trace.FieldAccess:1699553004373507 +pre:org.ntlab.trace.MethodInvocation:1699553004418995 +pre:org.ntlab.trace.BlockEnter:1699553004434510 +post:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.MethodInvocation:1699553004418995 +pre:org.ntlab.trace.MethodInvocation:1699553004515964 +pre:org.ntlab.trace.BlockEnter:1699553004526543 +post:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.MethodInvocation:1699553004302631 +pre:org.ntlab.trace.MethodInvocation:1699553004606587 +pre:org.ntlab.trace.BlockEnter:1699553004615402 +post:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.FieldAccess:1699553004629507 +post:org.ntlab.trace.FieldAccess:1699553004629507 +pre:org.ntlab.trace.MethodInvocation:1699553004648195 +pre:org.ntlab.trace.BlockEnter:1699553004655953 +post:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.MethodInvocation:1699553004648195 +pre:org.ntlab.trace.MethodInvocation:1699553004703556 +pre:org.ntlab.trace.BlockEnter:1699553004712019 +post:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553003253243 + */ + + // Change! +// System.out.println("===== All Statements Backward ====="); +// TracePoint tp = null; +// DeltaAliasCollector dac = new DeltaAliasCollector(); +// long restart = 0L; +// for(;;) { +// tp = trace.traverseStatementsInTraceBackward(new IStatementVisitor() { +// @Override +// public boolean preVisitStatement(Statement statement) { +// System.out.println("pre:" + statement.getThreadNo() + ":" + statement.getTimeStamp()); +// if(statement instanceof FieldUpdate) { +// FieldUpdate fu = (FieldUpdate) statement; +// if(!Trace.isNull(fu.getValueObjId()) && !Trace.isPrimitive(fu.getValueClassName())) { +// return true; +// } +// } +// return false; +// } +// +// @Override +// public boolean postVisitStatement(Statement statement) { +// System.out.println("post:" + statement.getThreadNo() + ":" + statement.getTimeStamp()); +// return false; +// } +// }, restart); +// if(tp == null || !tp.isValid()) break; +// dex.extract(tp, dac); +// Statement statement = tp.getStatement(); +// if(statement instanceof MethodInvocation) { +// restart = ((MethodInvocation)tp.getStatement()).getCalledMethodExecution().getExitTime(); +// } else { +// restart = tp.getStatement().getTimeStamp(); +// } +// } + +// trace.traverseStatementsInTraceBackward(new IStatementVisitor() { +// @Override +// public boolean preVisitStatement(Statement statement) { +// System.out.println("post:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); +// return false; +// } +// @Override +// public boolean postVisitStatement(Statement statement) { +// System.out.println("pre:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); +// return false; +// } +// }); + } + + private static void traverseMethodExecution(MethodExecution m) { + System.out.println(m.getSignature()); + for(Statement ms :m.getStatements()) { + if(ms instanceof FieldAccess) { + System.out.println(((FieldAccess)ms).getFieldName()); + } + } + for(MethodExecution m2: m.getChildren()) { + traverseMethodExecution(m2); + } + } +/* + * ���������� + * +===== All Statements Backward ===== +post:org.ntlab.trace.MethodInvocation:1699553003253243 +post:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.FieldUpdate:1699553004728240 +pre:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.MethodInvocation:1699553004648195 +post:org.ntlab.trace.FieldAccess:1699553004670763 +pre:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.MethodInvocation:1699553004648195 +post:org.ntlab.trace.FieldAccess:1699553004629507 +pre:org.ntlab.trace.FieldAccess:1699553004629507 +post:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004302631 +post:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.FieldAccess:1699553004546994 +pre:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.MethodInvocation:1699553004418995 +post:org.ntlab.trace.FieldAccess:1699553004461661 +pre:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.MethodInvocation:1699553004418995 +post:org.ntlab.trace.FieldAccess:1699553004373507 +pre:org.ntlab.trace.FieldAccess:1699553004373507 +post:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.MethodInvocation:1699553004302631 +post:org.ntlab.trace.FieldAccess:1699553004257849 +pre:org.ntlab.trace.FieldAccess:1699553004257849 +post:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553003386885 +post:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.FieldAccess:1699553004082951 +pre:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.MethodInvocation:1699553003896769 +post:org.ntlab.trace.FieldAccess:1699553003944020 +pre:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.MethodInvocation:1699553003896769 +post:org.ntlab.trace.FieldAccess:1699553003846345 +pre:org.ntlab.trace.FieldAccess:1699553003846345 +post:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553003482444 +post:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.FieldAccess:1699553003715876 +pre:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.MethodInvocation:1699553003556141 +post:org.ntlab.trace.FieldAccess:1699553003599513 +pre:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.MethodInvocation:1699553003556141 +post:org.ntlab.trace.FieldAccess:1699553003526169 +pre:org.ntlab.trace.FieldAccess:1699553003526169 +post:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.MethodInvocation:1699553003482444 +post:org.ntlab.trace.FieldAccess:1699553003436956 +pre:org.ntlab.trace.FieldAccess:1699553003436956 +post:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.MethodInvocation:1699553003386885 +post:org.ntlab.trace.FieldAccess:1699553003355502 +pre:org.ntlab.trace.FieldAccess:1699553003355502 +post:org.ntlab.trace.FieldAccess:1699553003299083 +pre:org.ntlab.trace.FieldAccess:1699553003299083 +post:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.MethodInvocation:1699553003253243 +post:org.ntlab.trace.MethodInvocation:1699552993730471 +post:org.ntlab.trace.FieldUpdate:1699553003190477 +pre:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.MethodInvocation:1699553001472175 +post:org.ntlab.trace.FieldUpdate:1699553003149926 +pre:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.MethodInvocation:1699553002201034 +post:org.ntlab.trace.FieldUpdate:1699553003101618 +pre:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.MethodInvocation:1699553001472175 +post:org.ntlab.trace.FieldUpdate:1699553000682666 +pre:org.ntlab.trace.FieldUpdate:1699553000682666 +post:org.ntlab.trace.MethodInvocation:1699552994339441 +post:org.ntlab.trace.FieldUpdate:1699553000640352 +pre:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.MethodInvocation:1699552994979793 +post:org.ntlab.trace.FieldUpdate:1699553000596627 +pre:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.MethodInvocation:1699552995575363 +post:org.ntlab.trace.FieldUpdate:1699553000551845 +pre:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.MethodInvocation:1699552996163881 +post:org.ntlab.trace.FieldUpdate:1699553000508121 +pre:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.MethodInvocation:1699552996774613 +post:org.ntlab.trace.FieldUpdate:1699553000463691 +pre:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.MethodInvocation:1699552997363836 +post:org.ntlab.trace.FieldUpdate:1699553000422435 +pre:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.MethodInvocation:1699552997949532 +post:org.ntlab.trace.FieldUpdate:1699553000376947 +pre:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.MethodInvocation:1699552998548628 +post:org.ntlab.trace.FieldUpdate:1699553000331107 +pre:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.MethodInvocation:1699552999050402 +post:org.ntlab.trace.FieldUpdate:1699553000290908 +pre:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.MethodInvocation:1699552999466490 +post:org.ntlab.trace.FieldUpdate:1699553000259878 +pre:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.MethodInvocation:1699552999875526 +post:org.ntlab.trace.FieldUpdate:1699553000225322 +pre:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.MethodInvocation:1699552993730471 +post:org.ntlab.trace.BlockEnter:1699552992988213 +pre:org.ntlab.trace.BlockEnter:1699552992988213 + */ +} diff --git a/src/org/ntlab/trace/FieldAccess.java b/src/org/ntlab/trace/FieldAccess.java new file mode 100644 index 0000000..30f1546 --- /dev/null +++ b/src/org/ntlab/trace/FieldAccess.java @@ -0,0 +1,80 @@ +package org.ntlab.trace; + +public class FieldAccess extends Statement { + private String fieldName; + private String containerClassName; + private String containerObjId; + private String valueClassName; + private String valueObjId; + protected String thisClassName; + protected String thisObjId; + + public FieldAccess(String valueClassName, String valueObjId, String containerClassName, + String containerObjId, String thisClassName, String thisObjId, + int lineNo, String threadNo) { + super(lineNo, threadNo); + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + } + + public FieldAccess(String valueClassName, String valueObjId, String containerClassName, + String containerObjId, String thisClassName, String thisObjId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + } + + public FieldAccess(String fieldName, String valueClassName, String valueObjId, String containerClassName, + String containerObjId, String thisClassName, String thisObjId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.fieldName = fieldName; + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + } + + public String getFieldName() { + return fieldName; + } + + public String getContainerClassName() { + return containerClassName; + } + + public String getContainerObjId() { + return containerObjId; + } + + public String getValueClassName() { + return valueClassName; + } + + public String getValueObjId() { + return valueObjId; + } + + public String getThisClassName() { + return thisClassName; + } + + public String getThisObjId() { + return thisObjId; + } + + public Reference getReference() { + return new Reference(containerObjId, valueObjId, containerClassName, valueClassName); + } +} diff --git a/src/org/ntlab/trace/FieldUpdate.java b/src/org/ntlab/trace/FieldUpdate.java new file mode 100644 index 0000000..cfe730b --- /dev/null +++ b/src/org/ntlab/trace/FieldUpdate.java @@ -0,0 +1,61 @@ +package org.ntlab.trace; + +public class FieldUpdate extends Statement { + private String fieldName; + private String containerClassName; + private String containerObjId; + private String valueClassName; + private String valueObjId; + + public FieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, + int lineNo, String threadNo) { + super(lineNo, threadNo); + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + } + + public FieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + } + + public FieldUpdate(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, + int lineNo, String threadNo, long timeStamp) { + super(lineNo, threadNo, timeStamp); + this.fieldName = fieldName; + this.containerClassName = containerClassName; + this.containerObjId = containerObjId; + this.valueClassName = valueClassName; + this.valueObjId = valueObjId; + } + + public String getFieldName() { + return fieldName; + } + + public String getContainerClassName() { + return containerClassName; + } + + public String getContainerObjId() { + return containerObjId; + } + + public String getValueClassName() { + return valueClassName; + } + + public String getValueObjId() { + return valueObjId; + } + + public Reference getReference() { + return new Reference(containerObjId, valueObjId, containerClassName, valueClassName); + } +} diff --git a/src/org/ntlab/trace/IBoundaryChecker.java b/src/org/ntlab/trace/IBoundaryChecker.java new file mode 100644 index 0000000..2bd2b7d --- /dev/null +++ b/src/org/ntlab/trace/IBoundaryChecker.java @@ -0,0 +1,5 @@ +package org.ntlab.trace; + +public interface IBoundaryChecker { + abstract public boolean withinBoundary(String methodSignature); +} diff --git a/src/org/ntlab/trace/IMethodExecutionVisitor.java b/src/org/ntlab/trace/IMethodExecutionVisitor.java new file mode 100644 index 0000000..b20d2eb --- /dev/null +++ b/src/org/ntlab/trace/IMethodExecutionVisitor.java @@ -0,0 +1,10 @@ +package org.ntlab.trace; + +import java.util.ArrayList; + +public interface IMethodExecutionVisitor { + abstract public boolean preVisitThread(ThreadInstance thread); + abstract public boolean postVisitThread(ThreadInstance thread); + abstract public boolean preVisitMethodExecution(MethodExecution methodExecution); + abstract public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children); +} diff --git a/src/org/ntlab/trace/IStatementVisitor.java b/src/org/ntlab/trace/IStatementVisitor.java new file mode 100644 index 0000000..a5837f4 --- /dev/null +++ b/src/org/ntlab/trace/IStatementVisitor.java @@ -0,0 +1,6 @@ +package org.ntlab.trace; + +public interface IStatementVisitor { + abstract public boolean preVisitStatement(Statement statement); + abstract public boolean postVisitStatement(Statement statement); +} diff --git a/src/org/ntlab/trace/MethodExecution.java b/src/org/ntlab/trace/MethodExecution.java new file mode 100644 index 0000000..4658073 --- /dev/null +++ b/src/org/ntlab/trace/MethodExecution.java @@ -0,0 +1,298 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class MethodExecution { + private String signature; + private String callerSideSignature; + private String thisClassName; + private String thisObjId; + private ArrayList arguments; + private ObjectReference returnValue = null; + private boolean isConstructor; + private boolean isStatic; + private boolean isCollectionType; + private ArrayList statements = new ArrayList(); + private ArrayList children = new ArrayList(); + private MethodExecution callerMethodExecution = null; + private int callerStatementExecution = -1; + private boolean isTerminated = false; + private AugmentationInfo augmentation = null; + private long entryTime = 0L; + private long exitTime = 0L; + + public MethodExecution(String signature, String callerSideSignature, + String thisClassName, String thisObjId, boolean isConstructor, + boolean isStatic, long enterTime) { + this.signature = signature; + this.callerSideSignature = callerSideSignature; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + this.isConstructor = isConstructor; + this.isStatic = isStatic; + this.isCollectionType = false; + this.isTerminated = false; + this.entryTime = enterTime; + } + + public void setArguments(ArrayList arguments) { + this.arguments = arguments; + } + + public void setThisObjeId(String thisObjId) { + this.thisObjId = thisObjId; + } + + public void setReturnValue(ObjectReference returnValue) { + this.returnValue = returnValue; + } + + public void setCollectionType(boolean isCollectionType) { + this.isCollectionType = isCollectionType; + } + + public void setTerminated(boolean isTerminated) { + this.isTerminated = isTerminated; + } + + public String getDeclaringClassName() { + return Trace.getDeclaringType(signature, isConstructor); + } + + public String getSignature() { + return signature; + } + + public String getCallerSideSignature() { + return callerSideSignature; + } + + public String getThisClassName() { + return thisClassName; + } + + public String getThisObjId() { + if (isStatic) return Trace.getNull(); + return thisObjId; + } + + public ArrayList getArguments() { + if (arguments == null) arguments = new ArrayList(); + return arguments; + } + + public ObjectReference getReturnValue() { + return returnValue; + } + + public boolean isConstructor() { + return isConstructor; + } + + public boolean isStatic() { + return isStatic; + } + + public boolean isCollectionType() { + return isCollectionType; + } + + public boolean isTerminated() { + return isTerminated; + } + + public long getEntryTime() { + return entryTime; + } + + public long getExitTime() { + if (isTerminated || exitTime == 0L) { + TracePoint exitPoint = getExitPoint(); + if (!exitPoint.isValid()) return entryTime; + Statement lastStatament = exitPoint.getStatement(); + if (lastStatament instanceof MethodInvocation) { + return ((MethodInvocation) lastStatament).getCalledMethodExecution().getExitTime(); + } else { + return lastStatament.getTimeStamp(); + } + } + return exitTime; + } + + public void setExitTime(long exitTime) { + this.exitTime = exitTime; + } + + public void addStatement(Statement statement) { + statements.add(statement); + if (statement instanceof MethodInvocation) { + children.add(((MethodInvocation)statement).getCalledMethodExecution()); + } + } + + public ArrayList getStatements() { + return statements; + } + + public ArrayList getChildren() { + return children; + } + + public void setCaller(MethodExecution callerMethodExecution, int callerStatementExecution) { + this.callerMethodExecution = callerMethodExecution; + this.callerStatementExecution = callerStatementExecution; + } + + public MethodExecution getParent() { + return callerMethodExecution; + } + + public TracePoint getEntryPoint() { + return new TracePoint(this, 0); + } + + public TracePoint getExitPoint() { + return new TracePoint(this, statements.size() - 1); + } + + public TracePoint getExitOutPoint() { + return new TracePoint(this, statements.size()); + } + + public MethodExecution getCallerMethodExecution() { + return callerMethodExecution; + } + + public int getCallerStatementExecution() { + return callerStatementExecution; + } + + public TracePoint getCallerTracePoint() { + if (callerMethodExecution == null) return null; + return new TracePoint(callerMethodExecution, callerStatementExecution); + } + + /** + * ���̃��\�b�h���s����т��̑S�Ăяo������Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @return�@true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) { + if (visitor.preVisitMethodExecution(this)) return true; + ArrayList calledMethodExecutions = getChildren(); + for (int i = calledMethodExecutions.size() - 1; i >= 0; i--) { + MethodExecution child = calledMethodExecutions.get(i); + if (child.traverseMethodExecutionsBackward(visitor)) return true; + } + if (visitor.postVisitMethodExecution(this, null)) return true; + return false; + } + + public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { + if (entryTime <= markEnd) { + if (entryTime >= markStart) { + ArrayList markedChildren = new ArrayList(); + visitor.preVisitMethodExecution(this); + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + if (child.getEntryTime() <= markEnd) { + child.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + markedChildren.add(child); + } else { + break; + } + } + visitor.postVisitMethodExecution(this, markedChildren); + } else { + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + if (child.getEntryTime() <= markEnd) { + child.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + } + } + } + } + } + + public void getMarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) { + if (entryTime <= markEnd) { + if (entryTime >= markStart) { + signatures.add(getSignature()); + } + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + child.getMarkedMethodSignatures(signatures, markStart, markEnd); + } + } + } + + public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) { + if (entryTime < markStart || entryTime > markEnd) { + signatures.add(getSignature()); + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + child.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + } else { + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + child.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + } + } + + public void getUnmarkedMethodExecutions(HashMap> allExecutions, long markStart, long markEnd) { + if (entryTime < markStart || entryTime > markEnd) { + ArrayList executions = allExecutions.get(getSignature()); + if (executions == null) { + executions = new ArrayList<>(); + allExecutions.put(getSignature(), executions); + } + executions.add(this); + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + child.getUnmarkedMethodExecutions(allExecutions, markStart, markEnd); + } + } else { + for (int i = 0; i < children.size(); i++) { + MethodExecution child = children.get(i); + child.getUnmarkedMethodExecutions(allExecutions, markStart, markEnd); + } + } + } + + public AugmentationInfo getAugmentation() { + return augmentation; + } + + public void setAugmentation(AugmentationInfo augmentation) { + this.augmentation = augmentation; + } + + /** + *�@�����œn���ꂽmethodExecution���Ăяo�������\�b�h�Ăяo����T���ĕԂ� + * @param child ����methodExecution����Ăяo���ꂽ���Ƃ̂���ʂ�methodExecution + * @return �����œn���ꂽmethodExecution���Ăяo�������Ƃ��L�^���Ă��郁�\�b�h�Ăяo�� + */ + public MethodInvocation getMethodInvocation(MethodExecution child) { + int callerStatementExecution = child.getCallerStatementExecution(); + if (callerStatementExecution != -1) { + return (MethodInvocation)statements.get(callerStatementExecution); + } + return null; + } + + /** + * order���w�肵�đΉ�����TracePoint��Ԃ� + * @param order TracePoint��order + * @return + */ + public TracePoint getTracePoint(int order) { + if (order < this.getStatements().size()) { + return new TracePoint(this, order); + } + return null; + } +} diff --git a/src/org/ntlab/trace/MethodExecutionJPDA.java b/src/org/ntlab/trace/MethodExecutionJPDA.java new file mode 100644 index 0000000..89a8355 --- /dev/null +++ b/src/org/ntlab/trace/MethodExecutionJPDA.java @@ -0,0 +1,68 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class MethodExecutionJPDA { + private String signature; + private MethodExecutionJPDA callerMethodExecution = null; + private ArrayList children = new ArrayList(); + private long entryTime = 0L; + + public MethodExecutionJPDA(String signature, long enterTime) { + this.signature = signature; + this.entryTime = enterTime; + } + + public String getSignature() { + return signature; + } + + public long getEntryTime() { + return entryTime; + } + + public void addChild(MethodExecutionJPDA child) { + children.add(child); + } + + public ArrayList getChildren() { + return children; + } + + public void setCaller(MethodExecutionJPDA callerMethodExecution) { + this.callerMethodExecution = callerMethodExecution; + } + + public MethodExecutionJPDA getParent() { + return callerMethodExecution; + } + + public MethodExecutionJPDA getCallerMethodExecution() { + return callerMethodExecution; + } + + /** + * ���̃��\�b�h���s����т��̑S�Ăяo������Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @return�@true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseMethodExecutionsBackward(IMethodExecutionVisitorJPDA visitor) { + if (visitor.preVisitMethodExecution(this)) return true; + ArrayList calledMethodExecutions = getChildren(); + for (int i = calledMethodExecutions.size() - 1; i >= 0; i--) { + MethodExecutionJPDA child = calledMethodExecutions.get(i); + if (child.traverseMethodExecutionsBackward(visitor)) return true; + } + if (visitor.postVisitMethodExecution(this, null)) return true; + return false; + } + + public interface IMethodExecutionVisitorJPDA { + abstract public boolean preVisitThread(ThreadInstanceJPDA thread); + abstract public boolean postVisitThread(ThreadInstanceJPDA thread); + abstract public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution); + abstract public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList children); + } +} diff --git a/src/org/ntlab/trace/MethodInvocation.java b/src/org/ntlab/trace/MethodInvocation.java new file mode 100644 index 0000000..4bbe0b9 --- /dev/null +++ b/src/org/ntlab/trace/MethodInvocation.java @@ -0,0 +1,51 @@ +package org.ntlab.trace; + +public class MethodInvocation extends Statement { + private MethodExecution calledMethodExecution = null; + protected String thisClassName; + protected String thisObjId; + protected String callerSideMethodName = null; + + public MethodInvocation(MethodExecution methodExecution, String thisClassName, String thisObjId, + int lineNo, String threadNo) { + super(lineNo, threadNo); + this.calledMethodExecution = methodExecution; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + } + + public MethodInvocation(String callerSideMethodName, String thisClassName, String thisObjId, + int lineNo, String threadNo) { + super(lineNo, threadNo); + this.callerSideMethodName = callerSideMethodName; + this.thisClassName = thisClassName; + this.thisObjId = thisObjId; + } + + public long getTimeStamp() { + if (calledMethodExecution != null) { + return calledMethodExecution.getEntryTime(); + } + return timeStamp; + } + + public void setCalledMethodExecution(MethodExecution calledMethodExecution) { + this.calledMethodExecution = calledMethodExecution; + } + + public MethodExecution getCalledMethodExecution() { + return calledMethodExecution; + } + + public String getThisClassName() { + return thisClassName; + } + + public String getThisObjId() { + return calledMethodExecution.getCallerMethodExecution().getThisObjId(); + } + + public String getCallerSideMethodName() { + return callerSideMethodName; + } +} diff --git a/src/org/ntlab/trace/ObjectReference.java b/src/org/ntlab/trace/ObjectReference.java new file mode 100644 index 0000000..1786844 --- /dev/null +++ b/src/org/ntlab/trace/ObjectReference.java @@ -0,0 +1,70 @@ +package org.ntlab.trace; + +public class ObjectReference { + private String id; + private String actualType = null; // ���ۂ̌^ + private String calleeType = null; // �Ăяo���惁�\�b�h���ł̌^(�ÓI�Ɍ���ł���^) + private String callerType = null; // �Ăяo�������\�b�h���ł̌^(�ÓI�Ɍ���ł���^) + + public ObjectReference(String id) { + this.id = id; + this.actualType = null; + } + + public ObjectReference(String id, String actualType) { + this.id = id; + this.actualType = actualType; + } + + public ObjectReference(String id, String actualType, String calleeType) { + this.id = id; + this.actualType = actualType; + this.calleeType = calleeType; + } + + public ObjectReference(String id, String actualType, String calleeType, String callerType) { + this.id = id; + this.actualType = actualType; + this.calleeType = calleeType; + this.callerType = callerType; + } + + public String getId() { + return id; + } + + public String getActualType() { + return actualType; + } + + public String getCalleeType() { + return calleeType; + } + + public String getCallerType() { + return callerType; + } + + public void setId(String id) { + this.id = id; + } + + public void setActualType(String actualType) { + this.actualType = actualType; + } + + public void setCalleeType(String calleeType) { + this.calleeType = calleeType; + } + + public void setCallerType(String callerType) { + this.callerType = callerType; + } + + public boolean equals(Object other) { + if (this == other) return true; + if (!(other instanceof ObjectReference)) return false; + if (id != null && id.equals(((ObjectReference)other).id)) return true; + return false; + } +} diff --git a/src/org/ntlab/trace/Reference.java b/src/org/ntlab/trace/Reference.java new file mode 100644 index 0000000..1accbac --- /dev/null +++ b/src/org/ntlab/trace/Reference.java @@ -0,0 +1,119 @@ +package org.ntlab.trace; + +public class Reference { + private String id; + private ObjectReference srcObj; // �Q�ƌ��I�u�W�F�N�g + private ObjectReference dstObj; // �Q�Ɛ�I�u�W�F�N�g + private boolean bCreation = false; // �Q�ƌ��I�u�W�F�N�g���Q�Ɛ�I�u�W�F�N�g�𐶐�������? + private boolean bArray = false; // �Q�ƌ��I�u�W�F�N�g���z��ŎQ�Ɛ�I�u�W�F�N�g��v�f�Ƃ��ĕێ����Ă��邩? + private boolean bCollection = false; // �Q�ƌ��I�u�W�F�N�g���R���N�V�����ŎQ�Ɛ�I�u�W�F�N�g��v�f�Ƃ��ĕێ����Ă��邩? + private boolean bFinalLocal = false; // �Q�ƌ��I�u�W�F�N�g�������܂��͓����N���X�̂Ƃ��Q�Ɛ�I�u�W�F�N�g���O���N���X�� final local �ϐ��Ƃ��ĎQ�Ƃ��Ă��邩? + + public Reference(String srcObjectId, String dstObjectId, String srcClassName, + String dstClassName) { + srcObj = new ObjectReference(srcObjectId, srcClassName); + dstObj = new ObjectReference(dstObjectId, dstClassName); + } + + public Reference(ObjectReference srcObj, ObjectReference dstObj) { + this.srcObj = srcObj; + this.dstObj = dstObj; + } + + public ObjectReference getSrcObject() { + return srcObj; + } + + public ObjectReference getDstObject() { + return dstObj; + } + + public void setSrcClassName(String srcClassName) { + this.srcObj.setActualType(srcClassName); + } + + public void setDstClassName(String dstClassName) { + this.dstObj.setActualType(dstClassName); + } + + public void setSrcObjectId(String srcObjectId) { + this.srcObj.setId(srcObjectId); + } + + public void setDstObjectId(String dstObjectId) { + this.dstObj.setId(dstObjectId); + } + + public String getSrcClassName() { + return srcObj.getActualType(); + } + + public String getDstClassName() { + return dstObj.getActualType(); + } + + public String getSrcObjectId() { + return srcObj.getId(); + } + + public String getDstObjectId() { + return dstObj.getId(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setCreation(boolean bCreation) { + this.bCreation = bCreation; + } + + public boolean isCreation(){ + return bCreation; + } + + public void setArray(boolean bArray) { + this.bArray = bArray; + } + + public boolean isArray() { + return bArray; + } + + public void setCollection(boolean bCollection) { + this.bCollection = bCollection; + } + + public boolean isCollection() { + return bCollection; + } + + public void setFinalLocal(boolean bFinalLocal) { + this.bFinalLocal = bFinalLocal; + } + + public boolean isFinalLocal() { + return bFinalLocal; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof Reference) { + if (this.hashCode() != o.hashCode()) return false; + return (this.srcObj.getId().equals(((Reference)o).srcObj.getId()) && this.dstObj.getId().equals(((Reference)o).dstObj.getId())); + } + return false; + } + + public int hashCode() { + return Integer.parseInt(srcObj.getId()) + Integer.parseInt(dstObj.getId()); + } + + public String toString() { + return srcObj.getId() + "(" + srcObj.getActualType() + ")" + "->" + dstObj.getId() + "(" + dstObj.getActualType() + ")"; + } +} diff --git a/src/org/ntlab/trace/Statement.java b/src/org/ntlab/trace/Statement.java new file mode 100644 index 0000000..4831682 --- /dev/null +++ b/src/org/ntlab/trace/Statement.java @@ -0,0 +1,29 @@ +package org.ntlab.trace; + +public class Statement { + protected int lineNo; + protected String threadNo; + protected long timeStamp = 0L; + + public Statement(int lineNo, String threadNo) { + this.lineNo = lineNo; + this.threadNo = threadNo; + } + + public Statement(int lineNo, String threadNo, long timeStamp) { + this(lineNo, threadNo); + this.timeStamp = timeStamp; + } + + public int getLineNo() { + return lineNo; + } + + public String getThreadNo() { + return threadNo; + } + + public long getTimeStamp() { + return timeStamp; + } +} \ No newline at end of file diff --git a/src/org/ntlab/trace/TestTrace.java b/src/org/ntlab/trace/TestTrace.java new file mode 100644 index 0000000..c2f15f8 --- /dev/null +++ b/src/org/ntlab/trace/TestTrace.java @@ -0,0 +1,514 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class TestTrace { + + /** + * @param args + */ + public static void main(String[] args) { +// Trace trace = new Trace("traces\\worstCase.txt"); + Trace trace = new TraceJSON("traces\\_worstCase.txt"); +// HashSet marked = trace.getMarkedMethodSignatures(1255991806833871L, 1255991808597322L); + HashSet marked = trace.getMarkedMethodSignatures(1699553004208835L, 1699553004739523L); + System.out.println("===== Marked Methods ====="); + for (String method: marked) { + System.out.println(method); + } +// HashSet unmarked = trace.getUnmarkedMethodSignatures(1255991806833871L, 1255991808597322L); + HashSet unmarked = trace.getUnmarkedMethodSignatures(1699553004208835L, 1699553004739523L); + System.out.println("===== Unmarked Methods ====="); + for (String method: unmarked) { + System.out.println(method); + } + +/* + * ���������� + * +===== Marked Methods ===== +void worstCase.O.passL(worstCase.L) +worstCase.L worstCase.I.getL() +worstCase.L worstCase.K.getL() +worstCase.M worstCase.L.getM() +worstCase.K worstCase.J.getK() +void worstCase.N.passI(worstCase.I) +void worstCase.P.setM(worstCase.M) +===== Unmarked Methods ===== +worstCase.F worstCase.C.getF() +worstCase.E worstCase.D.getE() +worstCase.A() +public worstCase.M() +worstCase.F() +void worstCase.A.m() +public static void worstCase.main.main(java.lang.String[]) +worstCase.G() +worstCase.H() +worstCase.I() +worstCase.B() +worstCase.C() +worstCase.D() +worstCase.E() +worstCase.N() +worstCase.O() +worstCase.P() +worstCase.F worstCase.E.getF() +worstCase.J() +worstCase.K() +worstCase.L() +worstCase.I worstCase.F.getI() +worstCase.H worstCase.G.getH() +worstCase.I worstCase.H.getI() +worstCase.I worstCase.B.getI() + */ + HashSet all = trace.getAllMethodSignatures(); + System.out.println("===== All Methods ====="); + for (String method: all) { + System.out.println(method); + } +/* + * ���������� + * +===== All Methods ===== +worstCase.F worstCase.C.getF() +worstCase.E worstCase.D.getE() +worstCase.A() +void worstCase.P.setM(worstCase.M) +public worstCase.M() +worstCase.M worstCase.L.getM() +worstCase.L worstCase.I.getL() +worstCase.L worstCase.K.getL() +void worstCase.N.passI(worstCase.I) +void worstCase.A.m() +worstCase.F() +public static void worstCase.main.main(java.lang.String[]) +worstCase.G() +void worstCase.O.passL(worstCase.L) +worstCase.H() +worstCase.I() +worstCase.B() +worstCase.C() +worstCase.D() +worstCase.E() +worstCase.N() +worstCase.O() +worstCase.K worstCase.J.getK() +worstCase.F worstCase.E.getF() +worstCase.P() +worstCase.J() +worstCase.K() +worstCase.I worstCase.F.getI() +worstCase.I worstCase.H.getI() +worstCase.H worstCase.G.getH() +worstCase.L() +worstCase.I worstCase.B.getI() + */ + + ArrayList specified = trace.getMethodExecutions("void"); + System.out.println("===== Specified Methods ====="); + for (MethodExecution method: specified) { + System.out.println(method.getSignature()); + } +/* + * ���������� + * +===== Specified Methods ===== +void worstCase.A.m() +void worstCase.N.passI(worstCase.I) +void worstCase.O.passL(worstCase.L) +void worstCase.P.setM(worstCase.M) * + */ + HashMap> allExecutions = trace.getAllMethodExecutions(); + System.out.println("===== All Methods and Executions ====="); + for (String method: allExecutions.keySet()) { + System.out.println(method + ":" + allExecutions.get(method).size()); + } +/* + * ���������� + * +===== All Methods and Executions ===== +worstCase.F worstCase.C.getF():1 +worstCase.E worstCase.D.getE():1 +worstCase.A():1 +void worstCase.P.setM(worstCase.M):1 +public worstCase.M():1 +worstCase.M worstCase.L.getM():1 +worstCase.L worstCase.I.getL():1 +worstCase.L worstCase.K.getL():1 +void worstCase.N.passI(worstCase.I):1 +void worstCase.A.m():1 +worstCase.F():1 +public static void worstCase.main.main(java.lang.String[]):1 +worstCase.G():1 +void worstCase.O.passL(worstCase.L):1 +worstCase.H():1 +worstCase.I():1 +worstCase.B():1 +worstCase.C():1 +worstCase.D():1 +worstCase.E():1 +worstCase.N():1 +worstCase.O():1 +worstCase.K worstCase.J.getK():1 +worstCase.F worstCase.E.getF():1 +worstCase.P():1 +worstCase.J():1 +worstCase.K():1 +worstCase.I worstCase.F.getI():1 +worstCase.I worstCase.H.getI():1 +worstCase.H worstCase.G.getH():1 +worstCase.L():1 +worstCase.I worstCase.B.getI():1 + */ + System.out.println("===== All Statements Forward ====="); + trace.traverseStatementsInTrace(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + System.out.println("pre:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + System.out.println("post:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); + return false; + } + }); +/* + * ���������� + * +===== All Statements Forward ===== +pre:org.ntlab.trace.BlockEnter:1699552992988213 +post:org.ntlab.trace.BlockEnter:1699552992988213 +pre:org.ntlab.trace.MethodInvocation:1699552993730471 +pre:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.MethodInvocation:1699553000173135 +post:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.FieldUpdate:1699553000682666 +post:org.ntlab.trace.FieldUpdate:1699553000682666 +pre:org.ntlab.trace.MethodInvocation:1699553001472175 +pre:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.MethodInvocation:1699553003026510 +post:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.MethodInvocation:1699553001472175 +pre:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.MethodInvocation:1699552993730471 +pre:org.ntlab.trace.MethodInvocation:1699553003253243 +pre:org.ntlab.trace.BlockEnter:1699553003273695 +post:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.FieldAccess:1699553003299083 +post:org.ntlab.trace.FieldAccess:1699553003299083 +pre:org.ntlab.trace.FieldAccess:1699553003355502 +post:org.ntlab.trace.FieldAccess:1699553003355502 +pre:org.ntlab.trace.MethodInvocation:1699553003386885 +pre:org.ntlab.trace.BlockEnter:1699553003400637 +post:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.FieldAccess:1699553003436956 +post:org.ntlab.trace.FieldAccess:1699553003436956 +pre:org.ntlab.trace.MethodInvocation:1699553003482444 +pre:org.ntlab.trace.BlockEnter:1699553003500427 +post:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.FieldAccess:1699553003526169 +post:org.ntlab.trace.FieldAccess:1699553003526169 +pre:org.ntlab.trace.MethodInvocation:1699553003556141 +pre:org.ntlab.trace.BlockEnter:1699553003570951 +post:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.MethodInvocation:1699553003556141 +pre:org.ntlab.trace.MethodInvocation:1699553003668273 +pre:org.ntlab.trace.BlockEnter:1699553003688020 +post:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.MethodInvocation:1699553003482444 +pre:org.ntlab.trace.MethodInvocation:1699553003805088 +pre:org.ntlab.trace.BlockEnter:1699553003818135 +post:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.FieldAccess:1699553003846345 +post:org.ntlab.trace.FieldAccess:1699553003846345 +pre:org.ntlab.trace.MethodInvocation:1699553003896769 +pre:org.ntlab.trace.BlockEnter:1699553003912989 +post:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.MethodInvocation:1699553003896769 +pre:org.ntlab.trace.MethodInvocation:1699553004012075 +pre:org.ntlab.trace.BlockEnter:1699553004029706 +post:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553003386885 +pre:org.ntlab.trace.MethodInvocation:1699553004208835 +pre:org.ntlab.trace.BlockEnter:1699553004228229 +post:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.FieldAccess:1699553004257849 +post:org.ntlab.trace.FieldAccess:1699553004257849 +pre:org.ntlab.trace.MethodInvocation:1699553004302631 +pre:org.ntlab.trace.BlockEnter:1699553004326962 +post:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.FieldAccess:1699553004373507 +post:org.ntlab.trace.FieldAccess:1699553004373507 +pre:org.ntlab.trace.MethodInvocation:1699553004418995 +pre:org.ntlab.trace.BlockEnter:1699553004434510 +post:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.MethodInvocation:1699553004418995 +pre:org.ntlab.trace.MethodInvocation:1699553004515964 +pre:org.ntlab.trace.BlockEnter:1699553004526543 +post:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.MethodInvocation:1699553004302631 +pre:org.ntlab.trace.MethodInvocation:1699553004606587 +pre:org.ntlab.trace.BlockEnter:1699553004615402 +post:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.FieldAccess:1699553004629507 +post:org.ntlab.trace.FieldAccess:1699553004629507 +pre:org.ntlab.trace.MethodInvocation:1699553004648195 +pre:org.ntlab.trace.BlockEnter:1699553004655953 +post:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.MethodInvocation:1699553004648195 +pre:org.ntlab.trace.MethodInvocation:1699553004703556 +pre:org.ntlab.trace.BlockEnter:1699553004712019 +post:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553003253243 + */ + System.out.println("===== All Statements Backward ====="); + trace.traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + System.out.println("post:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { + System.out.println("pre:" + statement.getClass().getName() + ":" + statement.getTimeStamp()); + return false; + } + }); + } +/* + * ���������� + * +===== All Statements Backward ===== +post:org.ntlab.trace.MethodInvocation:1699553003253243 +post:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.FieldUpdate:1699553004728240 +pre:org.ntlab.trace.FieldUpdate:1699553004728240 +post:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.BlockEnter:1699553004712019 +pre:org.ntlab.trace.MethodInvocation:1699553004703556 +post:org.ntlab.trace.MethodInvocation:1699553004648195 +post:org.ntlab.trace.FieldAccess:1699553004670763 +pre:org.ntlab.trace.FieldAccess:1699553004670763 +post:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.BlockEnter:1699553004655953 +pre:org.ntlab.trace.MethodInvocation:1699553004648195 +post:org.ntlab.trace.FieldAccess:1699553004629507 +pre:org.ntlab.trace.FieldAccess:1699553004629507 +post:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.BlockEnter:1699553004615402 +pre:org.ntlab.trace.MethodInvocation:1699553004606587 +post:org.ntlab.trace.MethodInvocation:1699553004302631 +post:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.FieldAccess:1699553004546994 +pre:org.ntlab.trace.FieldAccess:1699553004546994 +post:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.BlockEnter:1699553004526543 +pre:org.ntlab.trace.MethodInvocation:1699553004515964 +post:org.ntlab.trace.MethodInvocation:1699553004418995 +post:org.ntlab.trace.FieldAccess:1699553004461661 +pre:org.ntlab.trace.FieldAccess:1699553004461661 +post:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.BlockEnter:1699553004434510 +pre:org.ntlab.trace.MethodInvocation:1699553004418995 +post:org.ntlab.trace.FieldAccess:1699553004373507 +pre:org.ntlab.trace.FieldAccess:1699553004373507 +post:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.BlockEnter:1699553004326962 +pre:org.ntlab.trace.MethodInvocation:1699553004302631 +post:org.ntlab.trace.FieldAccess:1699553004257849 +pre:org.ntlab.trace.FieldAccess:1699553004257849 +post:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.BlockEnter:1699553004228229 +pre:org.ntlab.trace.MethodInvocation:1699553004208835 +post:org.ntlab.trace.MethodInvocation:1699553003386885 +post:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.FieldAccess:1699553004082951 +pre:org.ntlab.trace.FieldAccess:1699553004082951 +post:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.BlockEnter:1699553004029706 +pre:org.ntlab.trace.MethodInvocation:1699553004012075 +post:org.ntlab.trace.MethodInvocation:1699553003896769 +post:org.ntlab.trace.FieldAccess:1699553003944020 +pre:org.ntlab.trace.FieldAccess:1699553003944020 +post:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.BlockEnter:1699553003912989 +pre:org.ntlab.trace.MethodInvocation:1699553003896769 +post:org.ntlab.trace.FieldAccess:1699553003846345 +pre:org.ntlab.trace.FieldAccess:1699553003846345 +post:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.BlockEnter:1699553003818135 +pre:org.ntlab.trace.MethodInvocation:1699553003805088 +post:org.ntlab.trace.MethodInvocation:1699553003482444 +post:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.FieldAccess:1699553003715876 +pre:org.ntlab.trace.FieldAccess:1699553003715876 +post:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.BlockEnter:1699553003688020 +pre:org.ntlab.trace.MethodInvocation:1699553003668273 +post:org.ntlab.trace.MethodInvocation:1699553003556141 +post:org.ntlab.trace.FieldAccess:1699553003599513 +pre:org.ntlab.trace.FieldAccess:1699553003599513 +post:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.BlockEnter:1699553003570951 +pre:org.ntlab.trace.MethodInvocation:1699553003556141 +post:org.ntlab.trace.FieldAccess:1699553003526169 +pre:org.ntlab.trace.FieldAccess:1699553003526169 +post:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.BlockEnter:1699553003500427 +pre:org.ntlab.trace.MethodInvocation:1699553003482444 +post:org.ntlab.trace.FieldAccess:1699553003436956 +pre:org.ntlab.trace.FieldAccess:1699553003436956 +post:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.BlockEnter:1699553003400637 +pre:org.ntlab.trace.MethodInvocation:1699553003386885 +post:org.ntlab.trace.FieldAccess:1699553003355502 +pre:org.ntlab.trace.FieldAccess:1699553003355502 +post:org.ntlab.trace.FieldAccess:1699553003299083 +pre:org.ntlab.trace.FieldAccess:1699553003299083 +post:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.BlockEnter:1699553003273695 +pre:org.ntlab.trace.MethodInvocation:1699553003253243 +post:org.ntlab.trace.MethodInvocation:1699552993730471 +post:org.ntlab.trace.FieldUpdate:1699553003190477 +pre:org.ntlab.trace.FieldUpdate:1699553003190477 +post:org.ntlab.trace.MethodInvocation:1699553001472175 +post:org.ntlab.trace.FieldUpdate:1699553003149926 +pre:org.ntlab.trace.FieldUpdate:1699553003149926 +post:org.ntlab.trace.MethodInvocation:1699553002201034 +post:org.ntlab.trace.FieldUpdate:1699553003101618 +pre:org.ntlab.trace.FieldUpdate:1699553003101618 +post:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.MethodInvocation:1699553003026510 +pre:org.ntlab.trace.MethodInvocation:1699553002201034 +pre:org.ntlab.trace.MethodInvocation:1699553001472175 +post:org.ntlab.trace.FieldUpdate:1699553000682666 +pre:org.ntlab.trace.FieldUpdate:1699553000682666 +post:org.ntlab.trace.MethodInvocation:1699552994339441 +post:org.ntlab.trace.FieldUpdate:1699553000640352 +pre:org.ntlab.trace.FieldUpdate:1699553000640352 +post:org.ntlab.trace.MethodInvocation:1699552994979793 +post:org.ntlab.trace.FieldUpdate:1699553000596627 +pre:org.ntlab.trace.FieldUpdate:1699553000596627 +post:org.ntlab.trace.MethodInvocation:1699552995575363 +post:org.ntlab.trace.FieldUpdate:1699553000551845 +pre:org.ntlab.trace.FieldUpdate:1699553000551845 +post:org.ntlab.trace.MethodInvocation:1699552996163881 +post:org.ntlab.trace.FieldUpdate:1699553000508121 +pre:org.ntlab.trace.FieldUpdate:1699553000508121 +post:org.ntlab.trace.MethodInvocation:1699552996774613 +post:org.ntlab.trace.FieldUpdate:1699553000463691 +pre:org.ntlab.trace.FieldUpdate:1699553000463691 +post:org.ntlab.trace.MethodInvocation:1699552997363836 +post:org.ntlab.trace.FieldUpdate:1699553000422435 +pre:org.ntlab.trace.FieldUpdate:1699553000422435 +post:org.ntlab.trace.MethodInvocation:1699552997949532 +post:org.ntlab.trace.FieldUpdate:1699553000376947 +pre:org.ntlab.trace.FieldUpdate:1699553000376947 +post:org.ntlab.trace.MethodInvocation:1699552998548628 +post:org.ntlab.trace.FieldUpdate:1699553000331107 +pre:org.ntlab.trace.FieldUpdate:1699553000331107 +post:org.ntlab.trace.MethodInvocation:1699552999050402 +post:org.ntlab.trace.FieldUpdate:1699553000290908 +pre:org.ntlab.trace.FieldUpdate:1699553000290908 +post:org.ntlab.trace.MethodInvocation:1699552999466490 +post:org.ntlab.trace.FieldUpdate:1699553000259878 +pre:org.ntlab.trace.FieldUpdate:1699553000259878 +post:org.ntlab.trace.MethodInvocation:1699552999875526 +post:org.ntlab.trace.FieldUpdate:1699553000225322 +pre:org.ntlab.trace.FieldUpdate:1699553000225322 +post:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.MethodInvocation:1699553000173135 +pre:org.ntlab.trace.MethodInvocation:1699552999875526 +pre:org.ntlab.trace.MethodInvocation:1699552999466490 +pre:org.ntlab.trace.MethodInvocation:1699552999050402 +pre:org.ntlab.trace.MethodInvocation:1699552998548628 +pre:org.ntlab.trace.MethodInvocation:1699552997949532 +pre:org.ntlab.trace.MethodInvocation:1699552997363836 +pre:org.ntlab.trace.MethodInvocation:1699552996774613 +pre:org.ntlab.trace.MethodInvocation:1699552996163881 +pre:org.ntlab.trace.MethodInvocation:1699552995575363 +pre:org.ntlab.trace.MethodInvocation:1699552994979793 +pre:org.ntlab.trace.MethodInvocation:1699552994339441 +pre:org.ntlab.trace.MethodInvocation:1699552993730471 +post:org.ntlab.trace.BlockEnter:1699552992988213 +pre:org.ntlab.trace.BlockEnter:1699552992988213 + */ +} diff --git a/src/org/ntlab/trace/TestTraceJPDA.java b/src/org/ntlab/trace/TestTraceJPDA.java new file mode 100644 index 0000000..ed866ed --- /dev/null +++ b/src/org/ntlab/trace/TestTraceJPDA.java @@ -0,0 +1,134 @@ +package org.ntlab.trace; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class TestTraceJPDA { + + /** + * @param args + */ + public static void main(String[] args) { + try { + final HashMap methodTraceCounts = new HashMap<>(); // ���̃��\�b�h�̎��s���܂ރg���[�X�̐� + final HashMap methodExecCountSums = new HashMap<>(); // ���̃��\�b�h�̑S���s�g���[�X�ɂ����鑍���s�� + final HashMap methodExecDepthSums = new HashMap<>(); // ���̃��\�b�h�̑S���s�g���[�X�ɂ�����S���s�̌Ăяo���[���̑��a + File dir; + dir = new File("traces"); + for (File file: dir.listFiles()) { + if (file.getName().endsWith(".log")) { + TraceJPDA traceJPDA = new TraceJPDA(new BufferedReader(new FileReader(file))); + final HashMap methodExecCounts = new HashMap<>(); + final HashMap methodExecDepthSum = new HashMap<>(); + MethodExecutionJPDA.IMethodExecutionVisitorJPDA visitor = new MethodExecutionJPDA.IMethodExecutionVisitorJPDA() { + private int depth = 0; + + @Override + public boolean preVisitThread(ThreadInstanceJPDA thread) { + depth = 0; + return false; + } + @Override + public boolean postVisitThread(ThreadInstanceJPDA thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution) { + String signature = methodExecution.getSignature(); + if (methodExecCounts.get(signature) == null) { + methodExecCounts.put(signature, 1); + } else { + methodExecCounts.put(signature, methodExecCounts.get(signature) + 1); + } + if (methodExecDepthSum.get(signature) == null) { + methodExecDepthSum.put(signature, depth); + } else { + methodExecDepthSum.put(signature, methodExecDepthSum.get(signature) + depth); + } + depth++; + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList children) { + depth--; + return false; + } + }; + traceJPDA.traverseMethodExecutionsBackward(visitor); + + for (String signature: methodExecCounts.keySet()) { + if (methodExecCounts.get(signature) != null) { + if (methodTraceCounts.get(signature) == null) { + methodTraceCounts.put(signature, 1); + } else { + methodTraceCounts.put(signature, methodTraceCounts.get(signature) + 1); + } + if (methodExecCountSums.get(signature) == null) { + methodExecCountSums.put(signature, methodExecCounts.get(signature)); + } else { + methodExecCountSums.put(signature, methodExecCountSums.get(signature) + methodExecCounts.get(signature)); + } + } + if (methodExecDepthSum.get(signature) != null) { + if (methodExecDepthSums.get(signature) == null) { + methodExecDepthSums.put(signature, methodExecDepthSum.get(signature)); + } else { + methodExecDepthSums.put(signature, methodExecDepthSums.get(signature) + methodExecDepthSum.get(signature)); + } + } + } + } + } + for (String signature: methodTraceCounts.keySet()) { + int traceCount = methodTraceCounts.get(signature); + int execCount = methodExecCountSums.get(signature); + System.out.println(signature + ":" + traceCount + ":" + + ((double)execCount / (double)traceCount) + ":" + + ((double)methodExecDepthSums.get(signature) / (double)execCount)); + } + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + +// TraceJPDA trace150938 = new TraceJPDA("traces\\trace1500938.log"); +// System.out.println("===== JPDA Trace Methods ====="); +// for (String method: trace150938.getAllMethodSignatures()) { +// System.out.println(method); +// } +/* + * ���������� + * +===== JPDA Trace Methods ===== +org.gjt.sp.jedit.bsh.Parser.jj_3R_51() +org.gjt.sp.jedit.textarea.TextArea.getHorizontalOffset() +org.gjt.sp.jedit.bsh.Types.getTypes() +org.gjt.sp.jedit.EBMessage.toString() +org.gjt.sp.jedit.bsh.Parser.jj_3R_84() +org.gjt.sp.jedit.bsh.Reflect.invokeObjectMethod() +org.gjt.sp.jedit.TextUtilities.findMatchingBracket() +org.gjt.sp.jedit.textarea.TextArea.getLastPhysicalLine() +org.gjt.sp.jedit.textarea.TextAreaPainter.isWrapGuidePainted() +org.gjt.sp.jedit.bsh.Parser.MultiplicativeExpression() +org.gjt.sp.jedit.textarea.SelectionManager.getSelectionStartAndEnd() +org.gjt.sp.jedit.Buffer.toString() +org.gjt.sp.jedit.bsh.Parser.jj_3R_86() +org.gjt.sp.jedit.textarea.TextArea.getPainter() +org.gjt.sp.jedit.bsh.BshClassManager$SignatureKey.equals() +org.gjt.sp.jedit.bsh.Parser.jj_3R_44() +org.gjt.sp.jedit.bsh.Parser.jj_3R_142() +org.gjt.sp.jedit.textarea.SelectionManager.addToSelection() +org.gjt.sp.jedit.gui.StatusBar$2.actionPerformed() +org.gjt.sp.jedit.bsh.JavaCharStream.getEndLine() +org.gjt.sp.jedit.bsh.Parser.jj_ntk() +org.gjt.sp.util.WorkThreadPool.fireProgressChanged() +org.gjt.sp.jedit.textarea.TextArea.getVisibleLines() + : + */ + } +} diff --git a/src/org/ntlab/trace/ThreadInstance.java b/src/org/ntlab/trace/ThreadInstance.java new file mode 100644 index 0000000..627f410 --- /dev/null +++ b/src/org/ntlab/trace/ThreadInstance.java @@ -0,0 +1,177 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +public class ThreadInstance { + private ArrayList roots = new ArrayList(); + private MethodExecution curMethodExecution = null; + private MethodInvocation curMethodInvocation = null; + private String id; + + public ThreadInstance(String id) { + this.id = id; + } + + public void addRoot(MethodExecution root) { + this.roots.add(root); + curMethodExecution = root; + } + + public ArrayList getRoot() { + return roots; + } + + public String getId() { + return id; + } + + public void preCallMethod(String callerSideSignature, int lineNumOfInvocationStatement) { + if (curMethodExecution != null) { + curMethodInvocation = new MethodInvocation(callerSideSignature, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), lineNumOfInvocationStatement, id); + } + } + + public void callMethod(String signature, String callerSideSignature, String receiverClassName, String receiverObjId, + boolean isConstractor, boolean isStatic, long timeStamp) { + if (callerSideSignature == null && curMethodInvocation != null) { + callerSideSignature = curMethodInvocation.getCallerSideMethodName(); + } + MethodExecution newMethodExecution = new MethodExecution(signature, callerSideSignature, receiverClassName, receiverObjId, isConstractor, isStatic, timeStamp); + if (curMethodExecution != null) { + if (curMethodInvocation == null) { + curMethodExecution.addStatement(new MethodInvocation(newMethodExecution, curMethodExecution.getThisClassName(), curMethodExecution.getThisObjId(), 0, id)); + } else { + curMethodInvocation.setCalledMethodExecution(newMethodExecution); + curMethodExecution.addStatement(curMethodInvocation); + curMethodInvocation = null; + } + newMethodExecution.setCaller(curMethodExecution, curMethodExecution.getStatements().size() - 1); + curMethodExecution = newMethodExecution; + } else { + addRoot(newMethodExecution); + } + } + + public void setArgments(ArrayList arguments) { + curMethodExecution.setArguments(arguments); + } + + public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType) { + if (curMethodExecution == null) return; + curMethodExecution.setReturnValue(returnValue); + if (curMethodExecution.getThisObjId().equals("0")) { + curMethodExecution.setThisObjeId(thisObjId); + } + curMethodExecution.setCollectionType(isCollectionType); + curMethodExecution = curMethodExecution.getParent(); + curMethodInvocation = null; // �O�̂��� + } + + public void returnMethod(ObjectReference returnValue, String thisObjId, boolean isCollectionType, long exitTime) { + if (curMethodExecution != null) curMethodExecution.setExitTime(exitTime); + returnMethod(returnValue, thisObjId, isCollectionType); + } + + public void terminateMethod() { + if (curMethodExecution == null) return; + curMethodExecution.setTerminated(true); + curMethodExecution = curMethodExecution.getParent(); + } + + public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId) { + FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, 0, id); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldAccess(String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { + FieldAccess fieldAccess = new FieldAccess(valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldAccess(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, String thisClassName, String thisId, int lineNo, long timeStamp) { + FieldAccess fieldAccess = new FieldAccess(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, thisClassName, thisId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldAccess); + } + + public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId) { + FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, 0, id); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void fieldUpdate(String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { + FieldUpdate fieldUpdate = new FieldUpdate(valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void fieldUpdate(String fieldName, String valueClassName, String valueObjId, String containerClassName, String containerObjId, int lineNo, long timeStamp) { + FieldUpdate fieldUpdate = new FieldUpdate(fieldName, valueClassName, valueObjId, containerClassName, containerObjId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(fieldUpdate); + } + + public void arrayCreate(String arrayClassName, String arrayObjectId, int dimension, int lineNo, long timeStamp) { + ArrayCreate arrayCreate = new ArrayCreate(arrayClassName, arrayObjectId, dimension, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arrayCreate); + } + + public void arraySet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { + ArrayUpdate arraySet = new ArrayUpdate(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arraySet); + } + + public void arrayGet(String arrayClassName, String arrayObjectId, int index, String valueClassName, String valueObjectId, int lineNo, long timeStamp) { + ArrayAccess arrayGet = new ArrayAccess(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(arrayGet); + } + + public void blockEnter(int blockId, int incomings, int lineNo, long timeStamp) { + BlockEnter blockEnter = new BlockEnter(blockId, incomings, lineNo, id, timeStamp); + if (curMethodExecution != null) curMethodExecution.addStatement(blockEnter); + } + + public void traverseMethodExecutionsBackward(IMethodExecutionVisitor visitor) { + visitor.preVisitThread(this); + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.traverseMethodExecutionsBackward(visitor); + } + visitor.postVisitThread(this); + } + + public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { + visitor.preVisitThread(this); + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + if (root.getEntryTime() <= markEnd) { + root.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + } else { + break; + } + } + visitor.postVisitThread(this); + } + + public void getUnmarkedMethodSignatures(HashSet signatures, long markStart, long markEnd) { + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + } + + public void getUnmarkedMethodExecutions(HashMap> executions, long markStart, long markEnd) { + for (int i = 0; i < roots.size(); i++) { + MethodExecution root = roots.get(i); + root.getUnmarkedMethodExecutions(executions, markStart, markEnd); + } + } + + public MethodExecution getCurrentMethodExecution() { + return curMethodExecution; + } + + public TracePoint getCurrentTracePoint() { + return new TracePoint(curMethodExecution, curMethodExecution.getStatements().size() - 1); + } +} diff --git a/src/org/ntlab/trace/ThreadInstanceJPDA.java b/src/org/ntlab/trace/ThreadInstanceJPDA.java new file mode 100644 index 0000000..3a7ecea --- /dev/null +++ b/src/org/ntlab/trace/ThreadInstanceJPDA.java @@ -0,0 +1,58 @@ +package org.ntlab.trace; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +public class ThreadInstanceJPDA { + private ArrayList roots = new ArrayList(); + private MethodExecutionJPDA curMethodExecution = null; + private String id; + + public ThreadInstanceJPDA(String id) { + this.id = id; + } + + public void addRoot(MethodExecutionJPDA root) { + this.roots.add(root); + curMethodExecution = root; + } + + public ArrayList getRoot() { + return roots; + } + + public String getId() { + return id; + } + + public void callMethod(String signature, long timeStamp) { + MethodExecutionJPDA newMethodExecution = new MethodExecutionJPDA(signature, timeStamp); + if (curMethodExecution != null) { + curMethodExecution.addChild(newMethodExecution); + newMethodExecution.setCaller(curMethodExecution); + curMethodExecution = newMethodExecution; + } else { + addRoot(newMethodExecution); + } + } + + public void returnMethod() { + if (curMethodExecution == null) return; + curMethodExecution = curMethodExecution.getParent(); + } + + public MethodExecutionJPDA getCuurentMethodExecution() { + return curMethodExecution; + } + + public void traverseMethodExecutionsBackward(MethodExecutionJPDA.IMethodExecutionVisitorJPDA visitor) { + visitor.preVisitThread(this); + for (int i = 0; i < roots.size(); i++) { + MethodExecutionJPDA root = roots.get(i); + root.traverseMethodExecutionsBackward(visitor); + } + visitor.postVisitThread(this); + } +} diff --git a/src/org/ntlab/trace/Trace.java b/src/org/ntlab/trace/Trace.java new file mode 100644 index 0000000..b46d7e4 --- /dev/null +++ b/src/org/ntlab/trace/Trace.java @@ -0,0 +1,1282 @@ +package org.ntlab.trace; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Stack; + +public class Trace { + protected static final boolean EAGER_DETECTION_OF_ARRAY_SET = false; // �z��v�f�ւ̑���̌��o�𑽂����ς��邩?(�������ς����False Positive�ɂȂ�”\��������) + protected static Trace theTrace = null; + protected HashMap threads = new HashMap(); + + protected Trace() { + } + + /** + * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param file �g���[�X�t�@�C�� + */ + public Trace(BufferedReader file) { + try { + read(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * �w�肵��PlainText�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param traceFile �g���[�X�t�@�C���̃p�X + */ + public Trace(String traceFile) { + BufferedReader file; + try { + file = new BufferedReader(new FileReader(traceFile)); + read(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void read(BufferedReader file) throws IOException { + // �g���[�X�t�@�C���ǂݍ��� + String line, prevLine = null; + String signature; + String callerSideSignature; + String threadNo = null; + String[] methodData; + String[] argData; + String[] returnData; + String[] accessData; + String[] updateData; + String thisObjectId; + String thisClassName; + boolean isConstractor = false; + boolean isCollectionType = false; + boolean isStatic = false; + long timeStamp = 0L; + ThreadInstance thread = null; + HashMap> stacks = new HashMap>(); + while ((line = file.readLine()) != null) { + // �g���[�X�t�@�C���̉�� + if (line.startsWith("Method")) { + // ���\�b�h�Ăяo���i�R���X�g���N�^�Ăяo�����܂ށj + methodData = line.split(":"); + int n = methodData[0].indexOf(','); + signature = methodData[0].substring(n + 1); + threadNo = methodData[methodData.length - 1].split(" ")[1]; + thisObjectId = methodData[1]; + thisClassName = methodData[0].substring(0, n).split(" ")[1]; + isConstractor = false; + isStatic = false; + if (signature.contains("static ")) { + isStatic = true; + } + callerSideSignature = signature; + timeStamp = Long.parseLong(methodData[methodData.length - 2]); + if (prevLine != null) { + if (prevLine.startsWith("New")) { + isConstractor = true; + } else if (prevLine.startsWith("Invoke")) { + callerSideSignature = prevLine.split(":")[1]; + } + } + thread = threads.get(threadNo); + Stack stack; + if (thread == null) { + thread = new ThreadInstance(threadNo); + threads.put(threadNo, thread); + stack = new Stack(); + stacks.put(threadNo, stack); + } else { + stack = stacks.get(threadNo); + } + stack.push(line); + thread.callMethod(signature, callerSideSignature, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp); + } else if (line.startsWith("Args")) { + // ���\�b�h�Ăяo���̈��� + argData = line.split(":"); + threadNo = argData[argData.length - 1].split(" ")[1]; + thread = threads.get(threadNo); + ArrayList arguments = new ArrayList(); + for (int k = 1; k < argData.length - 2; k += 2) { + arguments.add(new ObjectReference(argData[k+1], argData[k])); + } + thread.setArgments(arguments); + } else if (line.startsWith("Return")) { + // ���\�b�h����̕��A + returnData = line.split(":"); + threadNo = returnData[returnData.length - 1].split(" ")[1]; + Stack stack = stacks.get(threadNo); + if (!stack.isEmpty()) { + String line2 = stack.peek(); + if (line2.split("\\(")[0].endsWith(line.split("\\(")[1])) { + stack.pop(); + } else { + do { + stack.pop(); + thread.terminateMethod(); + line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.split("\\(")[0].endsWith(line.split("\\(")[1])); + if (!stack.isEmpty()) stack.pop(); + } + thread = threads.get(threadNo); + ObjectReference returnValue = new ObjectReference(returnData[2], returnData[1]); + thisObjectId = returnData[2]; + isCollectionType = false; + String curLine = returnData[0]; + if(curLine.contains("Return call(List") + || curLine.contains("Return call(Vector") + || curLine.contains("Return call(Iterator") + || curLine.contains("Return call(ListIterator") + || curLine.contains("Return call(ArrayList") + || curLine.contains("Return call(Stack") + || curLine.contains("Return call(Hash") + || curLine.contains("Return call(Map") + || curLine.contains("Return call(Set") + || curLine.contains("Return call(Linked") + || curLine.contains("Return call(Thread")) { + isCollectionType = true; + } + thread.returnMethod(returnValue, thisObjectId, isCollectionType); + } + } else if (line.startsWith("get")) { + // �t�B�[���h�A�N�Z�X + accessData = line.split(":"); + threadNo = accessData[8].split(" ")[1]; + thread = threads.get(threadNo); + if (thread != null) thread.fieldAccess(accessData[5], accessData[6], accessData[3], accessData[4], accessData[1], accessData[2]); + } else if (line.startsWith("set")) { + // �t�B�[���h�X�V + updateData = line.split(":"); + threadNo = updateData[6].split(" ")[1]; + thread = threads.get(threadNo); + if (thread != null) thread.fieldUpdate(updateData[3], updateData[4], updateData[1], updateData[2]); + } + prevLine = line; + } + } + + /** + * �I�����C����͗p�V���O���g���̎擾 + * @return �I�����C����͗p�g���[�X + */ + public static Trace getInstance() { + if (theTrace == null) { + theTrace = new Trace(); + } + return theTrace; + } + + /** + * �X���b�hID���w�肵�ăX���b�h�C���X�^���X���擾����(�I�����C����͗p) + * @param threadId + * @return �X���b�h�C���X�^���X + */ + public static ThreadInstance getThreadInstance(String threadId) { + return getInstance().threads.get(threadId); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾����(�I�����C����͗p) + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̃��\�b�h���s + */ + public static MethodExecution getCurrentMethodExecution(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentMethodExecution(); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃g���[�X�|�C���g���擾����(�I�����C����͗p) + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̎��s���̃g���[�X�|�C���g + */ + public static TracePoint getCurrentTracePoint(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentTracePoint(); + } + + /** + * �S�X���b�h���擾���� + * @return �X���b�hID����X���b�h�C���X�^���X�ւ̃}�b�v + */ + public HashMap getAllThreads() { + return threads; + } + + /** + * ���\�b�h���ɑS���\�b�h���s��S�ẴX���b�h������o�� + * @return ���\�b�h�V�O�j�`�����烁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getAllMethodExecutions() { + Iterator threadsIterator = threads.keySet().iterator(); + final HashMap> results = new HashMap<>(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + String signature = methodExecution.getSignature(); + ArrayList executions = results.get(signature); + if (executions == null) { + executions = new ArrayList<>(); + results.put(signature, executions); + } + executions.add(methodExecution); + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return results; + } + + /** + * �S���\�b�h�̃V�O�j�`�����擾���� + * @return �S���\�b�h�V�O�j�`�� + */ + public HashSet getAllMethodSignatures() { + final HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + signatures.add(methodExecution.getSignature()); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return signatures; + } + + /** + * ���\�b�h���� methodSignature�@�ɑO����v���郁�\�b�h���s��S�ẴX���b�h������o�� + * @param methodSignature ���������� + * @return ��v�����S���\�b�h���s + */ + public ArrayList getMethodExecutions(final String methodSignature) { + Iterator threadsIterator = threads.keySet().iterator(); + final ArrayList results = new ArrayList(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + if (methodExecution.getSignature().startsWith(methodSignature)) { + results.add(methodExecution); + } + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return results; + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @return �Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(final String methodSignature) { + return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getSignature().startsWith(methodSignature)) return true; + return false; + } + }); + } + + /** + * methodSignature �ɑO����v���郁�\�b�h�������ƒ��\�b�h�� before �ȑO�̍Ō�̎��s + * @param methodSignature ���\�b�h��(�O����v�Ō�������) + * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��) + * @return�@�Y������Ō�̃��\�b�h���s + */ + public MethodExecution getLastMethodExecution(final String methodSignature, TracePoint before) { + return traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getSignature().startsWith(methodSignature)) return true; + return false; + } + }, before); + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y�����郁�\�b�h�V�O�j�`�� + */ + public HashSet getMarkedMethodSignatures(final long markStart, final long markEnd) { + final HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + signatures.add(methodExecution.getSignature()); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }, markStart, markEnd); + } + return signatures; + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�S���\�b�h���s�����\�b�h���Ɏ擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getMarkedMethodExecutions(final long markStart, final long markEnd) { + final HashMap>allExecutions = new HashMap<>(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMarkedMethodExecutions(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + ArrayList executions = allExecutions.get(methodExecution.getSignature()); + if (executions == null) { + executions = new ArrayList<>(); + allExecutions.put(methodExecution.getSignature(), executions); + } + executions.add(methodExecution); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }, markStart, markEnd); + } + return allExecutions; + } + + /** + * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h�̃V�O�j�`�����擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y�����郁�\�b�h�V�O�j�`�� + */ + public HashSet getUnmarkedMethodSignatures(long markStart, long markEnd) { + HashSet signatures = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.getUnmarkedMethodSignatures(signatures, markStart, markEnd); + } + return signatures; + } + + /** + * �}�[�N�O�Ŏ��s���J�n���ꂽ�S���\�b�h���s���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return ���\�b�h�V�O�j�`������Y�����郁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getUnmarkedMethodExecutions(long markStart, long markEnd) { + HashMap> executions = new HashMap<>(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.getUnmarkedMethodExecutions(executions, markStart, markEnd); + } + return executions; + } + + + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions) { + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + return getLastMethodEntryInThread(rootExecutions, lastExecution.getExitOutPoint()); + } + + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start) { + return getLastMethodEntryInThread(rootExecutions, start, -1L); + } + + /** + * + * @param rootExecutions + * @param start + * @param before + * @return + */ + protected TracePoint getLastMethodEntryInThread(ArrayList rootExecutions, TracePoint start, final long before) { + final TracePoint cp[] = new TracePoint[1]; + cp[0] = start; + for (;;) { + if (!cp[0].isStepBackOut() && traverseMethodExecutionsInCallTreeBackward ( + new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { return false; } + @Override + public boolean postVisitThread(ThreadInstance thread) { return false; } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + if (methodExecution.getEntryTime() < before || before == -1L) { + cp[0] = methodExecution.getEntryPoint(); + return true; + } + return false; + } + }, cp[0])) { + return cp[0]; + } + if (rootExecutions.size() == 0) break; + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + cp[0] = lastExecution.getExitOutPoint(); + } + return null; + } + + public boolean getLastStatementInThread(String threadId, final TracePoint[] start, final IStatementVisitor visitor) { + return getLastStatementInThread((ArrayList) threads.get(threadId).getRoot().clone(), start, start[0].getStatement().getTimeStamp(), visitor); + } + + protected boolean getLastStatementInThread(ArrayList rootExecutions, final TracePoint[] start, final long before, final IStatementVisitor visitor) { + final boolean[] bArrived = new boolean[] { + false + }; + for (;;) { + if (start[0].isValid() && traverseStatementsInCallTreeBackward( + new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); + if ((!methodExecution.isTerminated() && methodExecution.getExitTime() < before) || before == -1L) { + if (visitor.preVisitStatement(statement)) return true; + bArrived[0] = true; + return true; + } + } else { + if (statement.getTimeStamp() < before || before == -1L) { + if (visitor.preVisitStatement(statement)) return true; + bArrived[0] = true; + return true; + } + } + return visitor.preVisitStatement(statement); + } + @Override + public boolean postVisitStatement(Statement statement) { + return visitor.postVisitStatement(statement); + } + }, start[0])) { + return !bArrived[0]; + } + if (rootExecutions.size() == 0) break; + MethodExecution lastExecution = rootExecutions.remove(rootExecutions.size() - 1); + start[0] = lastExecution.getExitPoint(); + } + start[0] = null; + return false; + } + + public TracePoint getCreationTracePoint(final ObjectReference newObjectId, TracePoint before) { + before = before.duplicate(); + before = traverseStatementsInTraceBackward( + new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation)statement; + if (mi.getCalledMethodExecution().isConstructor() + && mi.getCalledMethodExecution().getReturnValue().equals(newObjectId)) { + return true; + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, before); + if (before != null) { + return before; + } + return null; + } + + public TracePoint getFieldUpdateTracePoint(final Reference ref, TracePoint before) { + before = before.duplicate(); + final String srcType = ref.getSrcClassName(); + final String dstType = ref.getDstClassName(); + final String srcObjId = ref.getSrcObjectId(); + final String dstObjId = ref.getDstObjectId(); + + before = traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldUpdate) { + FieldUpdate fu = (FieldUpdate)statement; + if (fu.getContainerObjId().equals(srcObjId) + && fu.getValueObjId().equals(dstObjId)) { + // �I�u�W�F�N�gID���݂��Ɉ�v�����ꍇ + return true; + } else if ((srcObjId == null || isNull(srcObjId)) && fu.getContainerClassName().equals(srcType)) { + if ((dstObjId == null || isNull(dstObjId)) && fu.getValueClassName().equals(dstType)) { + // ref �ɃI�u�W�F�N�gID���w�肵�Ă��Ȃ������ꍇ + ref.setSrcObjectId(fu.getContainerObjId()); + ref.setDstObjectId(fu.getValueObjId()); + return true; + } else if (fu.getValueObjId().equals(dstObjId)) { + // �N���X�ϐ��ւ̑���̏ꍇ + ref.setSrcObjectId(srcObjId); + ref.setDstClassName(dstType); + return true; + } + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, before); + if (before != null) { + return before; + } + return null; + } + + public TracePoint getCollectionAddTracePoint(final Reference ref, TracePoint before) { + final TracePoint[] result = new TracePoint[1]; + if (traverseMethodEntriesInTraceBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + String srcType = ref.getSrcClassName(); + String dstType = ref.getDstClassName(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + if (methodExecution.isCollectionType() && isCollectionAdd(methodExecution.getSignature())) { + if (dstObjId != null && methodExecution.getThisObjId().equals(srcObjId)) { + ArrayList args = methodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + ObjectReference arg = args.get(i); + if (arg.getId().equals(dstObjId)) { + ref.setSrcClassName(methodExecution.getThisClassName()); + ref.setDstClassName(arg.getActualType()); + result[0] = methodExecution.getCallerTracePoint(); + return true; + } + } + } else if (dstObjId == null && methodExecution.getThisClassName().equals(srcType)) { + ArrayList args = methodExecution.getArguments(); + for (int i = 0; i < args.size(); i++) { + ObjectReference arg = args.get(i); + if (arg.getActualType().equals(dstType)) { + ref.setSrcObjectId(methodExecution.getThisObjId()); + ref.setDstObjectId(arg.getId()); + result[0] = methodExecution.getCallerTracePoint(); + return true; + } + } + } + } + return false; + } + }, before) != null) { + return result[0]; + } + return null; + } + + public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) { + final TracePoint start = before.duplicate(); + before = traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof FieldAccess) { + if (isArraySet(ref, start)) { + return true; + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, start); + if (before != null) { + return before; + } + return null; + } + + private boolean isCollectionAdd(String methodSignature) { + return (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(")); + } + + private boolean isArraySet(Reference ref, TracePoint fieldAccessPoint) { + FieldAccess fieldAccess = (FieldAccess)fieldAccessPoint.getStatement(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + if (fieldAccess.getValueClassName().startsWith("[L") + && fieldAccess.getValueObjId().equals(srcObjId)) { + // srcId �͔z�� + // ���\�b�h���s�J�n���� fieldAccessPoint �܂ł̊Ԃ̃��\�b�h���s���� dstId ���o��������? + TracePoint p = fieldAccessPoint.duplicate(); + while (p.stepBackOver()) { + Statement statement = p.getStatement(); + if (statement instanceof MethodInvocation) { + MethodExecution calledMethod = ((MethodInvocation)statement).getCalledMethodExecution(); + if (calledMethod.getReturnValue().getId().equals(dstObjId)) { + // dstId �͖߂�l�Ƃ��ďo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(calledMethod.getReturnValue().getActualType()); + return true; + } else if (dstObjId == null || isNull(dstObjId) && calledMethod.getReturnValue().getActualType().equals(ref.getDstClassName())) { + // dstClassName �͖߂�l�̌^�Ƃ��ďo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(calledMethod.getReturnValue().getId()); + return true; + } + } + if (EAGER_DETECTION_OF_ARRAY_SET) { + if (statement instanceof FieldAccess) { + if (((FieldAccess)statement).getContainerObjId().equals(dstObjId)) { + // dstId �̓t�B�[���h�ɏo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(((FieldAccess)statement).getContainerClassName()); + return true; + } else if (dstObjId == null || isNull(dstObjId) && ((FieldAccess)statement).getContainerClassName().equals(ref.getDstClassName())) { + // dstClassName �̓t�B�[���h�̌^�Ƃ��ďo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(((FieldAccess)statement).getContainerObjId()); + return true; + } + } + } + } + ArrayList args = fieldAccessPoint.getMethodExecution().getArguments(); + int argindex = args.indexOf(new ObjectReference(dstObjId)); + if (argindex != -1) { + // dstId �͈����ɏo�� + ref.setSrcClassName(fieldAccess.getValueClassName()); + ref.setDstClassName(args.get(argindex).getActualType()); + return true; + } else if (dstObjId == null || isNull(dstObjId)) { + for (int j = 0; j < args.size(); j++) { + if (args.get(j).getActualType().equals(ref.getDstClassName())) { + // dstClassName �͈����̌^�ɏo�� + ref.setSrcObjectId(fieldAccess.getValueObjId()); + ref.setDstObjectId(args.get(j).getId()); + return true; + } + } + } + } + return false; + } + + /** + * �g���[�X���̑S���\�b�h���s�̊J�n�n�_���t�����ɒT������ + * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) + * @return ���f�������\�b�h���s + */ + public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T�� + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList rootExecutions = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + TracePoint threadLastTp = getLastMethodEntryInThread(rootExecutions); + threadLastPoints.put(threadId, threadLastTp); + if (threadLastTp != null) { + long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } + } + } + return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �w�肵�����s���_�ȑO�Ɏ��s���J�n���ꂽ���\�b�h���s�̊J�n���_���t�����ɒT������ + * @param visitor ���\�b�h���s�̃r�W�^�[(postVisitMethodExecution()�����ĂѕԂ��Ȃ��̂Œ���) + * @param before �T���J�n���_ + * @return ���f�������\�b�h���s + */ + public MethodExecution traverseMethodEntriesInTraceBackward(IMethodExecutionVisitor visitor, TracePoint before) { + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); + ArrayList rootExecutions = (ArrayList)thread.getRoot().clone(); + for (int n = rootExecutions.size() - 1; n >= 0; n--) { + MethodExecution root = rootExecutions.get(n); + if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + before = getLastMethodEntryInThread(rootExecutions, before); + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + if (t == thread) { + threadRoots.put(threadId, rootExecutions); + traceLastThread = threadId; + threadLastPoints.put(threadId, before); + } else { + ArrayList rootExes = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExes); + MethodExecution threadLastExecution = rootExes.remove(rootExes.size() - 1); + TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExes, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); + threadLastPoints.put(threadId, threadBeforeTp); + if (threadBeforeTp != null) { + long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + return traverseMethodEntriesInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + private MethodExecution traverseMethodEntriesInTraceBackwardSub( + final IMethodExecutionVisitor visitor, + HashMap> threadRoots, HashMap threadLastPoints, + String traceLastThread, String traceLastThread2, long traceLastTime2) { + // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ƀ��\�b�h���s��T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̋t�����T�� + TracePoint threadLastTp = threadLastPoints.get(traceLastThread); + MethodExecution threadLastExecution = threadLastTp.getMethodExecution(); + do { + threadLastTp.stepBackOver(); + // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ + threadLastTp = getLastMethodEntryInThread(threadRoots.get(traceLastThread), threadLastTp); + if (threadLastTp == null) break; + if (visitor.postVisitMethodExecution(threadLastExecution, threadLastExecution.getChildren())) { + // �Y�����郁�\�b�h���s�����‚��� + return threadLastExecution; + } + threadLastExecution = threadLastTp.getMethodExecution(); + } while (threadLastExecution.getEntryTime() > traceLastTime2); + threadLastPoints.put(traceLastThread, threadLastTp); + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint lastTp = threadLastPoints.get(threadId); + if (lastTp != null) { + continueTraverse = true; + long threadLastTime = lastTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } + + /** + * �Ăяo�����̎����� markStart ���� markEnd �̊Ԃɂ���S�X���b�h���̑S���\�b�h���s��T������ + * @param visitor�@�r�W�^�[ + * @param markStart �J�n���� + * @param markEnd �I������ + */ + public void traverseMarkedMethodExecutions(IMethodExecutionVisitor visitor, long markStart, long markEnd) { + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + thread.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + } + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ炪�S���s�����������ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @return ���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTrace(IStatementVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadCurPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŏ��ɊJ�n�������\�b�h���s��T�� + long traceCurTime = -1; + String traceCurThread = null; + long traceCurTime2 = -1; + String traceCurThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList roots = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, roots); + TracePoint threadCurTp; + do { + MethodExecution threadCurExecution = roots.remove(0); + threadCurTp = threadCurExecution.getEntryPoint(); + } while (!threadCurTp.isValid() && roots.size() > 0); + if (threadCurTp.isValid()) { + threadCurPoints.put(threadId, threadCurTp); + long methodEntry = threadCurTp.getMethodExecution().getEntryTime(); + if (traceCurTime == -1 || traceCurTime > methodEntry) { + traceCurTime2 = traceCurTime; + traceCurThread2 = traceCurThread; + traceCurTime = methodEntry; + traceCurThread = threadId; + } + } else { + threadCurPoints.put(threadId, null); + } + } + return traverseStatementsInTraceSub(visitor, threadRoots, threadCurPoints, traceCurThread, traceCurThread2, traceCurTime2); + } + + private TracePoint traverseStatementsInTraceSub(IStatementVisitor visitor, + HashMap> threadRoots, + HashMap threadCurPoints, + String curThreadId, String nextThreadId, long nextThreadTime) { + // �S�X���b�h�̓������Ƃ�Ȃ��珇�����Ɏ��s����T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̏������T�� + TracePoint curTp = threadCurPoints.get(curThreadId); + while (curTp != null + && (curTp.getStatement().getTimeStamp() <= nextThreadTime || nextThreadTime == -1)) { + Statement statement = curTp.getStatement(); + if (visitor.preVisitStatement(statement)) return curTp; + if (!(statement instanceof MethodInvocation)) { + if (visitor.postVisitStatement(statement)) return curTp; + } + curTp.stepNoReturn(); // ���A�����ɌĂяo���؂�����Ă��� + if (!curTp.isValid()) { + // ���A���Ȃ��Ƃ���ȏ�T���ł��Ȃ� + while (!curTp.stepOver()) { // ���x�͕��A�͂��邪���炸�ɒT�� + if (curTp.isValid()) { + // �Ăяo����T���O�Ɉ�x�K��ς݂̃��\�b�h�Ăяo���s���A�T���������x�K�₷�� + if (visitor.postVisitStatement(curTp.getStatement())) return curTp; + } else { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList roots = threadRoots.get(curThreadId); + while (!curTp.isValid() && roots.size() > 0) { + // ���̌Ăяo���؂�����΂�����ŏ�����T�� + MethodExecution firstExecution = roots.remove(0); + curTp = firstExecution.getEntryPoint(); + } + if (curTp.isValid()) { + // ���̌Ăяo���؂�����΂�����ŏ�����T�� + threadCurPoints.put(curThreadId, curTp); + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadCurPoints.put(curThreadId, null); + curTp = null; + } + break; + } + } + } + } + curThreadId = nextThreadId; + if (curThreadId == null) break; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŏ��Ɏn�܂�X���b�h)�����肷�� + nextThreadTime = -1; + nextThreadId = null; + boolean continueTraverse = false; + for (String threadId: threadCurPoints.keySet()) { + if (!threadId.equals(curThreadId)) { + TracePoint threadTp = threadCurPoints.get(threadId); + if (threadTp != null) { + continueTraverse = true; + long threadTime = threadTp.getStatement().getTimeStamp(); + if (threadTime > 0 && (nextThreadTime == -1 || nextThreadTime > threadTime)) { + nextThreadTime = threadTime; + nextThreadId = threadId; + } + } + } + } + if (!continueTraverse && threadCurPoints.get(curThreadId) == null) break; + } + return null; + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ炪�S���s�����t�����ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @return ���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T�� + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList root = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, root); + TracePoint threadLastTp; + do { + MethodExecution threadLastExecution = root.remove(root.size() - 1); + threadLastTp = threadLastExecution.getExitPoint(); + } while (!threadLastTp.isValid() && root.size() > 0); + if (threadLastTp.isValid()) { + threadLastPoints.put(threadId, threadLastTp); + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, threadLastTp)) return threadLastTp; + long methodEntry = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime < methodEntry) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = methodEntry; + traceLastThread = threadId; + } + } else { + threadLastPoints.put(threadId, null); + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * + * @param visitor + * @param before + * @return + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { + if (before == null) { + return traverseStatementsInTraceBackward(visitor); + } + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return before; + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + if (t == thread) { + traceLastThread = threadId; + threadLastPoints.put(threadId, before); + for (int n = rootExecutions.size() - 1; n >= 0; n--) { + MethodExecution root = rootExecutions.get(n); + if (root.getEntryTime() > before.getMethodExecution().getEntryTime()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + } else { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + TracePoint threadBeforeTp = getLastMethodEntryInThread(rootExecutions, threadLastExecution.getExitOutPoint(), before.getMethodExecution().getEntryTime()); + threadLastPoints.put(threadId, threadBeforeTp); + if (threadBeforeTp != null) { + long threadLastTime = threadBeforeTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + private TracePoint traverseStatementsInTraceBackwardSub(IStatementVisitor visitor, + HashMap> threadRoots, + HashMap threadLastPoints, + String traceLastThread, String traceLastThread2, long traceLastTime2) { + // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ɏ��s����T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̋t�����T�� + TracePoint lastTp = threadLastPoints.get(traceLastThread); + do { + if (lastTp.stepBackOver()) { + // ���̃X���b�h�̎��̃��\�b�h���s�J�n���_�܂ŒT������ + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; + } else { + // �Ăяo�����ɖ߂����ꍇ + if (lastTp.isValid()) { + if (visitor.postVisitStatement(lastTp.getStatement())) return lastTp; + } else { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList root = threadRoots.get(traceLastThread); + while (!lastTp.isValid() && root.size() > 0) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + MethodExecution lastExecution = root.remove(root.size() - 1); + lastTp = lastExecution.getExitPoint(); + } + if (lastTp.isValid()) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + threadLastPoints.put(traceLastThread, lastTp); + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, lastTp)) return lastTp; + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadLastPoints.put(traceLastThread, null); + break; + } + } + } + } while (lastTp.getMethodExecution().getEntryTime() >= traceLastTime2); + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint threadLastTp = threadLastPoints.get(threadId); + if (threadLastTp != null) { + continueTraverse = true; + long threadLastTime = threadLastTp.getMethodExecution().getEntryTime(); + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } + + /** + * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���Ăяo���ؓ��̑S���s�����t�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) + * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseStatementsInCallTreeBackward(IStatementVisitor visitor, TracePoint before) { + for (;;) { + if (traverseStatamentsInCallTreeBackwardNoReturn(visitor, before)) return true; + while (!before.stepBackOver()) { + if (!before.isValid()) break; + if (visitor.postVisitStatement(before.getStatement())) return true; + } + if (!before.isValid()) break; + } + return false; + } + + /** + * before�ȑO�̌Ăяo���؂��Ăяo���悩��̕��A�������ɍs����Ƃ���܂ŋt�����ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @param before �T���J�n���s���_ + * @return true -- �T���𒆒f����, false -- ���A�����Ȃ����肱��ȏ�i�߂Ȃ� + */ + private boolean traverseStatamentsInCallTreeBackwardNoReturn(IStatementVisitor visitor, TracePoint before) { + for (;;) { + Statement statement = before.getStatement(); + if (statement instanceof MethodInvocation) { + // ���\�b�h�Ăяo�����̏ꍇ�́A�Ăяo���̑O��� preVisit �� postVisit ��ʁX�Ɏ��s���� + if (visitor.preVisitStatement(statement)) return true; + before.stepBackNoReturn(); + if (!before.isValid()) { + // �Ăяo����̃��\�b�h�Ŏ��s�����L�^����Ă��Ȃ��ꍇ + before.stepBackOver(); + if (visitor.postVisitStatement(statement)) return true; + if (before.isMethodEntry()) return false; + before.stepBackOver(); + } + } else { + if (visitor.preVisitStatement(statement)) return true; + if (visitor.postVisitStatement(statement)) return true; + if (before.isMethodEntry()) return false; + before.stepBackNoReturn(); + } + } + } + + /** + * before �Ŏw�肵���g���[�X�|�C���g�ȑO�̓���X���b�h���̑S���\�b�h���s���Ăяo���؂̒��ŋt�����ɒT������(�������Avisitor �� true ��Ԃ��܂�) + * @param visitor �r�W�^�[ + * @param before �T���̊J�n�_(�T���ΏۃX���b�h���w�肵�Ă���) + * @return true -- �T���𒆒f����, false -- �Ō�܂ŒT������ + */ + public boolean traverseMethodExecutionsInCallTreeBackward(IMethodExecutionVisitor visitor, TracePoint before) { + ArrayList prevMethodExecutions = before.getPreviouslyCalledMethods(); + for (int i = prevMethodExecutions.size() - 1; i >= 0; i--) { + MethodExecution child = prevMethodExecutions.get(i); + if (child.traverseMethodExecutionsBackward(visitor)) return true; + } + MethodExecution methodExecution = before.getMethodExecution(); + if (visitor.postVisitMethodExecution(methodExecution, null)) return true; + TracePoint caller = methodExecution.getCallerTracePoint(); + if (caller != null) { + if (traverseMethodExecutionsInCallTreeBackward(visitor, caller)) return true; + } + return false; + } + + public static String getDeclaringType(String methodSignature, boolean isConstructor) { + if (methodSignature == null) return null; + if (isConstructor) { + String[] fragments = methodSignature.split("\\("); + return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1); + } + String[] fragments = methodSignature.split("\\("); + return fragments[0].substring(fragments[0].lastIndexOf(' ') + 1, fragments[0].lastIndexOf('.')); + } + + public static String getMethodName(String methodSignature) { + String[] fragments = methodSignature.split("\\("); + String[] fragments2 = fragments[0].split("\\."); + return fragments2[fragments2.length - 1]; + } + + public static String getReturnType(String methodSignature) { + String[] fragments = methodSignature.split(" "); + for (int i = 0; i < fragments.length; i++) { + if (!fragments[i].equals("public") && !fragments[i].equals("private") && !fragments[i].equals("protected") + && !fragments[i].equals("abstract") && !fragments[i].equals("final") && !fragments[i].equals("static") + && !fragments[i].equals("synchronized") && !fragments[i].equals("native")) { + return fragments[i]; + } + } + return ""; + } + + public static boolean isNull(String objectId) { + return objectId.equals("0"); + } + + public static String getNull() { + return "0"; + } + + public static boolean isPrimitive(String typeName) { + if (typeName.equals("int") + || typeName.equals("boolean") + || typeName.equals("long") + || typeName.equals("double") + || typeName.equals("float") + || typeName.equals("char") + || typeName.equals("byte") + || typeName.equals("java.lang.Integer") + || typeName.equals("java.lang.Boolean") + || typeName.equals("java.lang.Long") + || typeName.equals("java.lang.Double") + || typeName.equals("java.lang.Float") + || typeName.equals("java.lang.Character") + || typeName.equals("java.lang.Byte")) return true; + return false; + } +} diff --git a/src/org/ntlab/trace/TraceJPDA.java b/src/org/ntlab/trace/TraceJPDA.java new file mode 100644 index 0000000..a25a6b0 --- /dev/null +++ b/src/org/ntlab/trace/TraceJPDA.java @@ -0,0 +1,157 @@ +package org.ntlab.trace; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Stack; + +public class TraceJPDA { + protected HashMap threads = new HashMap(); + + /** + * �w�肵��JSON�g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param traceFile �g���[�X�t�@�C���̃p�X + */ + public TraceJPDA(BufferedReader file) { + try { + readJPDA(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * �w�肵��JSON�g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param traceFile �g���[�X�t�@�C���̃p�X + */ + public TraceJPDA(String traceFile) { + BufferedReader file; + try { + file = new BufferedReader(new FileReader(traceFile)); + readJPDA(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readJPDA(BufferedReader file) throws IOException { + // �g���[�X�t�@�C���ǂݍ��� + String line = null; + String[] columns; + String[] columns2; + String[] stack; + String[] signature; + String threadId; + String threadName; + HashMap threadCallDepths = new HashMap<>(); + int depth = 0; + long timeStamp = 0L; + ThreadInstanceJPDA thread = null; + while ((line = file.readLine()) != null) { + // �g���[�X�t�@�C���̉�� + columns = line.split(":"); + if (columns.length < 4) continue; + threadName = columns[0]; + threadId = columns[1]; + stack = columns[2].split(" "); + columns2 = columns[3].split("\t"); + if (columns2.length < 2) continue; + timeStamp = Integer.parseInt(stack[stack.length - 1]) * 60 + + Integer.parseInt(columns2[0]); + depth = stack.length - 1; + signature = columns2[1].split(" -- "); + thread = threads.get(threadName); + if (thread == null) { + thread = new ThreadInstanceJPDA(threadName); + threads.put(threadName, thread); + threadCallDepths.put(threadName, 0); + } + if (signature.length < 2) continue; + for (int i = 0; i < threadCallDepths.get(threadName) - depth + 1; i++) { + thread.returnMethod(); + } + thread.callMethod(signature[1] + "." + signature[0] + "()", timeStamp); + threadCallDepths.put(threadName, depth); + } + } + + /** + * ���\�b�h���ɑS���\�b�h���s��S�ẴX���b�h������o�� + * @return ���\�b�h�V�O�j�`�����烁�\�b�h���s�̃��X�g�ւ�HashMap + */ + public HashMap> getAllMethodExecutions() { + final HashMap> results = new HashMap<>(); + for (ThreadInstanceJPDA thread: threads.values()) { + thread.traverseMethodExecutionsBackward(new MethodExecutionJPDA.IMethodExecutionVisitorJPDA() { + @Override + public boolean preVisitThread(ThreadInstanceJPDA thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstanceJPDA thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution) { + ArrayList executions = results.get(methodExecution.getSignature()); + if (executions == null) { + executions = new ArrayList(); + results.put(methodExecution.getSignature(), executions); + } + executions.add(methodExecution); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList children) { + return false; + } + }); + } + return results; + } + + /** + * �S���\�b�h�̃V�O�j�`�����擾���� + * @return �S���\�b�h�V�O�j�`�� + */ + public HashSet getAllMethodSignatures() { + final HashSet results = new HashSet(); + for (ThreadInstanceJPDA thread: threads.values()) { + thread.traverseMethodExecutionsBackward(new MethodExecutionJPDA.IMethodExecutionVisitorJPDA() { + @Override + public boolean preVisitThread(ThreadInstanceJPDA thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstanceJPDA thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution) { + results.add(methodExecution.getSignature()); + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList children) { + return false; + } + + }); + } + return results; + } + + public void traverseMethodExecutionsBackward(MethodExecutionJPDA.IMethodExecutionVisitorJPDA visitor) { + for (ThreadInstanceJPDA thread: threads.values()) { + visitor.preVisitThread(thread); + thread.traverseMethodExecutionsBackward(visitor); + visitor.postVisitThread(thread); + } + } +} diff --git a/src/org/ntlab/trace/TraceJSON.java b/src/org/ntlab/trace/TraceJSON.java new file mode 100644 index 0000000..973290a --- /dev/null +++ b/src/org/ntlab/trace/TraceJSON.java @@ -0,0 +1,927 @@ +package org.ntlab.trace; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Stack; + +public class TraceJSON extends Trace { + private HashMap classes = new HashMap<>(); + + private TraceJSON() { + + } + + /** + * �w�肵��JSON�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param file �g���[�X�t�@�C�� + */ + public TraceJSON(BufferedReader file) { + try { + readJSON(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * �w�肵��JSON�̃g���[�X�t�@�C������ǂ��� Trace �I�u�W�F�N�g�𐶐����� + * @param traceFile �g���[�X�t�@�C���̃p�X + */ + public TraceJSON(String traceFile) { + BufferedReader file; + try { + file = new BufferedReader(new FileReader(traceFile)); + readJSON(file); + file.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readJSON(BufferedReader file) throws IOException { + // �g���[�X�t�@�C���ǂݍ��� + String line = null; + String[] type; + String[] classNameData; + String[] pathData; + String[] signature; + String[] receiver; + String[] arguments; + String[] lineData; + String[] threadId; + String[] thisObj; + String[] containerObj; + String[] valueObj; + String[] returnValue; + String[] arrayObj; + String[] thisData; + String[] containerData; + String[] valueData; + String[] returnData; + String[] fieldData; + String[] arrayData; + String[] blockIdData; + String[] incomingsData; + String[] dimensionData; + String[] indexData; + String className; + String classPath; + String loaderPath; + String time; + String thisObjectId; + String thisClassName; + String containerObjectId; + String containerClassName; + String valueObjectId; + String valueClassName; + String returnClassName; + String returnObjectId; + String arrayObjectId; + String arrayClassName; + String shortSignature; + boolean isConstractor = false; + boolean isCollectionType = false; + boolean isStatic = false; + int dimension; + int index; + int blockId; + int incomings; + int lineNum; + long timeStamp = 0L; + ThreadInstance thread = null; + HashMap> stacks = new HashMap>(); + while ((line = file.readLine()) != null) { + // �g���[�X�t�@�C���̉�� + if (line.startsWith("{\"type\":\"classDef\"")) { + // �N���X��` + type = line.split(",\"name\":\""); + classNameData = type[1].split("\",\"path\":\""); + className = classNameData[0]; + pathData = classNameData[1].split("\",\"loaderPath\":\""); + classPath = pathData[0].substring(1); // �擪�� / ����菜�� + loaderPath = pathData[1].substring(1, pathData[1].length() - 3); // �擪�� / �ƁA������ "}, ����菜�� + initializeClass(className, classPath, loaderPath); + } else if (line.startsWith("{\"type\":\"methodCall\"")) { + // ���\�b�h�Ăяo���̌Ăяo���� + type = line.split(",\"callerSideSignature\":\""); + signature = type[1].split("\",\"threadId\":"); + threadId = signature[1].split(",\"lineNum\":"); + lineNum = Integer.parseInt(threadId[1].substring(0, threadId[1].length() - 2)); // ������ }, ����菜�� + thread = threads.get(threadId[0]); + thread.preCallMethod(signature[0], lineNum); + } else if (line.startsWith("{\"type\":\"methodEntry\"")) { + // ���\�b�h�Ăяo�� + type = line.split("\"signature\":\""); + signature = type[1].split("\",\"receiver\":"); + receiver = signature[1].split(",\"args\":"); + arguments = receiver[1].split(",\"threadId\":"); + threadId = arguments[1].split(",\"time\":"); + thisData = parseClassNameAndObjectId(receiver[0]); + thisClassName = thisData[0]; + thisObjectId = thisData[1]; + isConstractor = false; + isStatic = false; + if (signature[0].contains("static ")) { + isStatic = true; + } + thread = threads.get(threadId[0]); + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + Stack stack; + if (thread == null) { + thread = new ThreadInstance(threadId[0]); + threads.put(threadId[0], thread); + stack = new Stack(); + stacks.put(threadId[0], stack); + } else { + stack = stacks.get(threadId[0]); + } + stack.push(signature[0]); + // ���\�b�h�Ăяo���̐ݒ� + thread.callMethod(signature[0], null, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp); + // �����̐ݒ� + thread.setArgments(parseArguments(arguments)); + } else if (line.startsWith("{\"type\":\"constructorEntry\"")) { + // �R���X�g���N�^�Ăяo�� + type = line.split("\"signature\":\""); + signature = type[1].split("\",\"class\":\""); + receiver = signature[1].split("\",\"args\":"); + arguments = receiver[1].split(",\"threadId\":"); + threadId = arguments[1].split(",\"time\":"); + thisClassName = receiver[0]; + thisObjectId = "0"; + isConstractor = true; + isStatic = false; + thread = threads.get(threadId[0]); + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + Stack stack; + if (thread == null) { + thread = new ThreadInstance(threadId[0]); + threads.put(threadId[0], thread); + stack = new Stack(); + stacks.put(threadId[0], stack); + } else { + stack = stacks.get(threadId[0]); + } + stack.push(signature[0]); + // ���\�b�h�Ăяo���̐ݒ� + thread.callMethod(signature[0], null, thisClassName, thisObjectId, isConstractor, isStatic, timeStamp); + // �����̐ݒ� + thread.setArgments(parseArguments(arguments)); + } else if (line.startsWith("{\"type\":\"methodExit\"")) { + // ���\�b�h����̕��A + type = line.split(",\"shortSignature\":\""); + signature = type[1].split("\",\"receiver\":"); + receiver = signature[1].split(",\"returnValue\":"); + returnValue = receiver[1].split(",\"threadId\":"); + threadId = returnValue[1].split(",\"time\":"); + thisData = parseClassNameAndObjectId(receiver[0]); + thisClassName = thisData[0]; + thisObjectId = thisData[1]; + returnData = parseClassNameAndObjectId(returnValue[0]); + returnClassName = returnData[0]; + returnObjectId = returnData[1]; + shortSignature = signature[0]; + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + Stack stack = stacks.get(threadId[0]); + if (!stack.isEmpty()) { + String line2 = stack.peek(); + if (line2.endsWith(shortSignature)) { + stack.pop(); + } else { + do { + stack.pop(); + thread.terminateMethod(); + line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); + if (!stack.isEmpty()) stack.pop(); + } + thread = threads.get(threadId[0]); + ObjectReference returnVal = new ObjectReference(returnObjectId, returnClassName); + isCollectionType = false; + if(thisClassName.contains("java.util.List") + || thisClassName.contains("java.util.Vector") + || thisClassName.contains("java.util.Iterator") + || thisClassName.contains("java.util.ListIterator") + || thisClassName.contains("java.util.ArrayList") + || thisClassName.contains("java.util.Stack") + || thisClassName.contains("java.util.Hash") + || thisClassName.contains("java.util.Map") + || thisClassName.contains("java.util.Set") + || thisClassName.contains("java.util.Linked") + || thisClassName.contains("java.lang.Thread")) { + isCollectionType = true; + } + // ���\�b�h����̕��A�̐ݒ� + thread.returnMethod(returnVal, thisObjectId, isCollectionType, timeStamp); + } + } else if (line.startsWith("{\"type\":\"constructorExit\"")) { + // �R���X�g���N�^����̕��A + type = line.split(",\"shortSignature\":\""); + signature = type[1].split("\",\"returnValue\":"); + returnValue = signature[1].split(",\"threadId\":"); + threadId = returnValue[1].split(",\"time\":"); + returnData = parseClassNameAndObjectId(returnValue[0]); + thisClassName = returnClassName = returnData[0]; + thisObjectId = returnObjectId = returnData[1]; + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + Stack stack = stacks.get(threadId[0]); + shortSignature = signature[0]; + if (!stack.isEmpty()) { + String line2 = stack.peek(); + if (line2.endsWith(shortSignature)) { + stack.pop(); + } else { + do { + stack.pop(); + thread.terminateMethod(); + line2 = stack.peek(); + } while (!stack.isEmpty() && !line2.endsWith(shortSignature)); + if (!stack.isEmpty()) stack.pop(); + } + thread = threads.get(threadId[0]); + ObjectReference returnVal = new ObjectReference(returnObjectId, returnClassName); + isCollectionType = false; + if(thisClassName.contains("java.util.List") + || thisClassName.contains("java.util.Vector") + || thisClassName.contains("java.util.Iterator") + || thisClassName.contains("java.util.ListIterator") + || thisClassName.contains("java.util.ArrayList") + || thisClassName.contains("java.util.Stack") + || thisClassName.contains("java.util.Hash") + || thisClassName.contains("java.util.Map") + || thisClassName.contains("java.util.Set") + || thisClassName.contains("java.util.Linked") + || thisClassName.contains("java.lang.Thread")) { + isCollectionType = true; + } + // ���\�b�h����̕��A�̐ݒ� + thread.returnMethod(returnVal, thisObjectId, isCollectionType, timeStamp); + } + } else if (line.startsWith("{\"type\":\"fieldGet\"")) { + // �t�B�[���h�A�N�Z�X + type = line.split(",\"fieldName\":\""); + fieldData = type[1].split("\",\"this\":"); + thisObj = fieldData[1].split(",\"container\":"); + containerObj = thisObj[1].split(",\"value\":"); + valueObj = containerObj[1].split(",\"threadId\":"); + threadId = valueObj[1].split(",\"lineNum\":"); + lineData = threadId[1].split(",\"time\":"); + thisData = parseClassNameAndObjectId(thisObj[0]); + thisClassName = thisData[0]; + thisObjectId = thisData[1]; + containerData = parseClassNameAndObjectId(containerObj[0]); + containerClassName = containerData[0]; + containerObjectId = containerData[1]; + valueData = parseClassNameAndObjectId(valueObj[0]); + valueClassName = valueData[0]; + valueObjectId = valueData[1]; + thread = threads.get(threadId[0]); + lineNum = Integer.parseInt(lineData[0]); + time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + // �t�B�[���h�A�N�Z�X�̐ݒ� + if (thread != null) thread.fieldAccess(fieldData[0], valueClassName, valueObjectId, containerClassName, containerObjectId, thisClassName, thisObjectId, lineNum, timeStamp); + } else if (line.startsWith("{\"type\":\"fieldSet\"")) { + // �t�B�[���h�X�V + type = line.split(",\"fieldName\":\""); + fieldData = type[1].split("\",\"container\":"); + containerObj = fieldData[1].split(",\"value\":"); + valueObj = containerObj[1].split(",\"threadId\":"); + threadId = valueObj[1].split(",\"lineNum\":"); + lineData = threadId[1].split(",\"time\":"); + containerData = parseClassNameAndObjectId(containerObj[0]); + containerClassName = containerData[0]; + containerObjectId = containerData[1]; + valueData = parseClassNameAndObjectId(valueObj[0]); + valueClassName = valueData[0]; + valueObjectId = valueData[1]; + thread = threads.get(threadId[0]); + lineNum = Integer.parseInt(lineData[0]); + time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + // �t�B�[���h�X�V�̐ݒ� + if (thread != null) thread.fieldUpdate(fieldData[0], valueClassName, valueObjectId, containerClassName, containerObjectId, lineNum, timeStamp); + } else if (line.startsWith("{\"type\":\"arrayCreate\"")) { + // �z�񐶐� + type = line.split(",\"array\":"); + arrayObj = type[1].split(",\"dimension\":"); + arrayData = parseClassNameAndObjectId(arrayObj[0]); + arrayClassName = arrayData[0]; + arrayObjectId = arrayData[1]; + dimensionData = arrayObj[1].split(",\"threadId\":"); + dimension = Integer.parseInt(dimensionData[0]); + threadId = dimensionData[1].split(",\"lineNum\":"); + thread = threads.get(threadId[0]); + lineData = threadId[1].split(",\"time\":"); + lineNum = Integer.parseInt(lineData[0]); + time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + if (thread != null) thread.arrayCreate(arrayClassName, arrayObjectId, dimension, lineNum, timeStamp); + } else if (line.startsWith("{\"type\":\"arraySet\"")) { + // �z��v�f�ւ̑�� + type = line.split(",\"array\":"); + arrayObj = type[1].split(",\"index\":"); + arrayData = parseClassNameAndObjectId(arrayObj[0]); + arrayClassName = arrayData[0]; + arrayObjectId = arrayData[1]; + indexData = arrayObj[1].split(",\"value\":"); + index = Integer.parseInt(indexData[0]); + valueObj = indexData[1].split(",\"threadId\":"); + valueData = parseClassNameAndObjectId(valueObj[0]); + valueClassName = valueData[0]; + valueObjectId = valueData[1]; + threadId = valueObj[1].split(",\"time\":"); + thread = threads.get(threadId[0]); + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + if (thread != null) thread.arraySet(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, 0, timeStamp); + } else if (line.startsWith("{\"type\":\"arrayGet\"")) { + // �z��v�f�̎Q�� + type = line.split(",\"array\":"); + arrayObj = type[1].split(",\"index\":"); + arrayData = parseClassNameAndObjectId(arrayObj[0]); + arrayClassName = arrayData[0]; + arrayObjectId = arrayData[1]; + indexData = arrayObj[1].split(",\"value\":"); + index = Integer.parseInt(indexData[0]); + valueObj = indexData[1].split(",\"threadId\":"); + valueData = parseClassNameAndObjectId(valueObj[0]); + valueClassName = valueData[0]; + valueObjectId = valueData[1]; + threadId = valueObj[1].split(",\"time\":"); + thread = threads.get(threadId[0]); + time = threadId[1].substring(0, threadId[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + if (thread != null) thread.arrayGet(arrayClassName, arrayObjectId, index, valueClassName, valueObjectId, 0, timeStamp); + } else if (line.startsWith("{\"type\":\"blockEntry\"")) { + // �u���b�N�̊J�n + type = line.split(",\"methodSignature\":\""); + signature = type[1].split("\",\"blockId\":"); + blockIdData = signature[1].split(",\"incomings\":"); + blockId = Integer.parseInt(blockIdData[0]); + incomingsData = blockIdData[1].split(",\"threadId\":"); + incomings = Integer.parseInt(incomingsData[0]); + threadId = incomingsData[1].split(",\"lineNum\":"); + thread = threads.get(threadId[0]); + lineData = threadId[1].split(",\"time\":"); + lineNum = Integer.parseInt(lineData[0]); + time = lineData[1].substring(0, lineData[1].length() - 2); // ������ }, ����菜�� + timeStamp = Long.parseLong(time); + if (thread != null) thread.blockEnter(blockId, incomings, lineNum, timeStamp); + } + } + } + + /** + * �N���X���ƃI�u�W�F�N�gID��\��JSON�I�u�W�F�N�g����ǂ��� + * @param classNameAndObjectIdJSON �g���[�X�t�@�C������JSON�I�u�W�F�N�g + * @return + */ + protected String[] parseClassNameAndObjectId(String classNameAndObjectIdJSON) { + // �擪�� {"class":" ��10�����Ɩ����� } ����菜���ĕ��� + return classNameAndObjectIdJSON.substring(10, classNameAndObjectIdJSON.length() - 1).split("\",\"id\":"); + } + + /** + * ������\��JSON�z�����ǂ��� + * @param arguments + * @return + */ + protected ArrayList parseArguments(String[] arguments) { + String[] argData; + argData = arguments[0].substring(1, arguments[0].length() - 1).split(","); // �擪�� [ �Ɩ����� ] ����菜�� + ArrayList argumentsData = new ArrayList(); + for (int k = 0; k < argData.length - 1; k += 2) { + argumentsData.add(new ObjectReference(argData[k+1].substring(5, argData[k+1].length() - 1), argData[k].substring(10, argData[k].length() - 1))); + } + return argumentsData; + } + + /** + * �I�����C����͗p�V���O���g���̎擾 + * @return �I�����C����͗p�g���[�X + */ + public static TraceJSON getInstance() { + if (theTrace == null) { + theTrace = new TraceJSON(); + } + return (TraceJSON)theTrace; + } + + /** + * �X���b�hID���w�肵�ăX���b�h�C���X�^���X���擾����(�I�����C����͗p) + * @param threadId + * @return �X���b�h�C���X�^���X + */ + public static ThreadInstance getThreadInstance(String threadId) { + return getInstance().threads.get(threadId); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾���� + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̃��\�b�h���s + */ + public static MethodExecution getCurrentMethodExecution(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentMethodExecution(); + } + + /** + * �w�肵���X���b�h��Ō��ݎ��s���̃g���[�X�|�C���g���擾���� + * @param thread �ΏۃX���b�h + * @return thread ��Ō��ݎ��s���̎��s���̃g���[�X�|�C���g + */ + public static TracePoint getCurrentTracePoint(Thread thread) { + ThreadInstance t = getInstance().threads.get(String.valueOf(thread.getId())); + return t.getCurrentTracePoint(); + } + + public void initializeClass(String name, String path, String loaderPath) { + classes.put(name, new ClassInfo(name, path, loaderPath)); + } + + public ClassInfo getClassInfo(String className) { + return classes.get(className); + } + + public TracePoint getArraySetTracePoint(final Reference ref, TracePoint before) { + final TracePoint start = before.duplicate(); + before = traverseStatementsInTraceBackward(new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { + if (statement instanceof ArrayUpdate) { + ArrayUpdate arraySet = (ArrayUpdate)start.getStatement(); + String srcObjId = ref.getSrcObjectId(); + String dstObjId = ref.getDstObjectId(); + String srcClassName = ref.getSrcClassName(); + String dstClassName = ref.getDstClassName(); + if ((srcObjId != null && srcObjId.equals(arraySet.getArrayObjectId())) + || (srcObjId == null || isNull(srcObjId)) && srcClassName.equals(arraySet.getArrayClassName())) { + if ((dstObjId != null && dstObjId.equals(arraySet.getValueObjectId())) + || ((dstObjId == null || isNull(dstObjId)) && dstClassName.equals(arraySet.getValueClassName()))) { + if (srcObjId == null) { + ref.setSrcObjectId(arraySet.getArrayObjectId()); + } else if (srcClassName == null) { + ref.setSrcClassName(arraySet.getArrayClassName()); + } + if (dstObjId == null) { + ref.setDstObjectId(arraySet.getValueObjectId()); + } else if (dstClassName == null) { + ref.setDstClassName(arraySet.getValueClassName()); + } + return true; + } + } + } + return false; + } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }, start); + if (before != null) { + return before; + } + return null; + } + + /** + * ���s���ꂽ�S�u���b�N���擾���� + * @return �S�u���b�N(���\�b�h��:�u���b�NID) + */ + public HashSet getAllBlocks() { + final HashSet blocks = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return blocks; + } + + /** + * �}�[�N���Ŏ��s���J�n���ꂽ�u���b�N���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y������u���b�N(���\�b�h��:�u���b�NID) + */ + public HashSet getMarkedBlocks(final long markStart, final long markEnd) { + final HashSet blocks = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� + if (methodExecution.getEntryTime() > markEnd) return false; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + long entryTime = ((BlockEnter)s).getTimeStamp(); + if (entryTime >= markStart && entryTime <= markEnd) { + blocks.add(methodExecution.getSignature() + ":" + ((BlockEnter)s).getBlockId()); + } + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return blocks; + } + + /** + * ���s���ꂽ�S�t���[���擾���� + * @return �S�t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) + */ + public HashSet getAllFlows() { + final HashSet flows = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + int prevBlockId = -1; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + int curBlockID = ((BlockEnter)s).getBlockId(); + if (prevBlockId != -1) { + flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); + } else { + flows.add(methodExecution.getSignature() + ":" + curBlockID); + } + prevBlockId = curBlockID; + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return flows; + } + + /** + * �}�[�N���Ŏ��s���ꂽ�t���[���擾���� + * @param markStart �}�[�N�̊J�n���� + * @param markEnd �}�[�N�̏I������ + * @return �Y������t���[(���\�b�h��:�t���[���u���b�NID:�t���[��u���b�NID) + */ + public HashSet getMarkedFlows(final long markStart, final long markEnd) { + final HashSet flows = new HashSet(); + Iterator threadsIterator = threads.keySet().iterator(); + for (; threadsIterator.hasNext();) { + ThreadInstance thread = threads.get(threadsIterator.next()); + thread.traverseMethodExecutionsBackward(new IMethodExecutionVisitor() { + @Override + public boolean preVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean postVisitThread(ThreadInstance thread) { + return false; + } + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < markStart) return true; // �T���I�� + if (methodExecution.getEntryTime() > markEnd) return false; + int prevBlockId = -1; + for (Statement s: methodExecution.getStatements()) { + if (s instanceof BlockEnter) { + long entryTime = ((BlockEnter)s).getTimeStamp(); + int curBlockID = ((BlockEnter)s).getBlockId(); + if (entryTime >= markStart && entryTime <= markEnd) { + if (prevBlockId != -1) { + flows.add(methodExecution.getSignature() + ":" + prevBlockId + ":" + curBlockID); + } else { + flows.add(methodExecution.getSignature() + ":" + curBlockID); + } + } + prevBlockId = curBlockID; + } + } + return false; + } + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + return false; + } + }); + } + return flows; + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���S���s�����t�����ɒT������ + * + * @param visitor ���s���̃r�W�^�[ + * @return ���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor) { + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + // �e�X���b�h�ɂ����Ĉ�ԍŌ�ɊJ�n�������\�b�h���s��T�� + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance thread = threads.get(threadId); + ArrayList roots = (ArrayList)thread.getRoot().clone(); + threadRoots.put(threadId, roots); + TracePoint threadLastTp; + do { + MethodExecution threadLastExecution = roots.remove(roots.size() - 1); + threadLastTp = threadLastExecution.getExitPoint(); + } while (!threadLastTp.isValid() && roots.size() > 0); + if (threadLastTp.isValid()) { + threadLastPoints.put(threadId, threadLastTp); + long threadLastTime; + if (threadLastTp.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = threadLastTp.getStatement().getTimeStamp(); + } + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } + } else { + threadLastPoints.put(threadId, null); + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ + * + * @param visitor�@���s���̃r�W�^�[ + * @param before �T���J�n�g���[�X�|�C���g + * @return�@���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, TracePoint before) { + if (before == null) { + return traverseStatementsInTraceBackward(visitor); + } + // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + ThreadInstance thread = threads.get(before.getStatement().getThreadNo()); + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + if (t == thread) { + traceLastThread = threadId; + threadLastPoints.put(threadId, before); + for (int n = rootExecutions.size() - 1; n >= 0; n--) { + MethodExecution root = rootExecutions.get(n); + if (root.getEntryTime() > before.getStatement().getTimeStamp()) { + rootExecutions.remove(n); + } else { + break; + } + } + if (rootExecutions.size() > 0) { + rootExecutions.remove(rootExecutions.size() - 1); + } + } else { + TracePoint threadBeforeTp; + do { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + threadBeforeTp = threadLastExecution.getExitPoint(); + } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); + if (threadBeforeTp.isValid()) { + TracePoint[] tp = new TracePoint[] {threadBeforeTp}; + long threadLastTime; + if (before.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) before.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = before.getStatement().getTimeStamp(); + } + getLastStatementInThread(rootExecutions, tp, threadLastTime, new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { return false; } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }); + threadLastPoints.put(threadId, tp[0]); + if (tp[0] != null) { + if (tp[0].getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? + } else { + threadLastTime = tp[0].getStatement().getTimeStamp(); + } + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } else { + threadLastPoints.put(threadId, null); + } + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + /** + * �g���[�X���̑S�X���b�h�𓯊������Ȃ���w�肵���g���[�X�|�C���g����t�����ɒT������ + * + * @param visitor�@���s���̃r�W�^�[ + * @param before �T���J�n���� + * @return�@���f�����g���[�X�|�C���g + */ + public TracePoint traverseStatementsInTraceBackward(IStatementVisitor visitor, long before) { + if (before <= 0L) { + return traverseStatementsInTraceBackward(visitor); + } + // �S�ẴX���b�h�̃g���[�X�|�C���g�� before �̑O�܂Ŋ����߂� + HashMap> threadRoots = new HashMap>(); + HashMap threadLastPoints = new HashMap(); + long traceLastTime = 0; + String traceLastThread = null; + long traceLastTime2 = 0; + String traceLastThread2 = null; + for (String threadId: threads.keySet()) { + ThreadInstance t = threads.get(threadId); + ArrayList rootExecutions = (ArrayList)t.getRoot().clone(); + threadRoots.put(threadId, rootExecutions); + TracePoint threadBeforeTp; + do { + MethodExecution threadLastExecution = rootExecutions.remove(rootExecutions.size() - 1); + threadBeforeTp = threadLastExecution.getExitPoint(); + } while (!threadBeforeTp.isValid() && rootExecutions.size() > 0); + if (threadBeforeTp.isValid()) { + TracePoint[] tp = new TracePoint[] {threadBeforeTp}; + getLastStatementInThread(rootExecutions, tp, before, new IStatementVisitor() { + @Override + public boolean preVisitStatement(Statement statement) { return false; } + @Override + public boolean postVisitStatement(Statement statement) { return false; } + }); + threadLastPoints.put(threadId, tp[0]); + if (tp[0] != null) { + long threadLastTime; + if (tp[0].getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) tp[0].getStatement()).getCalledMethodExecution().getExitTime(); // ��Exception �����������ꍇ�͍l���Ȃ��Ă悢? + } else { + threadLastTime = tp[0].getStatement().getTimeStamp(); + } + if (traceLastTime < threadLastTime) { + traceLastTime2 = traceLastTime; + traceLastThread2 = traceLastThread; + traceLastTime = threadLastTime; + traceLastThread = threadId; + } + } + } else { + threadLastPoints.put(threadId, null); + } + } + return traverseStatementsInTraceBackwardSub(visitor, threadRoots, threadLastPoints, traceLastThread, traceLastThread2, traceLastTime2); + } + + private TracePoint traverseStatementsInTraceBackwardSub(IStatementVisitor visitor, + HashMap> threadRoots, + HashMap threadLastPoints, + String traceLastThread, String traceLastThread2, long traceLastTime2) { + // �S�X���b�h�̓������Ƃ�Ȃ���t�����Ɏ��s����T������ + for (;;) { + // �T���Ώۂ̃X���b�h���̋t�����T�� + TracePoint lastTp = threadLastPoints.get(traceLastThread); + while (lastTp != null) { + Statement statement = lastTp.getStatement(); + if (visitor.preVisitStatement(statement)) return lastTp; + if (statement instanceof MethodInvocation) { + // �Ăяo���悪����ꍇ�A�Ăяo����ɐ��� + lastTp.stepBackNoReturn(); + if (lastTp.isValid()) { + // ���ʂɌĂяo����Ɉڂ����ꍇ + MethodExecution methodExecution = ((MethodInvocation) statement).getCalledMethodExecution(); + if (!methodExecution.isTerminated() && methodExecution.getExitTime() < traceLastTime2) { + break; + } + continue; + } + // ��̃��\�b�h���s�̏ꍇ + } else { + if (visitor.postVisitStatement(statement)) return lastTp; + } + if (lastTp.isValid() && lastTp.getStatement().getTimeStamp() < traceLastTime2) break; + // 1�X�e�b�v�����߂� + while (!lastTp.stepBackOver() && lastTp.isValid()) { + // �Ăяo�����ɖ߂����ꍇ(���\�b�h�Ăяo�����ɕ��A) + statement = lastTp.getStatement(); + if (visitor.postVisitStatement(statement)) return lastTp; + } + if (!lastTp.isValid()) { + // �Ăяo���؂̊J�n���_�܂ŒT�����I�����ꍇ + ArrayList roots = threadRoots.get(traceLastThread); + while (!lastTp.isValid() && roots.size() > 0) { + // ���̌Ăяo���؂�T�� + MethodExecution lastExecution = roots.remove(roots.size() - 1); + lastTp = lastExecution.getExitPoint(); + } + if (lastTp.isValid()) { + // ���̌Ăяo���؂�����΂�����Ōォ��T�� + threadLastPoints.put(traceLastThread, lastTp); + if (lastTp.getStatement().getTimeStamp() < traceLastTime2) break; + } else { + // ���̃X���b�h�̒T�������ׂďI�������ꍇ + threadLastPoints.put(traceLastThread, null); + break; + } + } + } + traceLastThread = traceLastThread2; + // ���̎��ɒT�����ׂ��X���b�h(���T���̗̈悪��ԍŌ�܂Ŏc���Ă���X���b�h)�����肷�� + traceLastTime2 = 0; + traceLastThread2 = null; + boolean continueTraverse = false; + for (String threadId: threadLastPoints.keySet()) { + if (!threadId.equals(traceLastThread)) { + TracePoint threadLastTp = threadLastPoints.get(threadId); + if (threadLastTp != null) { + continueTraverse = true; + long threadLastTime; + if (threadLastTp.getStatement() instanceof MethodInvocation) { + threadLastTime = ((MethodInvocation) threadLastTp.getStatement()).getCalledMethodExecution().getExitTime(); + } else { + threadLastTime = threadLastTp.getStatement().getTimeStamp(); + } + if (traceLastTime2 < threadLastTime) { + traceLastTime2 = threadLastTime; + traceLastThread2 = threadId; + } + } + } + } + if (traceLastThread == null && traceLastThread2 == null) break; + if (!continueTraverse && threadLastPoints.get(traceLastThread) == null) break; + } + return null; + } +} \ No newline at end of file diff --git a/src/org/ntlab/trace/TracePoint.java b/src/org/ntlab/trace/TracePoint.java new file mode 100644 index 0000000..75b6f06 --- /dev/null +++ b/src/org/ntlab/trace/TracePoint.java @@ -0,0 +1,175 @@ +package org.ntlab.trace; + +import java.util.ArrayList; + +public class TracePoint { + private MethodExecution methodExecution; + private int order = 0; + + public TracePoint(MethodExecution methodExecution, int order) { + this.methodExecution = methodExecution; + this.order = order; + } + + public TracePoint duplicate() { + return new TracePoint(methodExecution, order); + } + + public Statement getStatement() { + return methodExecution.getStatements().get(order); + } + + public MethodExecution getMethodExecution() { + return methodExecution; + } + + public ArrayList getPreviouslyCalledMethods() { + ArrayList children = new ArrayList(); + ArrayList statements = methodExecution.getStatements(); + for (int i = 0; i < order; i++) { + Statement statement = statements.get(i); + if (statement instanceof MethodInvocation) { + MethodExecution child = ((MethodInvocation)statement).getCalledMethodExecution(); + children.add(child); + } + } + return children; + } + + /** + * �������̑S�T��(�������A���s�����L�^����Ă��Ȃ����\�b�h���s�ɂ͐���Ȃ�) + * @return false: ����ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepFull() { + if (getStatement() instanceof MethodInvocation) { + MethodExecution calledMethodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution(); + if (calledMethodExecution.getStatements().size() > 0) { + methodExecution = calledMethodExecution; + order = 0; + return true; + } + } + while (order >= methodExecution.getStatements().size() - 1) { + order = methodExecution.getCallerStatementExecution(); + methodExecution = methodExecution.getCallerMethodExecution(); + if (methodExecution == null) { + order = -1; + return false; + } + } + order++; + return true; + } + + /** + * �t�����̑S�T��(�������A���s�����L�^����Ă��Ȃ����\�b�h���s�ɂ͐���Ȃ��B�܂��A�Ăяo����̃��\�b�h���s����T��������ɁA�Ăяo�����̃��\�b�h�Ăяo������K�₷��̂Œ���!!) + * @return false: ����ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepBackFull() { + if (order <= 0) { + order = methodExecution.getCallerStatementExecution(); + methodExecution = methodExecution.getCallerMethodExecution(); + if (methodExecution == null) { + order = -1; + return false; + } + return true; + } + order--; + while (getStatement() instanceof MethodInvocation) { + MethodExecution calledMethodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution(); + if (calledMethodExecution.getStatements().size() == 0) break; + methodExecution = calledMethodExecution; + order = methodExecution.getStatements().size() - 1; + } + return true; + } + + /** + * �������ɒT������B�Ăяo�����ɖ߂邪�Ăяo����ɂ͐���Ȃ��B + * @return false: �Ăяo�����ɖ߂����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepOver() { + if (order < methodExecution.getStatements().size() - 1) { + order++; + return true; + } + order = methodExecution.getCallerStatementExecution(); + methodExecution = methodExecution.getCallerMethodExecution(); + if (methodExecution == null) { + order = -1; + return false; + } + return false; + } + + /** + * �t�����ɒT������B�Ăяo�����ɖ߂邪�Ăяo����ɂ͐���Ȃ��B + * @return false: �Ăяo�����ɖ߂����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepBackOver() { + if (order > 0) { + order--; + return true; + } + order = methodExecution.getCallerStatementExecution(); + methodExecution = methodExecution.getCallerMethodExecution(); + if (methodExecution == null) { + order = -1; + return false; + } + return false; + } + + /** + * �������ɒT������B�Ăяo�����H�邪�Ăяo�����ɂ͖߂�Ȃ��B + * @return false: �Ăяo����Ɉڂ����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepNoReturn() { + if (getStatement() instanceof MethodInvocation) { + methodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution(); + if (methodExecution.getStatements().size() > 0) { + order = 0; + } else { + order = -1; // �Ăяo����Ŏ��s�����L�^����Ă��Ȃ��ꍇ + } + return false; + } + order++; + if (order < methodExecution.getStatements().size()) { + return true; + } + return false; + } + + /** + * �t�����ɒT������B�Ăяo�����H�邪�Ăяo�����ɂ͖߂�Ȃ��B(��ɌĂяo�����̃��\�b�h�Ăяo������K�₵�Ă���Ăяo����̃��\�b�h���s��K�₷��̂Œ���!!) + * @return�@false: �Ăяo����Ɉڂ����ꍇ�܂��͂���ȏ�H��Ȃ��ꍇ, true: ����ȊO + */ + public boolean stepBackNoReturn() { + if (getStatement() instanceof MethodInvocation) { + methodExecution = ((MethodInvocation)getStatement()).getCalledMethodExecution(); + order = methodExecution.getStatements().size() - 1; // -1 �ɂȂ�ꍇ������(�Ăяo����Ŏ��s�����L�^����Ă��Ȃ��ꍇ) + return false; + } + order--; + if (order >= 0) { + return true; + } + return false; + } + + public boolean isValid() { + if (methodExecution == null || order == -1 || order >= methodExecution.getStatements().size()) return false; + return true; + } + + public boolean isMethodEntry() { + return (order == 0); + } + + public boolean isStepBackOut() { + if (order < 0) return true; + return false; + } +} diff --git a/src/org/ntlab/traceanalyzer/Activator.java b/src/org/ntlab/traceanalyzer/Activator.java new file mode 100644 index 0000000..005596a --- /dev/null +++ b/src/org/ntlab/traceanalyzer/Activator.java @@ -0,0 +1,102 @@ +package org.ntlab.traceanalyzer; + +import java.util.Hashtable; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +public class Activator extends AbstractUIPlugin implements BundleActivator, ServiceListener { + + public static final String PLUGIN_ID = "org.ntlab.traceAnalyzer"; //$NON-NLS-1$ + + private DictionaryService service; + private ServiceTracker dictionaryServiceTracker; + private BundleContext fContext; + + private static Activator plugin; + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + fContext = context; + service = new DictionaryServiceImpl(); + + Hashtable props = new Hashtable(); + // register the service + context.registerService(DictionaryService.class.getName(), service, props); + + // create a tracker and track the service + dictionaryServiceTracker = new ServiceTracker(context, DictionaryService.class.getName(), null); + dictionaryServiceTracker.open(); + + // have a service listener to implement the whiteboard pattern + fContext.addServiceListener(this, "(objectclass=" + Dictionary.class.getName() + ")"); + + // grab the service + service = (DictionaryService) dictionaryServiceTracker.getService(); + + // register the dictionary + service.registerDictionary(new DictionaryImpl()); + + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + // close the service tracker + dictionaryServiceTracker.close(); + dictionaryServiceTracker = null; + + service = null; + fContext = null; + plugin = null; + } + + public void serviceChanged(ServiceEvent ev) { + ServiceReference sr = ev.getServiceReference(); + switch(ev.getType()) { + case ServiceEvent.REGISTERED: + { + Dictionary dictionary = (Dictionary) fContext.getService(sr); + service.registerDictionary(dictionary); + } + break; + case ServiceEvent.UNREGISTERING: + { + Dictionary dictionary = (Dictionary) fContext.getService(sr); + service.unregisterDictionary(dictionary); + } + break; + } + } + + public static Activator getDefault() { + return plugin; + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + reg.put("TraceAnalyzer.STACK_FRAME_IMAGE", getImageDescriptor("/icons/full/stckframe_obj.gif")); + reg.put("TraceAnalyzer.STACK_FRAME_IMAGE2", getImageDescriptor("/icons/full/stckframe_obj2.gif")); + reg.put("TraceAnalyzer.STACK_FRAME_IMAGE3", getImageDescriptor("/icons/full/stckframe_obj3.gif")); + reg.put("TraceAnalyzer.THREAD_IMAGE", getImageDescriptor("/icons/full/threads_obj.gif")); + reg.put("TraceAnalyzer.THREAD_IMAGE2", getImageDescriptor("/icons/full/threads_obj2.gif")); + reg.put("TraceAnalyzer.HIGHLIGHT_UNIQUE_IMAGE", getImageDescriptor("/icons/full/read_obj.gif")); + } + + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java b/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java new file mode 100644 index 0000000..18d3e5e --- /dev/null +++ b/src/org/ntlab/traceanalyzer/CallTreeContentProvider.java @@ -0,0 +1,35 @@ +package org.ntlab.traceanalyzer; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class CallTreeContentProvider implements ITreeContentProvider { + + public Object[] getChildren(Object parentElement) { + Object[] children = null; + if (parentElement instanceof MarkedThread) { + children = ((MarkedThread)parentElement).getChildren().toArray(); + } else { + children = ((MarkedMethodExecution)parentElement).getChildren().toArray(); + } + return children==null ? new Object[0] : children; + } + + public Object getParent(Object element) { + return ((MarkedMethodExecution)element).getParent(); + } + + public boolean hasChildren(Object element) { + return getChildren(element).length == 0 ? false : true; + } + + public Object[] getElements(Object inputElement) { + return ((MarkedTrace)inputElement).getMarkedThreads().toArray(); + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } +} diff --git a/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java b/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java new file mode 100644 index 0000000..7fa2e26 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/CallTreeLabelProvider.java @@ -0,0 +1,55 @@ +package org.ntlab.traceanalyzer; + +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +public class CallTreeLabelProvider extends LabelProvider { + public Image getImage(Object element) { + if (element instanceof MarkedMethodExecution){ + int uniqueness = ((MarkedMethodExecution)element).isUniqueMethodInvokedFrom(); + ImageRegistry registry = Activator.getDefault().getImageRegistry(); + Image image; + switch (uniqueness) { + case 1: + image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE2"); + break; + case 2: + image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE3"); + break; + case 0: + default: + image = registry.get("TraceAnalyzer.STACK_FRAME_IMAGE"); + } + return image; + } else if(element instanceof MarkedThread){ + int uniqueness = ((MarkedThread)element).isUniqueMethodInvokedFrom(); + ImageRegistry registry = Activator.getDefault().getImageRegistry(); + Image image; + switch (uniqueness) { + case 1: + image = registry.get("TraceAnalyzer.THREAD_IMAGE2"); + break; + case 0: + default: + image = registry.get("TraceAnalyzer.THREAD_IMAGE"); + } + return image; + } else { + return null; + } + } + + public String getText(Object element) { + String name = null; + if (element instanceof MarkedMethodExecution){ + MarkedMethodExecution method = (MarkedMethodExecution)element; + name = method.getSignature(); + } else if (element instanceof MarkedThread){ + name = ((MarkedThread)element).getId(); + } + return name; + } +} diff --git a/src/org/ntlab/traceanalyzer/CallTreeView.java b/src/org/ntlab/traceanalyzer/CallTreeView.java new file mode 100644 index 0000000..a2359a6 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/CallTreeView.java @@ -0,0 +1,258 @@ +package org.ntlab.traceanalyzer; + +import java.io.File; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; +import org.ntlab.trace.ClassInfo; +import org.ntlab.trace.Trace; + +public class CallTreeView extends ViewPart { + private TreeViewer viewer; + private IAction openAction; + private IAction markAction; + private IAction highlightAction; + private MarkedTrace markedTrace; + private Shell shell; + + @Override + public void createPartControl(Composite parent) { + shell = parent.getShell(); + viewer = new TreeViewer(parent); + viewer.setContentProvider(new CallTreeContentProvider()); + viewer.setLabelProvider(new CallTreeLabelProvider()); + viewer.setInput(null); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel = (IStructuredSelection)event.getSelection(); + Object element = sel.getFirstElement(); + if (element instanceof MarkedMethodExecution) { + String className = ((MarkedMethodExecution)element).getDeclaringClassName(); + String methodSignature = ((MarkedMethodExecution)element).getSignature(); + ClassInfo classInfo = markedTrace.getClassInfo(className); + if (classInfo == null) { + className = ((MarkedMethodExecution)element).getReceiverClassName(); + classInfo = markedTrace.getClassInfo(className); + } + if (classInfo != null) { + String projectPath = classInfo.getLoaderPath(); + IJavaProject javaProject = findJavaProject(projectPath); + if (javaProject != null) { + openInJavaEditor(javaProject, className, methodSignature); + } + } + } + } + }); + getSite().setSelectionProvider(viewer); + createActions(); + createToolBar(); + createMenuBar(); + } + + /** �A�N�V�������쐬 */ + private void createActions(){ + // �g���[�X�t�@�C�����J���A�N�V�������쐬 + ImageDescriptor openIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER); + openAction = new Action("Open Trace File...", openIcon){ + public void run(){ + // �g���[�X�o�͐�Q�ƃE�B�U�[�h + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + dialog.setText("Open Trace File"); + dialog.setFilterExtensions(new String[]{"*.*"}); + String path = dialog.open(); + if (path == null) { + return; + } + markedTrace = new MarkedTrace(path); + viewer.setInput(markedTrace); + viewer.refresh(); + highlightAction.setChecked(false); + } + }; + + // �g���[�X�Ƀ}�[�N����A�N�V�������쐬 + ImageDescriptor markIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OPEN_MARKER); + markAction = new Action("Mark Trace...", markIcon){ + public void run(){ + final Shell traceMarkShell = new Shell(SWT.TITLE | SWT.ON_TOP | SWT.CLOSE); // �}�[�N�w���� + traceMarkShell.setText("Mark Trace"); + traceMarkShell.setSize(250, 150); + traceMarkShell.setLayout(new FormLayout()); + + // �J�n����(���x��) + Label startTimeLabel = new Label(traceMarkShell, SWT.NULL); + startTimeLabel.setText("Start Time:"); + FormData startTimeLabelForm = new FormData(); + startTimeLabelForm.top = new FormAttachment(10, 5); + startTimeLabelForm.left = new FormAttachment(5, 5); + startTimeLabel.setLayoutData(startTimeLabelForm); + + // �J�n����(�e�L�X�g�{�b�N�X) + final Text startTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP); + startTimeText.setText(Long.toString(markedTrace.getMarkStart())); + FormData startTimeTextForm = new FormData(); + startTimeTextForm.top = new FormAttachment(10, 5); + startTimeTextForm.left = new FormAttachment(35, 10); + startTimeTextForm.right = new FormAttachment(95, -5); + startTimeText.setLayoutData(startTimeTextForm); + + // �I������(���x��) + Label endTimeLabel = new Label(traceMarkShell, SWT.NULL); + endTimeLabel.setText("End Time:"); + FormData endTimeLabelForm = new FormData(); + endTimeLabelForm.top = new FormAttachment(30, 5); + endTimeLabelForm.left = new FormAttachment(5, 5); + endTimeLabel.setLayoutData(endTimeLabelForm); + + // �I�����ԓ���(�e�L�X�g�{�b�N�X) + final Text endTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP); + endTimeText.setText(Long.toString(markedTrace.getMarkEnd())); + FormData endTimeTextForm = new FormData(); + endTimeTextForm.top = new FormAttachment(30, 5); + endTimeTextForm.left = new FormAttachment(35, 10); + endTimeTextForm.right = new FormAttachment(95, -5); + endTimeText.setLayoutData(endTimeTextForm); + + //OK�{�^�� + Button okButton = new Button(traceMarkShell, SWT.PUSH); + okButton.setText("OK"); + FormData okButtonForm = new FormData(); + okButtonForm.bottom = new FormAttachment(100, -5); + okButtonForm.right = new FormAttachment(95, -5); + okButton.setLayoutData(okButtonForm); + okButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e){ + if (markedTrace != null) { + String startText = startTimeText.getText(); + String endText = endTimeText.getText(); + try { + long start = Long.parseLong(startText); + long end = Long.parseLong(endText); + traceMarkShell.close(); + markedTrace.mark(start, end); + viewer.setInput(markedTrace); + viewer.refresh(); + highlightAction.setChecked(false); + } catch (NumberFormatException ex) { + } + } else { + traceMarkShell.close(); + } + } + }); + + traceMarkShell.open(); + } + }; + + // �}�[�N�ŗL�̃��\�b�h����������A�N�V�������쐬 + ImageRegistry registry = Activator.getDefault().getImageRegistry(); + ImageDescriptor highlightIcon = registry.getDescriptor("TraceAnalyzer.HIGHLIGHT_UNIQUE_IMAGE"); + highlightAction = new Action("Highlight Unique Methods", Action.AS_CHECK_BOX){ + public void run(){ + if (markedTrace != null) { + if (isChecked()) { + markedTrace.setHighlightUniqueMethods(true); + viewer.setInput(markedTrace); + viewer.refresh(); + } else { + markedTrace.setHighlightUniqueMethods(false); + viewer.setInput(markedTrace); + viewer.refresh(); + } + } + } + }; + highlightAction.setImageDescriptor(highlightIcon); + } + + /** �c�[���o�[�ɃA�N�V������lj� */ + private void createToolBar(){ + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(openAction); + mgr.add(markAction); + mgr.add(highlightAction); + } + + /** ���j���[�o�[�ɃA�N�V������lj� */ + private void createMenuBar(){ + IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + mgr.add(openAction); + mgr.add(markAction); + } + + public void setFocus() { + viewer.getTree().setFocus(); + } + + private IJavaProject findJavaProject(String projectPath) { + IJavaProject javaProject = null; + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject[] projects = root.getProjects(); + for (IProject project: projects) { + if (projectPath.startsWith(project.getLocation().toString())) { + javaProject = JavaCore.create(project); + break; + } + } + return javaProject; + } + + private void openInJavaEditor(IJavaProject javaProject, String className, String methodSignature) { + try { + IType type = javaProject.findType(className); + if (type != null) { + IEditorPart editor = JavaUI.openInEditor(type); + if (!type.isLocal() && !type.isMember()) { + for (IMethod method: type.getMethods()) { + if (methodSignature.contains(method.getElementName())) { + JavaUI.revealInEditor(editor, (IJavaElement)method); + } + } + } + } + } catch (PartInitException | JavaModelException e) { + e.printStackTrace(); + } + } +} diff --git a/src/org/ntlab/traceanalyzer/Dictionary.java b/src/org/ntlab/traceanalyzer/Dictionary.java new file mode 100644 index 0000000..a572138 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/Dictionary.java @@ -0,0 +1,21 @@ +package org.ntlab.traceanalyzer; + +public interface Dictionary { + + /** + * Returns the language of the dictionary + * + * @return the language of the dictionary + */ + public String getLanguage(); + + /** + * Check for the existence of a word in the dictionary + * + * @param word the word to be checked. + * @return true if the word is in the dictionary + */ + public boolean check(String word); + + +} diff --git a/src/org/ntlab/traceanalyzer/DictionaryImpl.java b/src/org/ntlab/traceanalyzer/DictionaryImpl.java new file mode 100644 index 0000000..0dacb97 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/DictionaryImpl.java @@ -0,0 +1,24 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DictionaryImpl implements Dictionary { + + private List fWords = new ArrayList(Arrays.asList("osgi", "eclipse", "equinox")); + private String fLanguage = "en_US"; + + public String getLanguage() { + return fLanguage; + } + + public boolean check(String word) { + return fWords.contains(word); + } + + public String toString() { + return fLanguage; + } + +} diff --git a/src/org/ntlab/traceanalyzer/DictionaryService.java b/src/org/ntlab/traceanalyzer/DictionaryService.java new file mode 100644 index 0000000..9c67972 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/DictionaryService.java @@ -0,0 +1,28 @@ +package org.ntlab.traceanalyzer; + +public interface DictionaryService { + + /** + * Register a dictionary + * + * @param dictionary the dictionary to be added. + */ + public void registerDictionary(Dictionary dictionary); + + /** + * Remove a dictionary + * + * @param dictionary the dictionary to be removed. + */ + public void unregisterDictionary(Dictionary dictionary); + + /** + * Check for the existence of a word across all dictionaries + * + * @param word the word to be checked. + * @return true if the word is in any dictionary + */ + public boolean check(String word); + + +} diff --git a/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java b/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java new file mode 100644 index 0000000..f3e6469 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/DictionaryServiceImpl.java @@ -0,0 +1,28 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DictionaryServiceImpl implements DictionaryService { + + private List fDictionaries = new ArrayList(); + + public void registerDictionary(Dictionary dictionary) { + fDictionaries.add(dictionary); + } + + public void unregisterDictionary(Dictionary dictionary) { + fDictionaries.remove(dictionary); + } + + public boolean check(String word) { + for (int i = 0; i < fDictionaries.size(); i++ ) { + Dictionary dictionary = (Dictionary) fDictionaries.get(i); + if(dictionary.check(word)) + return true; + } + return false; + } + +} diff --git a/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java b/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java new file mode 100644 index 0000000..3badae6 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/MarkedMethodExecution.java @@ -0,0 +1,91 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.HashSet; + +import org.ntlab.trace.MethodExecution; + +public class MarkedMethodExecution { + private MethodExecution methodExecution; + private ArrayList children = null; + private int uniqueMethodInvokedFrom = 0; + + public MarkedMethodExecution(MethodExecution methodExecution) { + this.methodExecution = methodExecution; + } + + public void addChild(MarkedMethodExecution child) { + if (children == null) { + children = new ArrayList(); + } + children.add(child); + } + + public ArrayList getChildren() { + if (children == null) { + ArrayList rawChildren = methodExecution.getChildren(); + children = new ArrayList(); + for (int i = 0; i < rawChildren.size(); i++) { + children.add(0, new MarkedMethodExecution(rawChildren.get(i))); + } + } + return children; + } + + public Object getParent() { + return methodExecution.getParent(); + } + + public String getSignature() { + return methodExecution.getSignature(); + } + + public String getDeclaringClassName() { + return methodExecution.getDeclaringClassName(); + } + + public String getReceiverClassName() { + return methodExecution.getThisClassName(); + } + + /** + * �}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ���ǂ����𒲂ׂ� + * @param commonMethodSignatures �}�[�N�O�ŌĂяo���ꂽ�S���\�b�h�̃V�O�j�`�� + */ + public int searchUniqueMethodInvocation(HashSet commonMethodSignatures) { + if (uniqueMethodInvokedFrom > 0) return uniqueMethodInvokedFrom; + if (isUniqueMethod(commonMethodSignatures)) uniqueMethodInvokedFrom = 2; + ArrayList children = getChildren(); + for (int i = 0; i < children.size(); i++) { + int u = children.get(i).searchUniqueMethodInvocation(commonMethodSignatures); + if (uniqueMethodInvokedFrom == 0 && u > 0) uniqueMethodInvokedFrom = 1; + } + return uniqueMethodInvokedFrom; + } + + /** + * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾���� + * @param commonMethodSignatures �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h�̃V�O�j�`�� + * @return ���̃��\�b�h���s�ȉ��̃}�[�N�ŗL�̑S���\�b�h���s + */ + public void getUniqueMethodExecutions(HashSet commonMethodSignatures, ArrayList uniqueMethodExecutions) { + if (isUniqueMethod(commonMethodSignatures)) { + uniqueMethodExecutions.add(this); + } + for (int n = 0; n < children.size(); n++) { + children.get(n).getUniqueMethodExecutions(commonMethodSignatures, uniqueMethodExecutions); + } + } + + /** + * ���̃��\�b�h���s����}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ��? + * @return 0: �Ăяo����Ă��Ȃ�, 1: �Ăяo���ꂽ, 2: �������g���}�[�N�ŗL���\�b�h + */ + public int isUniqueMethodInvokedFrom() { + return uniqueMethodInvokedFrom; + } + + private boolean isUniqueMethod(HashSet commonMethodSignatures) { + return !commonMethodSignatures.contains(getSignature()); + } +} diff --git a/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java b/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java new file mode 100644 index 0000000..046b4e3 --- /dev/null +++ b/src/org/ntlab/traceanalyzer/MarkedMethodExecutionVisitor.java @@ -0,0 +1,51 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.Stack; + +import org.ntlab.trace.IMethodExecutionVisitor; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.ThreadInstance; + +public class MarkedMethodExecutionVisitor implements IMethodExecutionVisitor { + private ArrayList markedThreads = new ArrayList(); + private ArrayList topMethodExecutions = null; + private Stack callStack = new Stack(); + + @Override + public boolean preVisitThread(ThreadInstance thread) { + topMethodExecutions = new ArrayList(); + return false; + } + + @Override + public boolean postVisitThread(ThreadInstance thread) { + if (topMethodExecutions.size() > 0) markedThreads.add(new MarkedThread(thread.getId(), topMethodExecutions)); + return false; + } + + @Override + public boolean preVisitMethodExecution(MethodExecution methodExecution) { + MarkedMethodExecution child = new MarkedMethodExecution(methodExecution); + if (!callStack.isEmpty()) { + MarkedMethodExecution parent = callStack.peek(); + parent.addChild(child); + } + callStack.push(child); + return false; + } + + @Override + public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList children) { + MarkedMethodExecution markedMethodExecution = callStack.pop(); + if (callStack.isEmpty()) { + topMethodExecutions.add(markedMethodExecution); + } + return false; + } + + public ArrayList getMarkedThreads() { + return markedThreads; + } + +} diff --git a/src/org/ntlab/traceanalyzer/MarkedThread.java b/src/org/ntlab/traceanalyzer/MarkedThread.java new file mode 100644 index 0000000..68d380e --- /dev/null +++ b/src/org/ntlab/traceanalyzer/MarkedThread.java @@ -0,0 +1,56 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.HashSet; + +public class MarkedThread { + private String id; + private ArrayList methodExecutions; + private int uniqueMethodInvokedFrom = 0; + + public MarkedThread(String id, ArrayList methodExecutions) { + this.id = id; + this.methodExecutions = methodExecutions; + } + + public String getId() { + return id; + } + + public ArrayList getChildren() { + return methodExecutions; + } + + /** + * �}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ���ǂ����𒲂ׂ� + * @param commonMethodSignatures �}�[�N�O�ŌĂяo���ꂽ�S���\�b�h�̃V�O�j�`�� + */ + public void searchUniqueMethodInvocation(HashSet commonMethodSignatures) { + if (uniqueMethodInvokedFrom > 0) return; + for (int i = 0; i < methodExecutions.size(); i++) { + int h = methodExecutions.get(i).searchUniqueMethodInvocation(commonMethodSignatures); + if (h > 0) uniqueMethodInvokedFrom = 1; + } + } + + /** + * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾���� + * @param unmarkedMethodSignatures �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h�̃V�O�j�`�� + * @return ���̃X���b�h���̃}�[�N�ŗL�̑S���\�b�h���s + */ + public ArrayList getUniqueMethodExecutions(HashSet unmarkedMethodSignatures) { + ArrayList uniqueMethodExecutions = new ArrayList(); + for (int i = 0; i < methodExecutions.size(); i++) { + methodExecutions.get(i).getUniqueMethodExecutions(unmarkedMethodSignatures, uniqueMethodExecutions); + } + return null; + } + + /** + * ���̃X���b�h����}�[�N�ŗL�̃��\�b�h���Ăяo���ꂽ��? + * @return 0: �Ăяo����Ă��Ȃ�, 1: �Ăяo���ꂽ + */ + public int isUniqueMethodInvokedFrom() { + return uniqueMethodInvokedFrom; + } +} diff --git a/src/org/ntlab/traceanalyzer/MarkedTrace.java b/src/org/ntlab/traceanalyzer/MarkedTrace.java new file mode 100644 index 0000000..8aa6c5a --- /dev/null +++ b/src/org/ntlab/traceanalyzer/MarkedTrace.java @@ -0,0 +1,126 @@ +package org.ntlab.traceanalyzer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; + +import org.ntlab.trace.ClassInfo; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.ThreadInstance; +import org.ntlab.trace.Trace; +import org.ntlab.trace.TraceJSON; + +public class MarkedTrace { + private Trace trace; + private long markStart = -1L; + private long markEnd = -1L; + private ArrayList markedThreads = null; + private boolean bHighlightUniqueMethods = false; + /** + * �}�[�N�O�Ŏ��s���ꂽ�S���\�b�h���s + */ + private HashSet unmarkedMethodSignatures = null; + + public MarkedTrace(String traceFilePath) { + this.trace = new TraceJSON(traceFilePath); + markFull(); + } + + public void setTrace(Trace trace) { + this.trace = trace; + markFull(); + } + + public ClassInfo getClassInfo(String className) { + if (trace instanceof TraceJSON) { + return ((TraceJSON)trace).getClassInfo(className); + } + return null; + } + + public void markFull() { + Collection threads = trace.getAllThreads().values(); + long start = -1L; + long end = -1L; + for (ThreadInstance thread: threads) { + ArrayList roots = thread.getRoot(); + for (MethodExecution m: roots) { + if (start == -1L || m.getEntryTime() < start) { + start = m.getEntryTime(); + } + if (end == -1L || m.getExitTime() > end) { + end = m.getExitTime(); // JSON�g���[�X�̂ݑΉ� + } + } + } + if (end < start) { + end = start + 1; + } + mark(start, end); + } + + public void mark(long start, long end) { + this.markStart = start; + this.markEnd = end; + updateMarkedThreads(); + } + + public long getMarkStart() { + return markStart; + } + + public long getMarkEnd() { + return markEnd; + } + + public ArrayList getMarkedThreads() { + if (markedThreads == null) { + updateMarkedThreads(); + } + return markedThreads; + } + + private void updateMarkedThreads() { + MarkedMethodExecutionVisitor visitor = new MarkedMethodExecutionVisitor(); + trace.traverseMarkedMethodExecutions(visitor, markStart, markEnd); + markedThreads = visitor.getMarkedThreads(); + } + + /** + * �}�[�N�ŗL�̃��\�b�h���������� + * @param bHighlightUniqueMethods �}�[�N�ŗL�̃��\�b�h���������邩? + */ + public void setHighlightUniqueMethods(boolean bHighlightUniqueMethods) { + this.bHighlightUniqueMethods = bHighlightUniqueMethods; + if (bHighlightUniqueMethods) { + if (unmarkedMethodSignatures == null) unmarkedMethodSignatures = trace.getUnmarkedMethodSignatures(markStart, markEnd); + for (int i = 0; i < markedThreads.size(); i++) { + markedThreads.get(i).searchUniqueMethodInvocation(unmarkedMethodSignatures); + } + } + } + + /** + * �}�[�N�ŗL�̃��\�b�h���������Ă��邩? + * @return + */ + public boolean isbHighlightUniqueMethods() { + return bHighlightUniqueMethods; + } + + /** + * �}�[�N�ŗL�̃��\�b�h���s�����ׂĎ擾���� + * @return�@�}�[�N�ŗL�̑S���\�b�h���s + */ + public ArrayList getUniqueMethodExecutions() { + ArrayList uniqueMethodExecutions = new ArrayList(); + if (markedThreads == null) { + updateMarkedThreads(); + } + if (unmarkedMethodSignatures == null) unmarkedMethodSignatures = trace.getUnmarkedMethodSignatures(markStart, markEnd); + for (int i = 0; i < markedThreads.size(); i++) { + uniqueMethodExecutions.addAll(markedThreads.get(i).getUniqueMethodExecutions(unmarkedMethodSignatures)); + } + return uniqueMethodExecutions; + } +} diff --git a/traces/__arraySample.txt b/traces/__arraySample.txt new file mode 100644 index 0000000..e1eed13 --- /dev/null +++ b/traces/__arraySample.txt @@ -0,0 +1,47 @@ +{"type":"classDef","name":"arraySample.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"methodEntry","signature":"public static void arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":865101683}],"threadId":1,"time":1929123793164451}, +{"type":"blockEntry","methodSignature":"arraySample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1929123793181024}, +{"type":"methodCall","callerSideSignature":"arraySample.A()","threadId":1,"lineNum":10}, +{"type":"classDef","name":"arraySample.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.A()","class":"arraySample.A","args":[],"threadId":1,"time":1929123793858048}, +{"type":"arrayCreate","array":{"class":"[Ljava.lang.Object;","id":1127555950},"dimension":1,"threadId":1,"lineNum":5,"time":1929123793886610}, +{"type":"fieldSet","fieldName":"arraySample.A.array","container":{"class":"arraySample.A","id":1437150522},"value":{"class":"[Ljava.lang.Object;","id":1127555950},"threadId":1,"lineNum":5,"time":1929123793904946}, +{"type":"methodCall","callerSideSignature":"arraySample.D()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"arraySample.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.D()","class":"arraySample.D","args":[],"threadId":1,"time":1929123794328439}, +{"type":"constructorExit","shortSignature":"arraySample.D()","returnValue":{"class":"arraySample.D","id":542899160},"threadId":1,"time":1929123794359469}, +{"type":"fieldSet","fieldName":"arraySample.A.d","container":{"class":"arraySample.A","id":1437150522},"value":{"class":"arraySample.D","id":542899160},"threadId":1,"lineNum":6,"time":1929123794374984}, +{"type":"constructorExit","shortSignature":"arraySample.A()","returnValue":{"class":"arraySample.A","id":1437150522},"threadId":1,"time":1929123794384858}, +{"type":"methodCall","callerSideSignature":"arraySample.A.init()","threadId":1,"lineNum":11}, +{"type":"methodEntry","signature":"public void arraySample.A.init()","receiver":{"class":"arraySample.A","id":1437150522},"args":[],"threadId":1,"time":1929123794402841}, +{"type":"blockEntry","methodSignature":"arraySample.A.init()","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1929123794411657}, +{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1437150522},"container":{"class":"arraySample.A","id":1437150522},"value":{"class":"[Ljava.lang.Object;","id":1127555950},"threadId":1,"lineNum":9,"time":1929123794426819}, +{"type":"methodCall","callerSideSignature":"arraySample.B()","threadId":1,"lineNum":9}, +{"type":"classDef","name":"arraySample.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.B()","class":"arraySample.B","args":[],"threadId":1,"time":1929123794838676}, +{"type":"methodCall","callerSideSignature":"arraySample.C()","threadId":1,"lineNum":5}, +{"type":"classDef","name":"arraySample.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.C()","class":"arraySample.C","args":[],"threadId":1,"time":1929123795158852}, +{"type":"constructorExit","shortSignature":"arraySample.C()","returnValue":{"class":"arraySample.C","id":1777161954},"threadId":1,"time":1929123795182125}, +{"type":"fieldSet","fieldName":"arraySample.B.c","container":{"class":"arraySample.B","id":1558398402},"value":{"class":"arraySample.C","id":1777161954},"threadId":1,"lineNum":5,"time":1929123795204692}, +{"type":"constructorExit","shortSignature":"arraySample.B()","returnValue":{"class":"arraySample.B","id":1558398402},"threadId":1,"time":1929123795214918}, +{"type":"arraySet","array":{"class":"[Ljava.lang.Object;","id":1127555950},"index":0,"value":{"class":"arraySample.B","id":1558398402},"threadId":1,"time":1929123795627832}, +{"type":"methodExit","shortSignature":"arraySample.A.init()","receiver":{"class":"arraySample.A","id":1437150522},"returnValue":{"class":"void","id":0},"threadId":1,"time":1929123796710366}, +{"type":"methodCall","callerSideSignature":"arraySample.A.start()","threadId":1,"lineNum":12}, +{"type":"methodEntry","signature":"public void arraySample.A.start()","receiver":{"class":"arraySample.A","id":1437150522},"args":[],"threadId":1,"time":1929123796730113}, +{"type":"blockEntry","methodSignature":"arraySample.A.start()","blockId":0,"incomings":0,"threadId":1,"lineNum":13,"time":1929123796738576}, +{"type":"fieldGet","fieldName":"arraySample.A.d","this":{"class":"arraySample.A","id":1437150522},"container":{"class":"arraySample.A","id":1437150522},"value":{"class":"arraySample.D","id":542899160},"threadId":1,"lineNum":13,"time":1929123796753033}, +{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1437150522},"container":{"class":"arraySample.A","id":1437150522},"value":{"class":"[Ljava.lang.Object;","id":1127555950},"threadId":1,"lineNum":13,"time":1929123796767137}, +{"type":"arrayGet","array":{"class":"[Ljava.lang.Object;","id":1127555950},"index":0,"value":{"class":"arraySample.B","id":1558398402},"threadId":1,"time":1929123796774895}, +{"type":"methodCall","callerSideSignature":"arraySample.B.getC()","threadId":1,"lineNum":13}, +{"type":"methodEntry","signature":"public arraySample.C arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1558398402},"args":[],"threadId":1,"time":1929123796829903}, +{"type":"blockEntry","methodSignature":"arraySample.B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":1929123796838719}, +{"type":"fieldGet","fieldName":"arraySample.B.c","this":{"class":"arraySample.B","id":1558398402},"container":{"class":"arraySample.B","id":1558398402},"value":{"class":"arraySample.C","id":1777161954},"threadId":1,"lineNum":8,"time":1929123796853881}, +{"type":"methodExit","shortSignature":"arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1558398402},"returnValue":{"class":"arraySample.C","id":1777161954},"threadId":1,"time":1929123796866223}, +{"type":"methodCall","callerSideSignature":"arraySample.D.setC(arraySample.C)","threadId":1,"lineNum":13}, +{"type":"methodEntry","signature":"void arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":542899160},"args":[{"class":"arraySample.C","id":1777161954}],"threadId":1,"time":1929123796887027}, +{"type":"blockEntry","methodSignature":"arraySample.D.setC(arraySample.C)","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1929123796895843}, +{"type":"fieldSet","fieldName":"arraySample.D.c","container":{"class":"arraySample.D","id":542899160},"value":{"class":"arraySample.C","id":1777161954},"threadId":1,"lineNum":7,"time":1929123796910300}, +{"type":"methodExit","shortSignature":"arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":542899160},"returnValue":{"class":"void","id":0},"threadId":1,"time":1929123796920878}, +{"type":"methodExit","shortSignature":"arraySample.A.start()","receiver":{"class":"arraySample.A","id":1437150522},"returnValue":{"class":"void","id":0},"threadId":1,"time":1929123796932162}, +{"type":"methodExit","shortSignature":"arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1929123796940978}, diff --git a/traces/_arraySample.txt b/traces/_arraySample.txt new file mode 100644 index 0000000..2cd7054 --- /dev/null +++ b/traces/_arraySample.txt @@ -0,0 +1,47 @@ +{"type":"classDef","name":"arraySample.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"methodEntry","signature":"public static void arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":865101683}],"threadId":1,"time":1699149368296708}, +{"type":"blockEntry","methodSignature":"arraySample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1699149368313281}, +{"type":"methodCall","callerSideSignature":"arraySample.A()","threadId":1,"lineNum":10}, +{"type":"classDef","name":"arraySample.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.A()","class":"arraySample.A","args":[],"threadId":1,"time":1699149368958570}, +{"type":"arrayCreate","array":{"class":"[LarraySample.B;","id":1484304002},"dimension":1,"threadId":1,"lineNum":5,"time":1699149369290735}, +{"type":"fieldSet","fieldName":"arraySample.A.array","container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":5,"time":1699149369313303}, +{"type":"methodCall","callerSideSignature":"arraySample.D()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"arraySample.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.D()","class":"arraySample.D","args":[],"threadId":1,"time":1699149369698361}, +{"type":"constructorExit","shortSignature":"arraySample.D()","returnValue":{"class":"arraySample.D","id":1642365377},"threadId":1,"time":1699149369729743}, +{"type":"fieldSet","fieldName":"arraySample.A.d","container":{"class":"arraySample.A","id":1527318062},"value":{"class":"arraySample.D","id":1642365377},"threadId":1,"lineNum":6,"time":1699149369744906}, +{"type":"constructorExit","shortSignature":"arraySample.A()","returnValue":{"class":"arraySample.A","id":1527318062},"threadId":1,"time":1699149369755132}, +{"type":"methodCall","callerSideSignature":"arraySample.A.init()","threadId":1,"lineNum":11}, +{"type":"methodEntry","signature":"public void arraySample.A.init()","receiver":{"class":"arraySample.A","id":1527318062},"args":[],"threadId":1,"time":1699149369774526}, +{"type":"blockEntry","methodSignature":"arraySample.A.init()","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1699149369783341}, +{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":9,"time":1699149369798856}, +{"type":"methodCall","callerSideSignature":"arraySample.B()","threadId":1,"lineNum":9}, +{"type":"classDef","name":"arraySample.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.B()","class":"arraySample.B","args":[],"threadId":1,"time":1699149369928972}, +{"type":"methodCall","callerSideSignature":"arraySample.C()","threadId":1,"lineNum":5}, +{"type":"classDef","name":"arraySample.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/arraySample/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public arraySample.C()","class":"arraySample.C","args":[],"threadId":1,"time":1699149370298162}, +{"type":"constructorExit","shortSignature":"arraySample.C()","returnValue":{"class":"arraySample.C","id":1558398402},"threadId":1,"time":1699149370320729}, +{"type":"fieldSet","fieldName":"arraySample.B.c","container":{"class":"arraySample.B","id":1291383602},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":5,"time":1699149370343649}, +{"type":"constructorExit","shortSignature":"arraySample.B()","returnValue":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149370353875}, +{"type":"arraySet","array":{"class":"[LarraySample.B;","id":1484304002},"index":0,"value":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149370763616}, +{"type":"methodExit","shortSignature":"arraySample.A.init()","receiver":{"class":"arraySample.A","id":1527318062},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371705456}, +{"type":"methodCall","callerSideSignature":"arraySample.A.start()","threadId":1,"lineNum":12}, +{"type":"methodEntry","signature":"public void arraySample.A.start()","receiver":{"class":"arraySample.A","id":1527318062},"args":[],"threadId":1,"time":1699149371725202}, +{"type":"blockEntry","methodSignature":"arraySample.A.start()","blockId":0,"incomings":0,"threadId":1,"lineNum":13,"time":1699149371732960}, +{"type":"fieldGet","fieldName":"arraySample.A.d","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"arraySample.D","id":1642365377},"threadId":1,"lineNum":13,"time":1699149371748475}, +{"type":"fieldGet","fieldName":"arraySample.A.array","this":{"class":"arraySample.A","id":1527318062},"container":{"class":"arraySample.A","id":1527318062},"value":{"class":"[LarraySample.B;","id":1484304002},"threadId":1,"lineNum":13,"time":1699149371762932}, +{"type":"arrayGet","array":{"class":"[LarraySample.B;","id":1484304002},"index":0,"value":{"class":"arraySample.B","id":1291383602},"threadId":1,"time":1699149371769632}, +{"type":"methodCall","callerSideSignature":"arraySample.B.getC()","threadId":1,"lineNum":13}, +{"type":"methodEntry","signature":"public arraySample.C arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1291383602},"args":[],"threadId":1,"time":1699149371825346}, +{"type":"blockEntry","methodSignature":"arraySample.B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":8,"time":1699149371834514}, +{"type":"fieldGet","fieldName":"arraySample.B.c","this":{"class":"arraySample.B","id":1291383602},"container":{"class":"arraySample.B","id":1291383602},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":8,"time":1699149371848971}, +{"type":"methodExit","shortSignature":"arraySample.B.getC()","receiver":{"class":"arraySample.B","id":1291383602},"returnValue":{"class":"arraySample.C","id":1558398402},"threadId":1,"time":1699149371860960}, +{"type":"methodCall","callerSideSignature":"arraySample.D.setC(arraySample.C)","threadId":1,"lineNum":13}, +{"type":"methodEntry","signature":"void arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":1642365377},"args":[{"class":"arraySample.C","id":1558398402}],"threadId":1,"time":1699149371881059}, +{"type":"blockEntry","methodSignature":"arraySample.D.setC(arraySample.C)","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1699149371889875}, +{"type":"fieldSet","fieldName":"arraySample.D.c","container":{"class":"arraySample.D","id":1642365377},"value":{"class":"arraySample.C","id":1558398402},"threadId":1,"lineNum":7,"time":1699149371904685}, +{"type":"methodExit","shortSignature":"arraySample.D.setC(arraySample.C)","receiver":{"class":"arraySample.D","id":1642365377},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371915968}, +{"type":"methodExit","shortSignature":"arraySample.A.start()","receiver":{"class":"arraySample.A","id":1527318062},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371926899}, +{"type":"methodExit","shortSignature":"arraySample.Main.main(java.lang.String[])","receiver":{"class":"arraySample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699149371936067}, diff --git a/traces/_finalLocal.txt b/traces/_finalLocal.txt new file mode 100644 index 0000000..6dc29bd --- /dev/null +++ b/traces/_finalLocal.txt @@ -0,0 +1,31 @@ +2 +{"type":"classDef","name":"finalLocal.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"methodEntry","signature":"public static void finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1819586596}],"threadId":1,"time":1699409891667627}, +{"type":"blockEntry","methodSignature":"finalLocal.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":9,"time":1699409891692663}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main()","threadId":1,"lineNum":9}, +{"type":"constructorEntry","signature":"public finalLocal.Main()","class":"finalLocal.Main","args":[],"threadId":1,"time":1699409891713115}, +{"type":"constructorExit","shortSignature":"finalLocal.Main()","returnValue":{"class":"finalLocal.Main","id":1624785692},"threadId":1,"time":1699409891727925}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main.coordinator()","threadId":1,"lineNum":10}, +{"type":"methodEntry","signature":"public void finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":1624785692},"args":[],"threadId":1,"time":1699409891754723}, +{"type":"blockEntry","methodSignature":"finalLocal.Main.coordinator()","blockId":0,"incomings":0,"threadId":1,"lineNum":20,"time":1699409891766713}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main.A()","threadId":1,"lineNum":20}, +{"type":"classDef","name":"finalLocal.Main$A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main$A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"finalLocal.Main.A()","class":"finalLocal.Main$A","args":[],"threadId":1,"time":1699409892360519}, +{"type":"constructorExit","shortSignature":"finalLocal.Main.A()","returnValue":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"time":1699409892401070}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","threadId":1,"lineNum":29}, +{"type":"classDef","name":"finalLocal.Main$1Test","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/finalLocal/Main$1Test.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","class":"finalLocal.Main$1Test","args":[{"class":"finalLocal.Main","id":1624785692},{"class":"finalLocal.Main$A","id":1656301910}],"threadId":1,"time":1699409893076332}, +{"type":"constructorExit","shortSignature":"finalLocal.Main.1Test(finalLocal.Main,finalLocal.Main.A)","returnValue":{"class":"finalLocal.Main$1Test","id":1437150522},"threadId":1,"time":1699409893104894}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main.1Test.test()","threadId":1,"lineNum":30}, +{"type":"methodEntry","signature":"public void finalLocal.Main.1Test.test()","receiver":{"class":"finalLocal.Main$1Test","id":1437150522},"args":[],"threadId":1,"time":1699409893132045}, +{"type":"blockEntry","methodSignature":"finalLocal.Main.1Test.test()","blockId":0,"incomings":0,"threadId":1,"lineNum":25,"time":1699409893145092}, +{"type":"fieldSet","fieldName":"finalLocal.Main$1Test.a2","container":{"class":"finalLocal.Main$1Test","id":1437150522},"value":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"lineNum":25,"time":1699409893165191}, +{"type":"fieldGet","fieldName":"java.lang.System.out","this":{"class":"finalLocal.Main$1Test","id":1437150522},"container":{"class":"---","id":0},"value":{"class":"java.io.PrintStream","id":1440245445},"threadId":1,"lineNum":26,"time":1699409893193048}, +{"type":"fieldGet","fieldName":"finalLocal.Main$1Test.a2","this":{"class":"finalLocal.Main$1Test","id":1437150522},"container":{"class":"finalLocal.Main$1Test","id":1437150522},"value":{"class":"finalLocal.Main$A","id":1656301910},"threadId":1,"lineNum":26,"time":1699409893215263}, +{"type":"methodCall","callerSideSignature":"finalLocal.Main.A.get()","threadId":1,"lineNum":26}, +{"type":"methodEntry","signature":"int finalLocal.Main.A.get()","receiver":{"class":"finalLocal.Main$A","id":1656301910},"args":[],"threadId":1,"time":1699409893243472}, +{"type":"blockEntry","methodSignature":"finalLocal.Main.A.get()","blockId":0,"incomings":0,"threadId":1,"lineNum":15,"time":1699409893255814}, +{"type":"methodExit","shortSignature":"finalLocal.Main.A.get()","receiver":{"class":"finalLocal.Main$A","id":1656301910},"returnValue":{"class":"int","id":2},"threadId":1,"time":1699409893273797}, +{"type":"methodExit","shortSignature":"finalLocal.Main.1Test.test()","receiver":{"class":"finalLocal.Main$1Test","id":1437150522},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893469852}, +{"type":"methodExit","shortSignature":"finalLocal.Main.coordinator()","receiver":{"class":"finalLocal.Main","id":1624785692},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893492420}, +{"type":"methodExit","shortSignature":"finalLocal.Main.main(java.lang.String[])","receiver":{"class":"finalLocal.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699409893520982}, diff --git a/traces/_threadSample.txt b/traces/_threadSample.txt new file mode 100644 index 0000000..744e487 --- /dev/null +++ b/traces/_threadSample.txt @@ -0,0 +1,62 @@ +{"type":"classDef","name":"threadSample.Main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/Main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"methodEntry","signature":"public static void threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1588438933}],"threadId":1,"time":1699487713263226}, +{"type":"blockEntry","methodSignature":"threadSample.Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":11,"time":1699487713280504}, +{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample()","threadId":1,"lineNum":11}, +{"type":"classDef","name":"threadSample.ThreadSample","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/ThreadSample.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public threadSample.ThreadSample()","class":"threadSample.ThreadSample","args":[],"threadId":1,"time":1699487713462454}, +{"type":"constructorExit","shortSignature":"threadSample.ThreadSample()","returnValue":{"class":"threadSample.ThreadSample","id":1523931074},"threadId":1,"time":1699487713495248}, +{"type":"methodCall","callerSideSignature":"java.lang.Thread.start()","threadId":1,"lineNum":12}, +{"type":"methodEntry","signature":"public synchronized void java.lang.Thread.start()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"args":[],"threadId":1,"time":1699487713514289}, +{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699487713590454}, +{"type":"methodExit","shortSignature":"threadSample.Main.main(java.lang.String[])","receiver":{"class":"threadSample.Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699487713603148}, +{"type":"methodEntry","signature":"public void threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"args":[],"threadId":10,"time":1699487713707876}, +{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.run()","blockId":0,"incomings":0,"threadId":10,"lineNum":5,"time":1699487713725154}, +{"type":"methodCall","callerSideSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","threadId":10,"lineNum":5}, +{"type":"classDef","name":"threadSample.ThreadSample$1","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/ThreadSample$1.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","class":"threadSample.ThreadSample$1","args":[{"class":"threadSample.ThreadSample","id":1523931074}],"threadId":10,"time":1699487714260779}, +{"type":"constructorExit","shortSignature":"threadSample.ThreadSample.1(threadSample.ThreadSample)","returnValue":{"class":"threadSample.ThreadSample$1","id":1484491751},"threadId":10,"time":1699487714281583}, +{"type":"methodCall","callerSideSignature":"java.lang.Thread(java.lang.Runnable)","threadId":10,"lineNum":5}, +{"type":"constructorEntry","signature":"public java.lang.Thread(java.lang.Runnable)","class":"java.lang.Thread","args":[{"class":"threadSample.ThreadSample$1","id":1484491751}],"threadId":10,"time":1699487714301330}, +{"type":"constructorExit","shortSignature":"java.lang.Thread(java.lang.Runnable)","returnValue":{"class":"java.lang.Thread","id":387848211},"threadId":10,"time":1699487714322839}, +{"type":"methodCall","callerSideSignature":"java.lang.Thread.start()","threadId":10,"lineNum":12}, +{"type":"methodEntry","signature":"public synchronized void java.lang.Thread.start()","receiver":{"class":"java.lang.Thread","id":387848211},"args":[],"threadId":10,"time":1699487714339060}, +{"type":"methodExit","shortSignature":"java.lang.Thread.start()","receiver":{"class":"java.lang.Thread","id":387848211},"returnValue":{"class":"void","id":0},"threadId":10,"time":1699487714397242}, +{"type":"methodExit","shortSignature":"threadSample.ThreadSample.run()","receiver":{"class":"threadSample.ThreadSample","id":1523931074},"returnValue":{"class":"void","id":0},"threadId":10,"time":1699487714418399}, +{"type":"methodEntry","signature":"public void threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":1484491751},"args":[],"threadId":12,"time":1699487714499853}, +{"type":"blockEntry","methodSignature":"threadSample.ThreadSample.1.run()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1699487714518542}, +{"type":"methodCall","callerSideSignature":"threadSample.A()","threadId":12,"lineNum":8}, +{"type":"classDef","name":"threadSample.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public threadSample.A()","class":"threadSample.A","args":[],"threadId":12,"time":1699487715148668}, +{"type":"methodCall","callerSideSignature":"threadSample.B()","threadId":12,"lineNum":4}, +{"type":"classDef","name":"threadSample.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public threadSample.B()","class":"threadSample.B","args":[],"threadId":12,"time":1699487715599313}, +{"type":"methodCall","callerSideSignature":"threadSample.C()","threadId":12,"lineNum":4}, +{"type":"classDef","name":"threadSample.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public threadSample.C()","class":"threadSample.C","args":[],"threadId":12,"time":1699487715910673}, +{"type":"constructorExit","shortSignature":"threadSample.C()","returnValue":{"class":"threadSample.C","id":2022437173},"threadId":12,"time":1699487715935004}, +{"type":"fieldSet","fieldName":"threadSample.B.c","container":{"class":"threadSample.B","id":730401895},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":4,"time":1699487715959334}, +{"type":"constructorExit","shortSignature":"threadSample.B()","returnValue":{"class":"threadSample.B","id":730401895},"threadId":12,"time":1699487715968503}, +{"type":"fieldSet","fieldName":"threadSample.A.b","container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.B","id":730401895},"threadId":12,"lineNum":4,"time":1699487715989659}, +{"type":"methodCall","callerSideSignature":"threadSample.D()","threadId":12,"lineNum":5}, +{"type":"classDef","name":"threadSample.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/threadSample/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public threadSample.D()","class":"threadSample.D","args":[],"threadId":12,"time":1699487716356028}, +{"type":"constructorExit","shortSignature":"threadSample.D()","returnValue":{"class":"threadSample.D","id":289975132},"threadId":12,"time":1699487716377891}, +{"type":"fieldSet","fieldName":"threadSample.A.d","container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.D","id":289975132},"threadId":12,"lineNum":5,"time":1699487716392701}, +{"type":"constructorExit","shortSignature":"threadSample.A()","returnValue":{"class":"threadSample.A","id":848123013},"threadId":12,"time":1699487716402574}, +{"type":"methodCall","callerSideSignature":"threadSample.A.m()","threadId":12,"lineNum":9}, +{"type":"methodEntry","signature":"public void threadSample.A.m()","receiver":{"class":"threadSample.A","id":848123013},"args":[],"threadId":12,"time":1699487716421262}, +{"type":"blockEntry","methodSignature":"threadSample.A.m()","blockId":0,"incomings":0,"threadId":12,"lineNum":8,"time":1699487716428668}, +{"type":"fieldGet","fieldName":"threadSample.A.d","this":{"class":"threadSample.A","id":848123013},"container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.D","id":289975132},"threadId":12,"lineNum":8,"time":1699487716444183}, +{"type":"fieldGet","fieldName":"threadSample.A.b","this":{"class":"threadSample.A","id":848123013},"container":{"class":"threadSample.A","id":848123013},"value":{"class":"threadSample.B","id":730401895},"threadId":12,"lineNum":8,"time":1699487716458993}, +{"type":"methodCall","callerSideSignature":"threadSample.B.getC()","threadId":12,"lineNum":8}, +{"type":"methodEntry","signature":"public threadSample.C threadSample.B.getC()","receiver":{"class":"threadSample.B","id":730401895},"args":[],"threadId":12,"time":1699487716478034}, +{"type":"blockEntry","methodSignature":"threadSample.B.getC()","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1699487716485791}, +{"type":"fieldGet","fieldName":"threadSample.B.c","this":{"class":"threadSample.B","id":730401895},"container":{"class":"threadSample.B","id":730401895},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":7,"time":1699487716502717}, +{"type":"methodExit","shortSignature":"threadSample.B.getC()","receiver":{"class":"threadSample.B","id":730401895},"returnValue":{"class":"threadSample.C","id":2022437173},"threadId":12,"time":1699487716518585}, +{"type":"methodCall","callerSideSignature":"threadSample.D.setC(threadSample.C)","threadId":12,"lineNum":8}, +{"type":"methodEntry","signature":"public void threadSample.D.setC(threadSample.C)","receiver":{"class":"threadSample.D","id":289975132},"args":[{"class":"threadSample.C","id":2022437173}],"threadId":12,"time":1699487716538684}, +{"type":"blockEntry","methodSignature":"threadSample.D.setC(threadSample.C)","blockId":0,"incomings":0,"threadId":12,"lineNum":7,"time":1699487716547147}, +{"type":"fieldSet","fieldName":"threadSample.D.c","container":{"class":"threadSample.D","id":289975132},"value":{"class":"threadSample.C","id":2022437173},"threadId":12,"lineNum":7,"time":1699487716560194}, +{"type":"methodExit","shortSignature":"threadSample.D.setC(threadSample.C)","receiver":{"class":"threadSample.D","id":289975132},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716575356}, +{"type":"methodExit","shortSignature":"threadSample.A.m()","receiver":{"class":"threadSample.A","id":848123013},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716590871}, +{"type":"methodExit","shortSignature":"threadSample.ThreadSample.1.run()","receiver":{"class":"threadSample.ThreadSample$1","id":1484491751},"returnValue":{"class":"void","id":0},"threadId":12,"time":1699487716609207}, diff --git a/traces/_worstCase.txt b/traces/_worstCase.txt new file mode 100644 index 0000000..ccef302 --- /dev/null +++ b/traces/_worstCase.txt @@ -0,0 +1,159 @@ +{"type":"classDef","name":"worstCase.main","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/main.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"methodEntry","signature":"public static void worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"args":[{"class":"[Ljava.lang.String;","id":1457398981}],"threadId":1,"time":1699552992964235}, +{"type":"blockEntry","methodSignature":"worstCase.main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":10,"time":1699552992988213}, +{"type":"methodCall","callerSideSignature":"worstCase.A()","threadId":1,"lineNum":10}, +{"type":"classDef","name":"worstCase.A","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/A.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.A()","class":"worstCase.A","args":[],"threadId":1,"time":1699552993730471}, +{"type":"methodCall","callerSideSignature":"worstCase.B()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.B","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/B.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.B()","class":"worstCase.B","args":[],"threadId":1,"time":1699552994339441}, +{"type":"methodCall","callerSideSignature":"worstCase.C()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.C","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/C.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.C()","class":"worstCase.C","args":[],"threadId":1,"time":1699552994979793}, +{"type":"methodCall","callerSideSignature":"worstCase.D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.D","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/D.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.D()","class":"worstCase.D","args":[],"threadId":1,"time":1699552995575363}, +{"type":"methodCall","callerSideSignature":"worstCase.E()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.E","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/E.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.E()","class":"worstCase.E","args":[],"threadId":1,"time":1699552996163881}, +{"type":"methodCall","callerSideSignature":"worstCase.F()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.F","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/F.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.F()","class":"worstCase.F","args":[],"threadId":1,"time":1699552996774613}, +{"type":"methodCall","callerSideSignature":"worstCase.G()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.G","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/G.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.G()","class":"worstCase.G","args":[],"threadId":1,"time":1699552997363836}, +{"type":"methodCall","callerSideSignature":"worstCase.H()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.H","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/H.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.H()","class":"worstCase.H","args":[],"threadId":1,"time":1699552997949532}, +{"type":"methodCall","callerSideSignature":"worstCase.I()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.I","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/I.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.I()","class":"worstCase.I","args":[],"threadId":1,"time":1699552998548628}, +{"type":"methodCall","callerSideSignature":"worstCase.J()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.J","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/J.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.J()","class":"worstCase.J","args":[],"threadId":1,"time":1699552999050402}, +{"type":"methodCall","callerSideSignature":"worstCase.K()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.K","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/K.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.K()","class":"worstCase.K","args":[],"threadId":1,"time":1699552999466490}, +{"type":"methodCall","callerSideSignature":"worstCase.L()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.L","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/L.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.L()","class":"worstCase.L","args":[],"threadId":1,"time":1699552999875526}, +{"type":"methodCall","callerSideSignature":"worstCase.M()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.M","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/M.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"public worstCase.M()","class":"worstCase.M","args":[],"threadId":1,"time":1699553000173135}, +{"type":"constructorExit","shortSignature":"worstCase.M()","returnValue":{"class":"worstCase.M","id":1289325312},"threadId":1,"time":1699553000199581}, +{"type":"fieldSet","fieldName":"worstCase.L.m","container":{"class":"worstCase.L","id":1580520554},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":4,"time":1699553000225322}, +{"type":"constructorExit","shortSignature":"worstCase.L()","returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553000234842}, +{"type":"fieldSet","fieldName":"worstCase.K.l","container":{"class":"worstCase.K","id":1583721335},"value":{"class":"worstCase.L","id":1580520554},"threadId":1,"lineNum":4,"time":1699553000259878}, +{"type":"constructorExit","shortSignature":"worstCase.K()","returnValue":{"class":"worstCase.K","id":1583721335},"threadId":1,"time":1699553000268694}, +{"type":"fieldSet","fieldName":"worstCase.J.k","container":{"class":"worstCase.J","id":1692156427},"value":{"class":"worstCase.K","id":1583721335},"threadId":1,"lineNum":4,"time":1699553000290908}, +{"type":"constructorExit","shortSignature":"worstCase.J()","returnValue":{"class":"worstCase.J","id":1692156427},"threadId":1,"time":1699553000300782}, +{"type":"fieldSet","fieldName":"worstCase.I.j","container":{"class":"worstCase.I","id":947131368},"value":{"class":"worstCase.J","id":1692156427},"threadId":1,"lineNum":4,"time":1699553000331107}, +{"type":"constructorExit","shortSignature":"worstCase.I()","returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553000348033}, +{"type":"fieldSet","fieldName":"worstCase.H.i","container":{"class":"worstCase.H","id":1288110412},"value":{"class":"worstCase.I","id":947131368},"threadId":1,"lineNum":4,"time":1699553000376947}, +{"type":"constructorExit","shortSignature":"worstCase.H()","returnValue":{"class":"worstCase.H","id":1288110412},"threadId":1,"time":1699553000390346}, +{"type":"fieldSet","fieldName":"worstCase.G.h","container":{"class":"worstCase.G","id":489049077},"value":{"class":"worstCase.H","id":1288110412},"threadId":1,"lineNum":4,"time":1699553000422435}, +{"type":"constructorExit","shortSignature":"worstCase.G()","returnValue":{"class":"worstCase.G","id":489049077},"threadId":1,"time":1699553000433718}, +{"type":"fieldSet","fieldName":"worstCase.F.g","container":{"class":"worstCase.F","id":1027920070},"value":{"class":"worstCase.G","id":489049077},"threadId":1,"lineNum":4,"time":1699553000463691}, +{"type":"constructorExit","shortSignature":"worstCase.F()","returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553000475327}, +{"type":"fieldSet","fieldName":"worstCase.E.f","container":{"class":"worstCase.E","id":1894160022},"value":{"class":"worstCase.F","id":1027920070},"threadId":1,"lineNum":4,"time":1699553000508121}, +{"type":"constructorExit","shortSignature":"worstCase.E()","returnValue":{"class":"worstCase.E","id":1894160022},"threadId":1,"time":1699553000520462}, +{"type":"fieldSet","fieldName":"worstCase.D.e","container":{"class":"worstCase.D","id":849906626},"value":{"class":"worstCase.E","id":1894160022},"threadId":1,"lineNum":4,"time":1699553000551845}, +{"type":"constructorExit","shortSignature":"worstCase.D()","returnValue":{"class":"worstCase.D","id":849906626},"threadId":1,"time":1699553000565597}, +{"type":"fieldSet","fieldName":"worstCase.C.d","container":{"class":"worstCase.C","id":1466926985},"value":{"class":"worstCase.D","id":849906626},"threadId":1,"lineNum":4,"time":1699553000596627}, +{"type":"constructorExit","shortSignature":"worstCase.C()","returnValue":{"class":"worstCase.C","id":1466926985},"threadId":1,"time":1699553000610732}, +{"type":"fieldSet","fieldName":"worstCase.B.c","container":{"class":"worstCase.B","id":1529569335},"value":{"class":"worstCase.C","id":1466926985},"threadId":1,"lineNum":4,"time":1699553000640352}, +{"type":"constructorExit","shortSignature":"worstCase.B()","returnValue":{"class":"worstCase.B","id":1529569335},"threadId":1,"time":1699553000654457}, +{"type":"fieldSet","fieldName":"worstCase.A.b","container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.B","id":1529569335},"threadId":1,"lineNum":4,"time":1699553000682666}, +{"type":"methodCall","callerSideSignature":"worstCase.N()","threadId":1,"lineNum":5}, +{"type":"classDef","name":"worstCase.N","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/N.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.N()","class":"worstCase.N","args":[],"threadId":1,"time":1699553001472175}, +{"type":"methodCall","callerSideSignature":"worstCase.O()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.O","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/O.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.O()","class":"worstCase.O","args":[],"threadId":1,"time":1699553002201034}, +{"type":"methodCall","callerSideSignature":"worstCase.P()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"worstCase.P","path":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/worstCase/P.class","loaderPath":"/C:/Users/Nitta/git/TracerOnJavassist/TracerOnJavassist/bin/"}, +{"type":"constructorEntry","signature":"worstCase.P()","class":"worstCase.P","args":[],"threadId":1,"time":1699553003026510}, +{"type":"constructorExit","shortSignature":"worstCase.P()","returnValue":{"class":"worstCase.P","id":1386559816},"threadId":1,"time":1699553003062477}, +{"type":"fieldSet","fieldName":"worstCase.O.p","container":{"class":"worstCase.O","id":1565773915},"value":{"class":"worstCase.P","id":1386559816},"threadId":1,"lineNum":4,"time":1699553003101618}, +{"type":"constructorExit","shortSignature":"worstCase.O()","returnValue":{"class":"worstCase.O","id":1565773915},"threadId":1,"time":1699553003115017}, +{"type":"fieldSet","fieldName":"worstCase.N.o","container":{"class":"worstCase.N","id":697579067},"value":{"class":"worstCase.O","id":1565773915},"threadId":1,"lineNum":4,"time":1699553003149926}, +{"type":"constructorExit","shortSignature":"worstCase.N()","returnValue":{"class":"worstCase.N","id":697579067},"threadId":1,"time":1699553003164031}, +{"type":"fieldSet","fieldName":"worstCase.A.n","container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.N","id":697579067},"threadId":1,"lineNum":5,"time":1699553003190477}, +{"type":"constructorExit","shortSignature":"worstCase.A()","returnValue":{"class":"worstCase.A","id":2092558755},"threadId":1,"time":1699553003215866}, +{"type":"methodCall","callerSideSignature":"worstCase.A.m()","threadId":1,"lineNum":11}, +{"type":"methodEntry","signature":"void worstCase.A.m()","receiver":{"class":"worstCase.A","id":2092558755},"args":[],"threadId":1,"time":1699553003253243}, +{"type":"blockEntry","methodSignature":"worstCase.A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":1699553003273695}, +{"type":"fieldGet","fieldName":"worstCase.A.n","this":{"class":"worstCase.A","id":2092558755},"container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.N","id":697579067},"threadId":1,"lineNum":7,"time":1699553003299083}, +{"type":"fieldGet","fieldName":"worstCase.A.b","this":{"class":"worstCase.A","id":2092558755},"container":{"class":"worstCase.A","id":2092558755},"value":{"class":"worstCase.B","id":1529569335},"threadId":1,"lineNum":7,"time":1699553003355502}, +{"type":"methodCall","callerSideSignature":"worstCase.B.getI()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"worstCase.I worstCase.B.getI()","receiver":{"class":"worstCase.B","id":1529569335},"args":[],"threadId":1,"time":1699553003386885}, +{"type":"blockEntry","methodSignature":"worstCase.B.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003400637}, +{"type":"fieldGet","fieldName":"worstCase.B.c","this":{"class":"worstCase.B","id":1529569335},"container":{"class":"worstCase.B","id":1529569335},"value":{"class":"worstCase.C","id":1466926985},"threadId":1,"lineNum":6,"time":1699553003436956}, +{"type":"methodCall","callerSideSignature":"worstCase.C.getF()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.F worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1466926985},"args":[],"threadId":1,"time":1699553003482444}, +{"type":"blockEntry","methodSignature":"worstCase.C.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003500427}, +{"type":"fieldGet","fieldName":"worstCase.C.d","this":{"class":"worstCase.C","id":1466926985},"container":{"class":"worstCase.C","id":1466926985},"value":{"class":"worstCase.D","id":849906626},"threadId":1,"lineNum":6,"time":1699553003526169}, +{"type":"methodCall","callerSideSignature":"worstCase.D.getE()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.E worstCase.D.getE()","receiver":{"class":"worstCase.D","id":849906626},"args":[],"threadId":1,"time":1699553003556141}, +{"type":"blockEntry","methodSignature":"worstCase.D.getE()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003570951}, +{"type":"fieldGet","fieldName":"worstCase.D.e","this":{"class":"worstCase.D","id":849906626},"container":{"class":"worstCase.D","id":849906626},"value":{"class":"worstCase.E","id":1894160022},"threadId":1,"lineNum":6,"time":1699553003599513}, +{"type":"methodExit","shortSignature":"worstCase.D.getE()","receiver":{"class":"worstCase.D","id":849906626},"returnValue":{"class":"worstCase.E","id":1894160022},"threadId":1,"time":1699553003626664}, +{"type":"methodCall","callerSideSignature":"worstCase.E.getF()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.F worstCase.E.getF()","receiver":{"class":"worstCase.E","id":1894160022},"args":[],"threadId":1,"time":1699553003668273}, +{"type":"blockEntry","methodSignature":"worstCase.E.getF()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003688020}, +{"type":"fieldGet","fieldName":"worstCase.E.f","this":{"class":"worstCase.E","id":1894160022},"container":{"class":"worstCase.E","id":1894160022},"value":{"class":"worstCase.F","id":1027920070},"threadId":1,"lineNum":6,"time":1699553003715876}, +{"type":"methodExit","shortSignature":"worstCase.E.getF()","receiver":{"class":"worstCase.E","id":1894160022},"returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553003743381}, +{"type":"methodExit","shortSignature":"worstCase.C.getF()","receiver":{"class":"worstCase.C","id":1466926985},"returnValue":{"class":"worstCase.F","id":1027920070},"threadId":1,"time":1699553003767006}, +{"type":"methodCall","callerSideSignature":"worstCase.F.getI()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.I worstCase.F.getI()","receiver":{"class":"worstCase.F","id":1027920070},"args":[],"threadId":1,"time":1699553003805088}, +{"type":"blockEntry","methodSignature":"worstCase.F.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003818135}, +{"type":"fieldGet","fieldName":"worstCase.F.g","this":{"class":"worstCase.F","id":1027920070},"container":{"class":"worstCase.F","id":1027920070},"value":{"class":"worstCase.G","id":489049077},"threadId":1,"lineNum":6,"time":1699553003846345}, +{"type":"methodCall","callerSideSignature":"worstCase.G.getH()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.H worstCase.G.getH()","receiver":{"class":"worstCase.G","id":489049077},"args":[],"threadId":1,"time":1699553003896769}, +{"type":"blockEntry","methodSignature":"worstCase.G.getH()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553003912989}, +{"type":"fieldGet","fieldName":"worstCase.G.h","this":{"class":"worstCase.G","id":489049077},"container":{"class":"worstCase.G","id":489049077},"value":{"class":"worstCase.H","id":1288110412},"threadId":1,"lineNum":6,"time":1699553003944020}, +{"type":"methodExit","shortSignature":"worstCase.G.getH()","receiver":{"class":"worstCase.G","id":489049077},"returnValue":{"class":"worstCase.H","id":1288110412},"threadId":1,"time":1699553003969761}, +{"type":"methodCall","callerSideSignature":"worstCase.H.getI()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.I worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1288110412},"args":[],"threadId":1,"time":1699553004012075}, +{"type":"blockEntry","methodSignature":"worstCase.H.getI()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004029706}, +{"type":"fieldGet","fieldName":"worstCase.H.i","this":{"class":"worstCase.H","id":1288110412},"container":{"class":"worstCase.H","id":1288110412},"value":{"class":"worstCase.I","id":947131368},"threadId":1,"lineNum":6,"time":1699553004082951}, +{"type":"methodExit","shortSignature":"worstCase.H.getI()","receiver":{"class":"worstCase.H","id":1288110412},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004119623}, +{"type":"methodExit","shortSignature":"worstCase.F.getI()","receiver":{"class":"worstCase.F","id":1027920070},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004147480}, +{"type":"methodExit","shortSignature":"worstCase.B.getI()","receiver":{"class":"worstCase.B","id":1529569335},"returnValue":{"class":"worstCase.I","id":947131368},"threadId":1,"time":1699553004170752}, +{"type":"methodCall","callerSideSignature":"worstCase.N.passI(worstCase.I)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void worstCase.N.passI(worstCase.I)","receiver":{"class":"worstCase.N","id":697579067},"args":[{"class":"worstCase.I","id":947131368}],"threadId":1,"time":1699553004208835}, +{"type":"blockEntry","methodSignature":"worstCase.N.passI(worstCase.I)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004228229}, +{"type":"fieldGet","fieldName":"worstCase.N.o","this":{"class":"worstCase.N","id":697579067},"container":{"class":"worstCase.N","id":697579067},"value":{"class":"worstCase.O","id":1565773915},"threadId":1,"lineNum":6,"time":1699553004257849}, +{"type":"methodCall","callerSideSignature":"worstCase.I.getL()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.L worstCase.I.getL()","receiver":{"class":"worstCase.I","id":947131368},"args":[],"threadId":1,"time":1699553004302631}, +{"type":"blockEntry","methodSignature":"worstCase.I.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004326962}, +{"type":"fieldGet","fieldName":"worstCase.I.j","this":{"class":"worstCase.I","id":947131368},"container":{"class":"worstCase.I","id":947131368},"value":{"class":"worstCase.J","id":1692156427},"threadId":1,"lineNum":6,"time":1699553004373507}, +{"type":"methodCall","callerSideSignature":"worstCase.J.getK()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.K worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1692156427},"args":[],"threadId":1,"time":1699553004418995}, +{"type":"blockEntry","methodSignature":"worstCase.J.getK()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004434510}, +{"type":"fieldGet","fieldName":"worstCase.J.k","this":{"class":"worstCase.J","id":1692156427},"container":{"class":"worstCase.J","id":1692156427},"value":{"class":"worstCase.K","id":1583721335},"threadId":1,"lineNum":6,"time":1699553004461661}, +{"type":"methodExit","shortSignature":"worstCase.J.getK()","receiver":{"class":"worstCase.J","id":1692156427},"returnValue":{"class":"worstCase.K","id":1583721335},"threadId":1,"time":1699553004482466}, +{"type":"methodCall","callerSideSignature":"worstCase.K.getL()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.L worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1583721335},"args":[],"threadId":1,"time":1699553004515964}, +{"type":"blockEntry","methodSignature":"worstCase.K.getL()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004526543}, +{"type":"fieldGet","fieldName":"worstCase.K.l","this":{"class":"worstCase.K","id":1583721335},"container":{"class":"worstCase.K","id":1583721335},"value":{"class":"worstCase.L","id":1580520554},"threadId":1,"lineNum":6,"time":1699553004546994}, +{"type":"methodExit","shortSignature":"worstCase.K.getL()","receiver":{"class":"worstCase.K","id":1583721335},"returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553004564273}, +{"type":"methodExit","shortSignature":"worstCase.I.getL()","receiver":{"class":"worstCase.I","id":947131368},"returnValue":{"class":"worstCase.L","id":1580520554},"threadId":1,"time":1699553004582256}, +{"type":"methodCall","callerSideSignature":"worstCase.O.passL(worstCase.L)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void worstCase.O.passL(worstCase.L)","receiver":{"class":"worstCase.O","id":1565773915},"args":[{"class":"worstCase.L","id":1580520554}],"threadId":1,"time":1699553004606587}, +{"type":"blockEntry","methodSignature":"worstCase.O.passL(worstCase.L)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004615402}, +{"type":"fieldGet","fieldName":"worstCase.O.p","this":{"class":"worstCase.O","id":1565773915},"container":{"class":"worstCase.O","id":1565773915},"value":{"class":"worstCase.P","id":1386559816},"threadId":1,"lineNum":6,"time":1699553004629507}, +{"type":"methodCall","callerSideSignature":"worstCase.L.getM()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"worstCase.M worstCase.L.getM()","receiver":{"class":"worstCase.L","id":1580520554},"args":[],"threadId":1,"time":1699553004648195}, +{"type":"blockEntry","methodSignature":"worstCase.L.getM()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004655953}, +{"type":"fieldGet","fieldName":"worstCase.L.m","this":{"class":"worstCase.L","id":1580520554},"container":{"class":"worstCase.L","id":1580520554},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":6,"time":1699553004670763}, +{"type":"methodExit","shortSignature":"worstCase.L.getM()","receiver":{"class":"worstCase.L","id":1580520554},"returnValue":{"class":"worstCase.M","id":1289325312},"threadId":1,"time":1699553004682752}, +{"type":"methodCall","callerSideSignature":"worstCase.P.setM(worstCase.M)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void worstCase.P.setM(worstCase.M)","receiver":{"class":"worstCase.P","id":1386559816},"args":[{"class":"worstCase.M","id":1289325312}],"threadId":1,"time":1699553004703556}, +{"type":"blockEntry","methodSignature":"worstCase.P.setM(worstCase.M)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1699553004712019}, +{"type":"fieldSet","fieldName":"worstCase.P.m","container":{"class":"worstCase.P","id":1386559816},"value":{"class":"worstCase.M","id":1289325312},"threadId":1,"lineNum":6,"time":1699553004728240}, +{"type":"methodExit","shortSignature":"worstCase.P.setM(worstCase.M)","receiver":{"class":"worstCase.P","id":1386559816},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004739523}, +{"type":"methodExit","shortSignature":"worstCase.O.passL(worstCase.L)","receiver":{"class":"worstCase.O","id":1565773915},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004751512}, +{"type":"methodExit","shortSignature":"worstCase.N.passI(worstCase.I)","receiver":{"class":"worstCase.N","id":697579067},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004764207}, +{"type":"methodExit","shortSignature":"worstCase.A.m()","receiver":{"class":"worstCase.A","id":2092558755},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004776548}, +{"type":"methodExit","shortSignature":"worstCase.main.main(java.lang.String[])","receiver":{"class":"worstCase.main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1699553004787479}, diff --git a/traces/jEditNormal.trace b/traces/jEditNormal.trace new file mode 100644 index 0000000..01e4fd4 --- /dev/null +++ b/traces/jEditNormal.trace Binary files differ diff --git a/traces/presenSample.txt b/traces/presenSample.txt new file mode 100644 index 0000000..2f04996 --- /dev/null +++ b/traces/presenSample.txt @@ -0,0 +1,40 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/PresenSample/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":216347870210700}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":216347870254600}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/PresenSample/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":216347872791600}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/PresenSample/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":216347875023600}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/PresenSample/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":216347876341600}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":216347876377600}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":3,"time":216347876415300}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":216347876424600}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":3,"time":216347876447900}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/PresenSample/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":216347877889800}, +{"type":"fieldSet","fieldName":"D.c","container":{"class":"D","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":216347877935400}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1028566121},"threadId":1,"time":216347877945700}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":4,"time":216347877962900}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":216347877981400}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":216347878025300}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":216347878035800}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":6,"time":216347878050900}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":216347878110900}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":216347878120500}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":216347878136100}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":216347878155000}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":7,"time":216347878168800}, +{"type":"methodCall","callerSideSignature":"D.setC(C)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void D.setC(C)","receiver":{"class":"D","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":216347878191700}, +{"type":"blockEntry","methodSignature":"D.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":216347878198100}, +{"type":"fieldSet","fieldName":"D.c","container":{"class":"D","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":216347878210900}, +{"type":"methodExit","shortSignature":"D.setC(C)","receiver":{"class":"D","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":216347878224800}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":216347878234800}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":216347878245900}, diff --git a/traces/testTrace.txt b/traces/testTrace.txt new file mode 100644 index 0000000..5b1cd0b --- /dev/null +++ b/traces/testTrace.txt @@ -0,0 +1,55 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":115568563480700}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":115568563506400}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":115568564913400}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":115568566418500}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"static C.()","class":"C","args":[],"threadId":1,"time":115568567528200}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/C.class","loaderPath":"/"}, +{"type":"constructorExit","shortSignature":"C.()","returnValue":{"class":"void","id":0},"threadId":1,"time":115568567543700}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":115568567572300}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":115568567585300}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":115568567618600}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":115568567627000}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":3,"time":115568567662100}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":115568567672400}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":3,"time":115568567698200}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":115568569056000}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":115568570527200}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":115568570583600}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":115568570598400}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":3,"time":115568570624100}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":115568570643900}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":4,"time":115568570690400}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":115568570708400}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":115568570745200}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":115568570756100}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":6,"time":115568570777500}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":6,"time":115568570800200}, +{"type":"methodCall","callerSideSignature":"D.passB(B)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void D.passB(B)","receiver":{"class":"D","id":1118140819},"args":[{"class":"B","id":865113938}],"threadId":1,"time":115568570833500}, +{"type":"blockEntry","methodSignature":"D.passB(B)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":115568570848900}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":5,"time":115568570869400}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":115568570900800}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":115568570911100}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":115568570933800}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":115568570967300}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":115568571003800}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":115568571018600}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":115568571035400}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":115568571051200}, +{"type":"methodExit","shortSignature":"D.passB(B)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":115568571073900}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":115568571089700}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":115568571102000}, diff --git a/traces/testTrace3.txt b/traces/testTrace3.txt new file mode 100644 index 0000000..7ed3deb --- /dev/null +++ b/traces/testTrace3.txt @@ -0,0 +1,48 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":1229132784416100}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1229132784464500}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":1229132787509900}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":1229132791075600}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":1550089733},"threadId":1,"time":1229132791136400}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":865113938},"value":{"class":"B","id":1550089733},"threadId":1,"lineNum":3,"time":1229132791203200}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":1229132793731300}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":1229132795848400}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1442407170},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":1229132795899900}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1442407170},"threadId":1,"time":1229132795914200}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1028566121},"value":{"class":"E","id":1442407170},"threadId":1,"lineNum":3,"time":1229132795941900}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1028566121},"threadId":1,"time":1229132795950600}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":865113938},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":4,"time":1229132795962200}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":865113938},"threadId":1,"time":1229132796001100}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":865113938},"args":[],"threadId":1,"time":1229132796046900}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":1229132796058300}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":865113938},"container":{"class":"A","id":865113938},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":6,"time":1229132796085500}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":865113938},"container":{"class":"A","id":865113938},"value":{"class":"B","id":1550089733},"threadId":1,"lineNum":6,"time":1229132796125300}, +{"type":"methodCall","callerSideSignature":"D.passB(B)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void D.passB(B)","receiver":{"class":"D","id":1028566121},"args":[{"class":"B","id":1550089733}],"threadId":1,"time":1229132796161600}, +{"type":"blockEntry","methodSignature":"D.passB(B)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":1229132796174500}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":1550089733},"args":[],"threadId":1,"time":1229132796261600}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":1229132796288500}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace3/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":1229132797848300}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1118140819},"threadId":1,"time":1229132797881400}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":1550089733},"returnValue":{"class":"C","id":1118140819},"threadId":1,"time":1229132797895200}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1028566121},"container":{"class":"D","id":1028566121},"value":{"class":"E","id":1442407170},"threadId":1,"lineNum":6,"time":1229132797911600}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1442407170},"args":[{"class":"C","id":1118140819}],"threadId":1,"time":1229132797930400}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":1229132797939100}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1442407170},"value":{"class":"C","id":1118140819},"threadId":1,"lineNum":5,"time":1229132797946900}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":1229132797956500}, +{"type":"methodExit","shortSignature":"D.passB(B)","receiver":{"class":"D","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":1229132797967100}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":865113938},"returnValue":{"class":"void","id":0},"threadId":1,"time":1229132797976100}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":1229132797985700}, diff --git a/traces/testTrace5.txt b/traces/testTrace5.txt new file mode 100644 index 0000000..d6c5358 --- /dev/null +++ b/traces/testTrace5.txt @@ -0,0 +1,58 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":715843630094500}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715843630140500}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":715843632448700}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":715843634705300}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":715843636149500}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":715843636184400}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":3,"time":715843636225500}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":715843636237700}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":3,"time":715843636260900}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":715843638186400}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace5/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":715843640191400}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":715843640262600}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":715843640278000}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":3,"time":715843640339100}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":715843640366100}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":4,"time":715843640403800}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":715843640421800}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":715843640451900}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":715843640463900}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":7,"time":715843640488500}, +{"type":"methodCall","callerSideSignature":"B.setA(A)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void B.setA(A)","receiver":{"class":"B","id":865113938},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":715843640518100}, +{"type":"blockEntry","methodSignature":"B.setA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715843640532000}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":6,"time":715843640552200}, +{"type":"methodCall","callerSideSignature":"C.setA(A)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void C.setA(A)","receiver":{"class":"C","id":1550089733},"args":[{"class":"A","id":1442407170}],"threadId":1,"time":715843640584400}, +{"type":"blockEntry","methodSignature":"C.setA(A)","blockId":0,"incomings":0,"threadId":1,"lineNum":4,"time":715843640595700}, +{"type":"methodCall","callerSideSignature":"A.getD()","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"D A.getD()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":715843640621900}, +{"type":"blockEntry","methodSignature":"A.getD()","blockId":0,"incomings":0,"threadId":1,"lineNum":11,"time":715843640631300}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":11,"time":715843640663300}, +{"type":"methodExit","shortSignature":"A.getD()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"D","id":1118140819},"threadId":1,"time":715843640686400}, +{"type":"methodCall","callerSideSignature":"D.setC(C)","threadId":1,"lineNum":4}, +{"type":"methodEntry","signature":"void D.setC(C)","receiver":{"class":"D","id":1118140819},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":715843640715800}, +{"type":"blockEntry","methodSignature":"D.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715843640730000}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":6,"time":715843640749000}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":715843640786600}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715843640800000}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":6,"time":715843640815400}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640846900}, +{"type":"methodExit","shortSignature":"D.setC(C)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640861900}, +{"type":"methodExit","shortSignature":"C.setA(A)","receiver":{"class":"C","id":1550089733},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640881300}, +{"type":"methodExit","shortSignature":"B.setA(A)","receiver":{"class":"B","id":865113938},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640895800}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640910400}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":715843640928200}, diff --git a/traces/traceSample1.txt b/traces/traceSample1.txt new file mode 100644 index 0000000..46bff28 --- /dev/null +++ b/traces/traceSample1.txt @@ -0,0 +1,51 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":715762700849100}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715762700895700}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":715762703155500}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":715762705579700}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":1550089733},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":715762705660000}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":1550089733},"threadId":1,"time":715762705684200}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":865113938},"value":{"class":"B","id":1550089733},"threadId":1,"lineNum":3,"time":715762705743700}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":715762707583100}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":715762709207900}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1442407170},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":715762709269200}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1442407170},"threadId":1,"time":715762709286400}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1028566121},"value":{"class":"E","id":1442407170},"threadId":1,"lineNum":3,"time":715762709325000}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1028566121},"threadId":1,"time":715762709334800}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":865113938},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":4,"time":715762709384700}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":865113938},"threadId":1,"time":715762709405800}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":865113938},"args":[],"threadId":1,"time":715762709445300}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":7,"time":715762709456000}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":865113938},"container":{"class":"A","id":865113938},"value":{"class":"D","id":1028566121},"threadId":1,"lineNum":7,"time":715762709510800}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":865113938},"container":{"class":"A","id":865113938},"value":{"class":"B","id":1550089733},"threadId":1,"lineNum":7,"time":715762709554000}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":1550089733},"args":[],"threadId":1,"time":715762709598600}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715762709622300}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace4/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":715762711197800}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1118140819},"threadId":1,"time":715762711232100}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":1550089733},"value":{"class":"C","id":1118140819},"threadId":1,"lineNum":6,"time":715762711243500}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":1550089733},"container":{"class":"B","id":1550089733},"value":{"class":"C","id":1118140819},"threadId":1,"lineNum":7,"time":715762711259600}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":1550089733},"returnValue":{"class":"C","id":1118140819},"threadId":1,"time":715762711269400}, +{"type":"methodCall","callerSideSignature":"D.passC(C)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void D.passC(C)","receiver":{"class":"D","id":1028566121},"args":[{"class":"C","id":1118140819}],"threadId":1,"time":715762711292200}, +{"type":"blockEntry","methodSignature":"D.passC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715762711298400}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1028566121},"container":{"class":"D","id":1028566121},"value":{"class":"E","id":1442407170},"threadId":1,"lineNum":6,"time":715762711311500}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1442407170},"args":[{"class":"C","id":1118140819}],"threadId":1,"time":715762711327500}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":715762711335800}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1442407170},"value":{"class":"C","id":1118140819},"threadId":1,"lineNum":6,"time":715762711343200}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":715762711352100}, +{"type":"methodExit","shortSignature":"D.passC(C)","receiver":{"class":"D","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":715762711362600}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":865113938},"returnValue":{"class":"void","id":0},"threadId":1,"time":715762711375300}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":715762711383200}, diff --git a/traces/traceSample2.txt b/traces/traceSample2.txt new file mode 100644 index 0000000..fdd9066 --- /dev/null +++ b/traces/traceSample2.txt @@ -0,0 +1,50 @@ +{"type":"classDef","name":"Main","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/Main.class","loaderPath":"/"}, +{"type":"methodEntry","signature":"public static void Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"args":[{"class":"[Ljava.lang.String;","id":118352462}],"threadId":1,"time":96705546952800}, +{"type":"blockEntry","methodSignature":"Main.main(java.lang.String[])","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":96705547008200}, +{"type":"methodCall","callerSideSignature":"A()","threadId":1,"lineNum":6}, +{"type":"classDef","name":"A","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/A.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public A()","class":"A","args":[],"threadId":1,"time":96705549263300}, +{"type":"methodCall","callerSideSignature":"B()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"B","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/B.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public B()","class":"B","args":[],"threadId":1,"time":96705551742300}, +{"type":"methodCall","callerSideSignature":"C()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"C","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/C.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public C()","class":"C","args":[],"threadId":1,"time":96705553290500}, +{"type":"constructorExit","shortSignature":"C()","returnValue":{"class":"C","id":1550089733},"threadId":1,"time":96705553346300}, +{"type":"fieldSet","fieldName":"B.c","container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":3,"time":96705553411200}, +{"type":"constructorExit","shortSignature":"B()","returnValue":{"class":"B","id":865113938},"threadId":1,"time":96705553432700}, +{"type":"fieldSet","fieldName":"A.b","container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":3,"time":96705553482900}, +{"type":"methodCall","callerSideSignature":"D()","threadId":1,"lineNum":4}, +{"type":"classDef","name":"D","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/D.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public D()","class":"D","args":[],"threadId":1,"time":96705555165500}, +{"type":"methodCall","callerSideSignature":"E()","threadId":1,"lineNum":3}, +{"type":"classDef","name":"E","path":"/C:/Users/Hongo Aki/runtime-EclipseApplication/TestTrace2/bin/E.class","loaderPath":"/"}, +{"type":"constructorEntry","signature":"public E()","class":"E","args":[],"threadId":1,"time":96705556958900}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"---","id":0},"threadId":1,"lineNum":3,"time":96705557015100}, +{"type":"constructorExit","shortSignature":"E()","returnValue":{"class":"E","id":1028566121},"threadId":1,"time":96705557026000}, +{"type":"fieldSet","fieldName":"D.e","container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":3,"time":96705557070300}, +{"type":"constructorExit","shortSignature":"D()","returnValue":{"class":"D","id":1118140819},"threadId":1,"time":96705557108300}, +{"type":"fieldSet","fieldName":"A.d","container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":4,"time":96705557149800}, +{"type":"constructorExit","shortSignature":"A()","returnValue":{"class":"A","id":1442407170},"threadId":1,"time":96705557163400}, +{"type":"methodCall","callerSideSignature":"A.m()","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void A.m()","receiver":{"class":"A","id":1442407170},"args":[],"threadId":1,"time":96705557199000}, +{"type":"blockEntry","methodSignature":"A.m()","blockId":0,"incomings":0,"threadId":1,"lineNum":6,"time":96705557212300}, +{"type":"fieldGet","fieldName":"A.d","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"D","id":1118140819},"threadId":1,"lineNum":6,"time":96705557232500}, +{"type":"fieldGet","fieldName":"A.b","this":{"class":"A","id":1442407170},"container":{"class":"A","id":1442407170},"value":{"class":"B","id":865113938},"threadId":1,"lineNum":6,"time":96705557257900}, +{"type":"methodCall","callerSideSignature":"D.passB(B)","threadId":1,"lineNum":6}, +{"type":"methodEntry","signature":"void D.passB(B)","receiver":{"class":"D","id":1118140819},"args":[{"class":"B","id":865113938}],"threadId":1,"time":96705557291200}, +{"type":"blockEntry","methodSignature":"D.passB(B)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":96705557306000}, +{"type":"methodCall","callerSideSignature":"B.getC()","threadId":1,"lineNum":5}, +{"type":"methodEntry","signature":"C B.getC()","receiver":{"class":"B","id":865113938},"args":[],"threadId":1,"time":96705557332200}, +{"type":"blockEntry","methodSignature":"B.getC()","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":96705557342300}, +{"type":"fieldGet","fieldName":"B.c","this":{"class":"B","id":865113938},"container":{"class":"B","id":865113938},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":96705557367300}, +{"type":"methodExit","shortSignature":"B.getC()","receiver":{"class":"B","id":865113938},"returnValue":{"class":"C","id":1550089733},"threadId":1,"time":96705557398900}, +{"type":"fieldGet","fieldName":"D.e","this":{"class":"D","id":1118140819},"container":{"class":"D","id":1118140819},"value":{"class":"E","id":1028566121},"threadId":1,"lineNum":6,"time":96705557426000}, +{"type":"methodCall","callerSideSignature":"E.setC(C)","threadId":1,"lineNum":7}, +{"type":"methodEntry","signature":"void E.setC(C)","receiver":{"class":"E","id":1028566121},"args":[{"class":"C","id":1550089733}],"threadId":1,"time":96705557456900}, +{"type":"blockEntry","methodSignature":"E.setC(C)","blockId":0,"incomings":0,"threadId":1,"lineNum":5,"time":96705557472500}, +{"type":"fieldSet","fieldName":"E.c","container":{"class":"E","id":1028566121},"value":{"class":"C","id":1550089733},"threadId":1,"lineNum":5,"time":96705557485400}, +{"type":"methodExit","shortSignature":"E.setC(C)","receiver":{"class":"E","id":1028566121},"returnValue":{"class":"void","id":0},"threadId":1,"time":96705557502000}, +{"type":"methodExit","shortSignature":"D.passB(B)","receiver":{"class":"D","id":1118140819},"returnValue":{"class":"void","id":0},"threadId":1,"time":96705557521700}, +{"type":"methodExit","shortSignature":"A.m()","receiver":{"class":"A","id":1442407170},"returnValue":{"class":"void","id":0},"threadId":1,"time":96705557554500}, +{"type":"methodExit","shortSignature":"Main.main(java.lang.String[])","receiver":{"class":"Main","id":0},"returnValue":{"class":"void","id":0},"threadId":1,"time":96705557570600},