1 /* 2 * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved. 3 * 4 * This file is part of the Lock Contention Tracing Subsystem for the HotSpot 5 * Virtual Machine, which is developed at Christian Doppler Laboratory on 6 * Monitoring and Evolution of Very-Large-Scale Software Systems. Please 7 * contact us at <http://mevss.jku.at/> if you need additional information 8 * or have any questions. 9 * 10 * This code is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 only, as 12 * published by the Free Software Foundation. 13 * 14 * This code is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * version 2 for more details (a copy is included in the LICENSE file that 18 * accompanied this code). 19 * 20 * You should have received a copy of the GNU General Public License version 21 * 2 along with this work. If not, see <http://www.gnu.org/licenses/>. 22 * 23 */ 24 package sun.evtracing.parser.metadata; 25 26 import java.util.Comparator; 27 import java.util.Iterator; 28 29 import sun.evtracing.parser.metadata.JavaMethod; 30 import sun.evtracing.parser.metadata.JavaStack; 31 import sun.evtracing.parser.metadata.JavaStackFrame; 32 import sun.evtracing.parser.metadata.MethodFilter; 33 34 /** 35 * Compares stack traces using only method and class names, disregarding class 36 * loaders and identifiers. 37 */ 38 public class JavaStackDeepComparator implements Comparator<JavaStack> { 39 40 public static final JavaStackDeepComparator INSTANCE = new JavaStackDeepComparator(); 41 42 public static JavaStackDeepComparator forTopMethodOnly(MethodFilter filter) { 43 return new JavaStackDeepComparator(filter); 44 } 45 46 private final boolean topMethodOnly; 47 private final MethodFilter filter; 48 49 private JavaStackDeepComparator() { 50 this.topMethodOnly = false; 51 this.filter = null; 52 } 53 54 private JavaStackDeepComparator(MethodFilter filter) { 55 assert (filter != null); 56 this.topMethodOnly = true; 57 this.filter = filter; 58 } 59 60 @Override 61 public int compare(JavaStack o1, JavaStack o2) { 62 if (o1 == o2) { 63 return 0; 64 } 65 if (o1.isSet() && !o2.isSet()) { 66 return 1; 67 } 68 if (!o1.isSet() && o2.isSet()) { 69 return -1; 70 } 71 if (!o1.isSet() && !o2.isSet()) { 72 return 0; 73 } 74 if (o1.isUnknown() && o2.isUnknown()) { 75 return System.identityHashCode(o1) - System.identityHashCode(o2); 76 } 77 if (o1.isUnknown() && !o2.isUnknown()) { 78 return -1; 79 } 80 if (!o1.isUnknown() && o2.isUnknown()) { 81 return 1; 82 } 83 if (o1.frameCount() == 0 || o2.frameCount() == 0 || (!topMethodOnly && o1.frameCount() != o2.frameCount())) { 84 return (o1.frameCount() - o2.frameCount()); 85 } 86 if (topMethodOnly) { 87 JavaMethod m1 = filter.getFirstUnmatched(o1); 88 JavaMethod m2 = filter.getFirstUnmatched(o2); 89 return JavaMethodDeepComparator.INSTANCE.compare(m1, m2); 90 } 91 int result; 92 Iterator<JavaStackFrame> i1 = o1.iterator(); 93 Iterator<JavaStackFrame> i2 = o2.iterator(); 94 do { 95 JavaStackFrame f1 = i1.next(); 96 JavaStackFrame f2 = i2.next(); 97 result = JavaMethodDeepComparator.INSTANCE.compare(f1.method(), f2.method()); 98 /*if (result == 0) { 99 result = f1.bci() - f2.bci(); 100 }*/ 101 } while (result == 0 && i1.hasNext()); 102 return result; 103 } 104 105 }