正在加载图片...
141:16 Yue Li,Tian Tan,Anders Moller,and Yannis Smaragdakis 1 class BufferedReader{ //Usage Code Reader in: 9 InputStreamReader isReader new InputStreamReader () BufferedReader(Reader in){ 10 BufferedReader reader1 new BufferedReader(isReader): this.inin; 11 reader1.close(); } 12 FileReader fReader new FileReader(): 6 void close()[in.close(); 13 BufferedReader reader2 new BufferedReader(fReader): 7} 14 //reader2.close(); Fig.9.Example of the no-out flow case Comparing ZIPPER with the conventional pointer analysis 2obj,we see that ZIPPER is able to achieve nearly identical precision as 2obj for every metric in every program.In summary,on average,98.8%of the precision of 2obj can be preserved considering all client analyses.Specifically, the average number for each client analysis is 96.8%for #fail-cast,98.9%for #poly-call,99.8%for #reach-mtd and 99.7%for #call-edge. ZIPPER can produce such great precision because it is designed according to its precision-guided principle:all the methods that are involved in the three basic flows(direct,wrapped,and unwrapped flows),or their combinations,will be analyzed context-sensitively.Since the three flows capture the essence of value flows in Java programs where imprecision may arise through method calls(as explained in Section 2),most context-related imprecision can be discovered by ZIPPER.However,on average,ZIPPER still misses 1.2%of the precision.Although these cases are rare and it is extremely hard to enumerate all of them,it is informative to examine some of them to understand the capabilities of ZIPPER more comprehensively.Next,let us take two examples to illustrate some of the rare cases where ZIPPER loses precision. The No-Out Flow Case.This case is observed in real code in our experiments,and we simplify the code as in Figure 9.The InputStreamReader object(created in line 9)and the FileReader object (created in line 12)flow into the IN method BufferedReader(a constructor)through parameter in (line 3).The objects are stored(line 4)and further loaded and become the receiver objects of the virtual call in.close()(line 6).The flow does not flow out through an Our method and thus the two methods in class BufferedReader are analyzed context-insensitively.As a result,the virtual call in line 6 will not be disambiguated into a monomorphic call,resulting in precision loss in the devirtualization analysis client.Note that there would be no observable(in our metrics)precision loss compared to a conventional object-sensitive analysis if the call in line 14 existed(i.e.,if it were not commented out).The call site on line 6 is truly polymorphic,and can be exercised for multiple receiver objects,as the addition of line 14 demonstrates. The Parameter-Out Flow Case.A second instance where ZIPPER void m(A input.B output){ loses precision,this time made up but interesting theoretically,output.field=input: is shown in Figure 10.An IN method m of some class accepts } two parameters input and output,and unlike any of our three m(a,b); //rare precision loss patterns,there is no flow out of an Our method.b.setfield(a): //common Instead,the flowing-in object through input flows out through Fig.10.Example of the parameter- another parameter output via a store operation,output.field out flow case. input.Thus,ZIPPER reports m as non-precision-critical.However,if m is analyzed context- insensitively,the flowing-in objects may be merged in the wrapper object(say w,which is pointed to by output)and imprecision would be introduced when the objects are then loaded from w outside ITo further validate the generality of ZIPPER's precision-guided capability,we also compare ZIPPER with a 2-type-sensitive pointer analysis(2type),another key context sensitivity for Java which is less precise but faster than 2obj.On average, 99.1%of the precision of 2type is preserved by ZiPPER;the detailed results are shown in Table 6 in Appendix A. Proc.ACM Program.Lang.,Vol.2,No.OOPSLA,Article 141.Publication date:November 2018.141:16 Yue Li, Tian Tan, Anders Mùller, and Yannis Smaragdakis 1 2 3 4 5 6 7 class BufferedReader{ Reader in; BufferedReader(Reader in){ this.in = in; } void close(){in.close();} } 8 9 10 11 12 13 14 //Usage Code InputStreamReader isReader = new InputStreamReader(); BufferedReader reader1 = new BufferedReader(isReader); reader1.close(); FileReader fReader = new FileReader(); BufferedReader reader2 = new BufferedReader(fReader); //reader2.close(); Fig. 9. Example of the no-out flow case. Comparing Zipper with the conventional pointer analysis 2obj, we see that Zipper is able to achieve nearly identical precision as 2obj for every metric in every program. In summary, on average, 98.8% of the precision of 2obj can be preserved considering all client analyses.1 Specifically, the average number for each client analysis is 96.8% for #fail-cast, 98.9% for #poly-call, 99.8% for #reach-mtd and 99.7% for #call-edge. Zipper can produce such great precision because it is designed according to its precision-guided principle: all the methods that are involved in the three basic flows (direct, wrapped, and unwrapped flows), or their combinations, will be analyzed context-sensitively. Since the three flows capture the essence of value flows in Java programs where imprecision may arise through method calls (as explained in Section 2), most context-related imprecision can be discovered by Zipper. However, on average, Zipper still misses 1.2% of the precision. Although these cases are rare and it is extremely hard to enumerate all of them, it is informative to examine some of them to understand the capabilities of Zipper more comprehensively. Next, let us take two examples to illustrate some of the rare cases where Zipper loses precision. The No-Out Flow Case. This case is observed in real code in our experiments, and we simplify the code as in Figure 9. The InputStreamReader object (created in line 9) and the FileReader object (created in line 12) flow into the In method BufferedReader (a constructor) through parameter in (line 3). The objects are stored (line 4) and further loaded and become the receiver objects of the virtual call in.close() (line 6). The flow does not flow out through an Out method and thus the two methods in class BufferedReader are analyzed context-insensitively. As a result, the virtual call in line 6 will not be disambiguated into a monomorphic call, resulting in precision loss in the devirtualization analysis client. Note that there would be no observable (in our metrics) precision loss compared to a conventional object-sensitive analysis if the call in line 14 existed (i.e., if it were not commented out). The call site on line 6 is truly polymorphic, and can be exercised for multiple receiver objects, as the addition of line 14 demonstrates. void m(A input,B output) { output.field = input; } m(a, b); //rare b.setField(a); //common Fig. 10. Example of the parameter￾out flow case. The Parameter-Out Flow Case. A second instance where Zipper loses precision, this time made up but interesting theoretically, is shown in Figure 10. An In method m of some class accepts two parameters input and output, and unlike any of our three precision loss patterns, there is no flow out of an Out method. Instead, the flowing-in object through input flows out through another parameter output via a store operation, output.field = input. Thus, Zipper reports m as non-precision-critical. However, if m is analyzed context￾insensitively, the flowing-in objects may be merged in the wrapper object (say w, which is pointed to by output) and imprecision would be introduced when the objects are then loaded from w outside 1To further validate the generality of Zipper’s precision-guided capability, we also compare Zipper with a 2-type-sensitive pointer analysis (2type), another key context sensitivity for Java which is less precise but faster than 2obj. On average, 99.1% of the precision of 2type is preserved by Zipper; the detailed results are shown in Table 6 in Appendix A. Proc. ACM Program. Lang., Vol. 2, No. OOPSLA, Article 141. Publication date: November 2018
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有