Top Banner
A Feasibility Study of Loop Bound Analysis for Loops with Disjunctive Guards Nick Gubbels Student Number: 0710288 [email protected] Master Thesis Computer Science Thesis Number: 666 November 2012 Supervisors: Prof. dr. Marko van Eekelen Rody Kersten MSc Dr. Sjaak Smetsers (Reader)
142

A Feasibility Study of Loop Bound Analysis for Loops with ...

May 01, 2023

Download

Documents

Khang Minh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: A Feasibility Study of Loop Bound Analysis for Loops with ...

A Feasibility Study of Loop BoundAnalysis for Loops with Disjunctive

Guards

Nick GubbelsStudent Number: [email protected]

Master Thesis Computer ScienceThesis Number: 666November 2012

Supervisors:Prof. dr. Marko van Eekelen

Rody Kersten MScDr. Sjaak Smetsers (Reader)

Page 2: A Feasibility Study of Loop Bound Analysis for Loops with ...

ii

Page 3: A Feasibility Study of Loop Bound Analysis for Loops with ...

Contents

1 Introduction 1

1.1 AHA project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 CHARTER project . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 ResAna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.4 Loop Bound Analysis . . . . . . . . . . . . . . . . . . . . . . . . 3

1.5 Goal of the thesis . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.6 Related work on Loop Bound Analysis . . . . . . . . . . . . . . . 4

1.7 Thesis outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Loop Bound Analysis with Polynomial Interpolation 7

2.1 Basic method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.1.1 Extract and instrument the loop . . . . . . . . . . . . . . 8

2.1.2 Polynomial interpolation . . . . . . . . . . . . . . . . . . . 9

2.1.3 Test node generation . . . . . . . . . . . . . . . . . . . . . 10

2.1.4 Inferring a ranking function . . . . . . . . . . . . . . . . . 10

2.2 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.2.1 Step size . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.2.2 Branch-splitting . . . . . . . . . . . . . . . . . . . . . . . 12

2.3 Working examples . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.3.1 Linear multivariate example . . . . . . . . . . . . . . . . . 13

2.3.2 Quadratic example . . . . . . . . . . . . . . . . . . . . . . 16

2.4 Soundness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 Loop Bound Analysis for Loops with Disjunctive Guards 19

3.1 Piece-wise ranking functions . . . . . . . . . . . . . . . . . . . . . 19

3.1.1 Condition Jumping . . . . . . . . . . . . . . . . . . . . . . 21

3.2 The challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.2.1 Example of condition jumping . . . . . . . . . . . . . . . 21

3.2.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.2.3 Multi-jumping . . . . . . . . . . . . . . . . . . . . . . . . 23

3.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.3.1 Symbolic Execution and SMT solvers . . . . . . . . . . . 24

3.3.2 Binary Decision Diagrams . . . . . . . . . . . . . . . . . . 26

3.3.3 Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . 28

iii

Page 4: A Feasibility Study of Loop Bound Analysis for Loops with ...

iv CONTENTS

4 Feasibility of Loop Bound Analysis for Loops with DisjunctiveGuards in Practice 314.1 Global Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.1.1 Apache harmony . . . . . . . . . . . . . . . . . . . . . . . 314.1.2 Caliper . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.1.3 CDx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.1.4 Eclipse IDE . . . . . . . . . . . . . . . . . . . . . . . . . . 324.1.5 GA-Playground . . . . . . . . . . . . . . . . . . . . . . . . 324.1.6 GWT-java-math . . . . . . . . . . . . . . . . . . . . . . . 334.1.7 JAGA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.1.8 Data Structures and Algorithm Analysis . . . . . . . . . . 334.1.9 Lightweight Java Game Library . . . . . . . . . . . . . . . 334.1.10 Java-ML . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.1.11 JavaNCSS . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.1.12 Jembench . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.1.13 JGAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.1.14 Jmatbench . . . . . . . . . . . . . . . . . . . . . . . . . . 344.1.15 NeoBio . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.1.16 Weka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.1.17 Totals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2 Detailed Feasibility Study . . . . . . . . . . . . . . . . . . . . . . 354.2.1 Detailed Loop Discussion . . . . . . . . . . . . . . . . . . 35

4.3 Categories of Loops with Disjunctive Guards . . . . . . . . . . . 594.3.1 Conjunctive Normal Form Elimination . . . . . . . . . . . 604.3.2 Condition Jumping check error . . . . . . . . . . . . . . . 614.3.3 Iterating through data structures with size field or method 624.3.4 Iterating through other data structures . . . . . . . . . . 644.3.5 Breaks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664.3.6 Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664.3.7 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664.3.8 Unpredictable updates . . . . . . . . . . . . . . . . . . . . 664.3.9 Loops depending on non-numerical values . . . . . . . . . 67

4.4 Summary of the proposed improvements/extensions . . . . . . . 674.5 Feasibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5 Future work 695.1 Improved branch-splitting . . . . . . . . . . . . . . . . . . . . . . 69

5.1.1 Using update functions . . . . . . . . . . . . . . . . . . . 705.2 Loop context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

6 Conclusion 73

A Loops used in the detailed feasibility study 79A.1 While-loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79A.2 For-loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

Page 5: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 1

Introduction

In software engineering a program needs to do what it is supposed to do. Toensure this, software should be tested thoroughly. However, for safety-critical,real-time and embedded systems, more aspects of software have to be consideredin order to be sure the software is correct. A small bug in the program couldlead to fatal situations, e.g. if the software of an air plane reach an error state.

Testing gives insight in what the output will be for given input, but onlyfor the input which is used in the test cases. To get information about morecases, a model of the program can be created and tested for some properties.This is called Model-based testing or model checking and it gives informationover larger sets of input/output. However, in the case of safety critical softwaresystems, it is even desirable to have proofs of certain properties.Tthis is doneby theorem proving. Even though theorem proving is most desirable, it takesmore effort than model checking, which by itself takes more effort than testing.For this reason most software systems are only tested.

Additionally, testing only addresses the functional aspects of the software,i.e. does the software do what it is supposed to do given this input? However,in the case of safety-critical, real-time and embedded systems, the resources ofthe system are most likely to be limited; such systems are in general scarceof memory and processing power. It is important that the software of thosesystems does not exceed the boundaries of its resources, since that could leadto a system crash.

Therefore, it is important to test the system’s use of the resources, or more-over even prove that the system does not exceed its boundaries. This is calledresource analysis. One such analysis is Loop Bound Analysis, which focuses onthe number of iterations of a given loop and tries to infer an upper bound forthat. This information gives insight in the processing time used by the program.Furthermore, it can be used as a base for a termination proof, since if a loophas an upper bound in the number of iterations, it will not iterate infinite manytimes.

In the following sections a few projects on resource analysis are described.

1

Page 6: A Feasibility Study of Loop Bound Analysis for Loops with ...

2 CHAPTER 1. INTRODUCTION

1.1 AHA project

Amortised Heap Analysis (AHA) project (as described in [32]) was a projectwhich focused on heap consumption. The target of the project was to developa method to infer non-linear bounds on the heap consumption of a (lazy) func-tional language.

In [30], [33], [29], [31] and [28] Shkaravska et al. describe a method for sizeanalysis. This method introduces a type system with size annotations. Forexample, consider the following function type:

Ln Lm → Ln+m

This represents a function, which has two lists as input, which contain n andm elements respectively. The result is a list of size n+m. This type is typicalfor an append function.

The type system with size annotations has been created for a small functionallanguage presented in [30, 33, 29, 31, 28]. The size analysis method consists oftwo parts: type inference and type checking. Note that a type in this contextcontains the size in the number of elements. For type inference the authorsdescribe a method using testing and polynomial interpolation. To infer the typeof some functions, test nodes with known types are created and the functionsare executed for those test nodes. Then the results of the functions are used toinfer a polynomial, which specifies the type of the function.

Since the method above depends on the selection of test nodes, the methodis not sound. Therefore, a type checking method is developed by the authors.They specify formal rules for type checking with size annotations of programs inthe functional language presented in [30, 33, 29, 31, 28]. These rules constructa formal derivation tree, which is a proof of the types and sizes of the functions.

1.2 CHARTER project

The CHARTER (Critical and High Assurance Requirements Transformed throughEngineering Rigour) project 1 was an ARTEMIS Embedded Computing Sys-tems Initiative project. The target of the project was to develop concepts,methods and tools to assist developers of critical systems to improve the devel-opment, verification and certification of software.

Results of the project vary from theoretical methods to fully usable toolsfor both development and verification of software. JamaicaVM, for example,is one of the development tools. It is a Java virtual machine implementationdeveloped by Aicas especially designed for real-time software 2 and can be usedto run and compile Java software. Verification tools are for example ResAna andKeY, which are explained in more depth in the following sections.

The contribution of the Radboud University in the CHARTER project con-sisted of two parts: 1) develop a method for resource analysis and 2) to createa formal specification of Real-Time Java Libraries. The first will be explainedin more detail in the following sections.

1For more information: http://charterproject.ning.com/2For more information, see http://www.aicas.com/jamaica.html

Page 7: A Feasibility Study of Loop Bound Analysis for Loops with ...

1.3. RESANA 3

1.3 ResAna

One of the results of the CHARTER project is the ResAna tool, as presentedby Kersten et al. in [20]. The ResAna tool consists of various resource analysismethods, e.g. heap/stack size analysis and Loop Bound Analysis. For the heapand stack size analysis, it makes use of a tool called COSTA (COst and Termi-nation Analyser) to extract the heap size and another tool Veriflux to extractstack size. Veriflux is an industrial tool by Aicas and is like ResAna part of theCHARTER Project. Veriflux is an automatic static code analysis tool.

The method behind COSTA is described in an article by Albert et al. [3].The method analyses Java byte code to extract certain properties, e.g. it doescost analysis given various cost models. One of such models is the heap costmodel, i.e. what is an upper bound for the size of the heap given a piece ofcode? Another cost model is the number of instructions, this is a model onexecution length of a piece of code, i.e. what is an upper bound on the numberof instructions executed. In combination with the cost analysis, the tool triesto prove termination as well. Indeed if an upper bound on the number ofinstructions exists and it is finite, termination can be guaranteed. An extensionof this method is proposed by Montenegro et al. in [24], using the polynomialinterpolation method of [30, 33, 29, 31, 28]. In [4], Albert et al. present amethod to use COSTA in combination with verification tool KeY [1, 6].

1.4 Loop Bound Analysis

Loop Bound Analysis is another part of the ResAna tool and methods. Thisfocuses on the number of iterations of loops. A basic method of Loop BoundAnalysis using polynomial interpolation is presented by Shkaravska et al. in[27] and it is inspired by the method of the same authors for polynomial sizeanalysis described in [30, 33, 29, 31, 28]. This method extracts a loop fromthe source code and instruments it with variables in order to do tests on thenumber of iterations. Given the results it infers a symbolic ranking function,which specifies an upper bound on the number of iterations of the loop. Sincepolynomial interpolation is used, the method in not limited to inferring linearbounds, unlike most other methods (presented in Section 1.6), which are limitedto linear bounds. The loop bound analysis method by Shkaravska et al. [27] isimplemented as a prototype in the ResAna tool.

The basic Loop Bound Analysis method with polynomial interpolation onlyinfers upper bounds for loops with conditions over conjunctions of numerical(in)equalities. In order to handle disjunctions as well, the method is extendedwith piece-wise ranking functions, which in essence splits the disjunctions in setsof conjunctions (pieces) for every possible case. However, in [21] Kersten andVan Eekelen describe a challenge with this method: condition jumping. Themethod assumes the different pieces obtained by splitting to be independent.However, this is not true in some cases. Therefore, a solution to this problemis described in [21].

Page 8: A Feasibility Study of Loop Bound Analysis for Loops with ...

4 CHAPTER 1. INTRODUCTION

1.5 Goal of the thesis

This research focuses on Loop Bound Analysis on loops with disjunctive guardsin practice. As described above, methods have been proposed, but how accurateand applicable are they in practice and what is needed to improve/extend thosemethods?

In this study the feasibility of Loop Bound Analysis for loops with disjunc-tive guards is examined. In other words how feasible is Loop Bound Analysisfor loops with disjunctive guards? The base of this study is the Loop BoundAnalysis method using polynomial interpolation by Shkaravska et al. [27] andthe extension for disjunctive guards by Kersten and Van Eekelen [21].

The following steps have been performed in order to answer the question:how feasible is Loop Bound Analysis for loops with disjunctive guards?

• Implement the method by Kersten and Van Eekelen [21] in the ResAna tool.

• A global study on loops with disjunctive guards: how many loops containdisjunctive guards?

• A detailed study on loops with disjunctive guards from a large Java pro-gram: what would be the optimal ranking function for the loop and howcan it be derived?

• Given the results of the detailed study, the loops have been sorted intocategories and for each category a solution has been proposed in order toderive a ranking function for loops in that category, if possible. Otherwisean explanation of why this is impossible has been given.

1.6 Related work on Loop Bound Analysis

De Michiel et al. present a method for Loop Bound Analysis for C programs in[11]. It is very different in comparison with the method described here. Insteadof a test-based approach, this method analyses the syntax and creates a contexttree. Using that it performs execution flow analysis and abstract interpretation.

Ermedahl et al. describe another method for Loop Bound Analysis in [13].It uses program slicing, abstract interpretation and invariant analysis. It hasbeen implemented in the SWEET tool (SWEdish Execution time Tool), whichanalyses ANSI-C programs.

Gulwani et al. present in [17] a series of different methods for loop boundanalysis. These methods include methods for nested loops and loops dependingon data structures. In [16] Gulwani et al. describe loop bound analysis basedon control-flow refinement and progress invariants. In [18] Gulwani and Zulegerpresent another method for loop bound analysis using abstract interpretationand a non-iterative proof-based technique.

Fulara and Jakubczyk describe in [15] a method to derive ranking functionsfor for-loops. The method uses pattern recognition and derives the rankingfunctions using predefined patterns. Therefore, this method is less general thanthe method presented by Shkaravska et al. [27], which is considered for thisresearch.

Hunt et al. describe a method for Worst Case Execution Time Analysis usingData Flow in [19]. It also addresses ranking function and their description in

Page 9: A Feasibility Study of Loop Bound Analysis for Loops with ...

1.7. THESIS OUTLINE 5

Java Modeling Language(JML) and the verification of those ranking functionsusing KeY [1, 6].

Podelski and Rybalchenko describe in [25] a method for deriving linear rank-ing functions for loops. This method is complete, i.e. if there exists a linearranking function for a loop, the method will find it.

Lokuciejewski et al. present in [23] a static analysis method for Loop BoundAnalysis using abstract interpretation. It also uses program slicing for efficiency.However, the result of this method for a loop is a concrete/numerical boundinstead of a symbolic bound.

1.7 Thesis outline

In Chapter 2 basic Loop Bound Analysis using polynomial interpolation [27]is described. This is followed by a description of loop bound analysis usingpolynomial interpolation for loops with disjunctive guards [21] in Chapter 3.Then a feasibility study has been done in Chapter 4. This feasibility study isdivided in three main parts: a) a global study in Section 4.1, b) a detailed studyin Section 4.2 and c) a study on what extensions are needed to derive rankingfunctions for loops with disjunctive guards in Section 4.3. Followed by futurework in Chapter 5 and finally in Chapter 6 the conclusion.

Page 10: A Feasibility Study of Loop Bound Analysis for Loops with ...

6 CHAPTER 1. INTRODUCTION

Page 11: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 2

Loop Bound Analysis withPolynomial Interpolation

The purpose of Loop Bound Analysis is deriving a ranking function for a givenloop. In this context a ranking function is a symbolic upper bound on thenumber of iterations of a loop. A method to derive a ranking function for agiven loop is described by Shkaravska et al. in [27].

The basic method will be described first, followed by an introduction to someextensions and this chapter concludes with some working examples.

2.1 Basic method

Consider the loop in Listing 2.1.

Listing 2.1: Example class

1 public class Example{2 public void method1 ( int i ) {3 //do something4 while ( i < 10)5 i ++;6 //do something e l s e7 }8 }

A ranking function for this loop is:

{10− i if i > 00 otherwise

This means that if, e.g., i = 0, that there will be at most 10 iterationsaccording to the ranking function. This is the most precise upper bound forthis loop. However, the following ranking function, which overestimates thenumber of iterations, is also valid, since it is an upper bound:

7

Page 12: A Feasibility Study of Loop Bound Analysis for Loops with ...

8 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

{100− i if i > 00 otherwise

In [27] a method is described to derive ranking functions for loops automat-ically. This method is based on testing, i.e. executing the loop given certaininput values in order to infer a ranking function. The method consists of thefollowing steps:

1. Extract and instrument the loop

2. Test node generation

3. Inferring a ranking function

In the following sections the method will be explained using the loop inListing 2.1.

2.1.1 Extract and instrument the loop

Since the loop will be executed to test the number of iterations given certaininput values, the loop is extracted from its context, i.e. remove all statementsbefore and after the loop. By extracting the loop and placing it in a testingsetting, there is more control over the variables on which the loop dependsthan there would be when executing the whole program. Since in this case thevariables used in the loop can be manipulated directly. However, this is notpossible when the whole program is executed, since the variables in the loop,can be dependent of other variables, i.e. the variables used in the loop cannot bemanipulated directly, but through manipulating other variables, which makesit more difficult. Moreover it creates a weaker testing method, because thevariables can only be manipulated indirectly, i.e. the values of the variables arerestricted to which values are possible through the variables they depend on.For example, variable j is created using variable i: j = 2i. Then the values ofj are restricted to even numbers.

After extracting it from its context, the loop is instrumented with a counter,which will be returned when the loop is finished, i.e. after finishing the loop itreturns the number of iterations. Therefore, a new version of the class will begenerated, this is shown in Listing 2.2.

Listing 2.2: Instrumented loop

1 public class Example{2 public void method1 ( int i ) {3 int count = 0 ;4 while ( i < 10) {5 i ++;6 count++;7 }8 return count ;9 }

10 }

Page 13: A Feasibility Study of Loop Bound Analysis for Loops with ...

2.1. BASIC METHOD 9

2.1.2 Polynomial interpolation

Before explaining the next step, test node generation, some explanation is neededabout polynomial interpolation. Polynomial interpolation is the interpolationof given data points by a polynomial, i.e. derive a polynomial that goes throughthose points. Polynomial interpolation itself will be used in the last step of themethod: deriving the polynomial, but the conditions presented below are usedin the next step.

Deriving a polynomial is finding values for the coefficients of the polynomial.For example, for a polynomial with one variable and degree d

p(z) = a0 + a1z + · · ·+ adzd

it is finding values for a1, . . . , ad, in such a way that polynomial p interpolatesthe test results.

However, there are certain conditions on the test data, in order for thepolynomial to exist and to be unique. In the case of a polynomial with onevariable and of degree d (as in the polynomial shown above), at least d + 1different data points are needed. The system of d + 1 pairwise different pointscan be written as follows in a matrix form:

1 z0 . . . zd−10 zd01 z1 . . . zd−11 zd1...

.... . .

......

1 zd−1 . . . zd−1d−1 zdd−11 zd . . . zd−1d zdd

a0a1...

ad−1ad

=

p(z0)p(z1)

...p(zd−1)p(zd)

A matrix in the form of Ai,j = zj−1i , like the matrix above, is called a

Vandermonde matrix. For pairwise different points z0, . . . , zd, the matrix has anon-zero determinant, which is called a Vandermonde determinant. Because thedeterminant has a non-zero value, there exists a unique solution to the system,i.e. a unique polynomial, which interpolates the data points.

However, for multivariate systems the test data need to satisfy more complexconditions in order to get a unique interpolating polynomial. First of all apolynomial p(z1, . . . , zk) of degree d and with k variables, i.e. dimension k, has

Nkd =

(d+ kk

)coefficients. In [8] three node configurations are introduced,

under which the Vandermonde determinant is non-zero. The simplest one isNode Configuration A. For the 2-dimensional case NCA is defined as follows:

Set W ⊂ R2 exists of N2d nodes. W lies in a 2-dimensional NCA if there

exists lines γ1, . . . , γd+1 in R2, in such a way that d+ 1 nodes of W lie on γd+1,d nodes on γd\γd+1, . . . , and 1 node lies on line γ1\(γ2 ∪ · · · ∪ γd+1).

NCA for any k > 2 is defined by induction on k:

Set W ⊂ Rk exists of Nkd nodes. W lies in a k-dimensional NCA if, for

any 0 ≤ i ≤ d, there is a (k − 1)-dimensional hyperplane, in such a way that it

Page 14: A Feasibility Study of Loop Bound Analysis for Loops with ...

10 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

contains Nk−1d−i nodes, which are on a (k− 1)-dimensional NCA for degree d− i

and these nodes are not lying on any other hyperplane.

2.1.3 Test node generation

The next step in the process of inferring a ranking function, is to generatetest nodes. In the previous step, the loop was instrumented with a counter.Therefore it can be executed with different input values and it will return thenumber of iterations of the loop for each test node, which is a set of input valuesused for one test execution.

As said in the previous section, in order to have a unique solution for thesystem of equations using polynomial interpolation, the test data needs to bein NCA. However, for test nodes used to derive a ranking function, there isone extra condition. The test nodes need to satisfy the loop guard as well.Otherwise it would have no sense to execute the test, as it would result in noiterations.

The example (in Listing 2.1) has a loop (guard) with just one variable.Therefore, the only requirement is, that there need to be d+ 1 different nodes,where d is the expected degree of the polynomial. Given the loop conditioni < 10, it is reasonable to expect a degree of 1, i.e. linear. Therefore, twodifferent nodes are needed:

i number of iterations0 101 9

2.1.4 Inferring a ranking function

After the test nodes are generated and the tests are executed, a polynomial canbe inferred, i.e. the system of equations need to be solved. The example hasone variable and is of degree 1, so the polynomial has the following form:

a0 + a1i = p(i)

Therefore, the system is as follows:

a0 = 10

a0 + a1 = 9

This gives that a0 = 10 and a1 = −1. Therefore, the polynomial interpolat-ing the test nodes is:

p(i) = 10− i

This is the main part of the inferred ranking function. However, there isstill another case for which this ranking function is not correct. This is the case

Page 15: A Feasibility Study of Loop Bound Analysis for Loops with ...

2.2. EXTENSIONS 11

where the loop is never entered, i.e. when the loop condition is not satisfied.Therefore, the inferred ranking function is:

{10− i if i > 00 otherwise

The method is also implemented in a tool: ResAna, which is part of theCHARTER Project1.

2.2 Extensions

In this section some extensions are presented as given in [27].

2.2.1 Step size

In the example in listing 2.1 the loop variable is incremented by 1. However,there are cases where the loop variable is incremented (or decremented) withanother value. The loop in Listing 2.3 is such a case.

Listing 2.3: A loop with step size 4

1 while ( i < 20)2 i += 4 ;

Since there is only one variable in the loop and the expected degree is 1,there need to be N1

1 = 2 test nodes to interpolate the following polynomial inthe data:

ai+ b = p(i)

The following test nodes could be used:

i = 0

i = 1

This would give the following results:

i p(i)0 51 5

This results in the following polynomial:

p(i) = 5

1For more information see http://charterproject.ning.com/

Page 16: A Feasibility Study of Loop Bound Analysis for Loops with ...

12 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

However, this is not a correct ranking function, since the number of iterationsof the loop is not constant. It is a correct upper bound for any i >= 0, but itis incorrect for any i < 0, e.g. i = −1 results in 6 iterations.

The problem is that the test nodes that are chosen for this example are tooclose to each other. The loop variable is incremented by 4, i.e. the step size ofthe loop is 4. Therefore, the differences of the values of i in the test nodes needto be a factor of 4. For example the following test nodes:

i = 0

i = 4

This would give the following results:

i p(i)0 54 4

This results in the following system of equations:

d = 5

4a+ d = 4

This gives that a = − 14 and d = 5. However, the number of iterations needs

to be an integer, so the polynomial needs to be ceiled:

{d5− 1

4 ie if i < 200 otherwise

2.2.2 Branch-splitting

Another extension mentioned in [27] handles if-statements inside the loop. Con-sider the loop in 2.4.

Listing 2.4: Loop with if-statements as given in [27]

1 while ( i > 0) {2 i f ( i > 100)3 i −= 10 ;4 else5 i−−;6 }

The loop contains two branches, which affect the upper bound differently:when i > 100 the value of i drops faster every iteration.

Branh-splitting is a solution to this problem for loops, which have the fol-lowing worst-case computation branch property :

Page 17: A Feasibility Study of Loop Bound Analysis for Loops with ...

2.3. WORKING EXAMPLES 13

“For each loop body, there is an execution path such that, for anycollections of values of the loop variables, if one follows this executionpath in every loop iteration one reaches the worst-case, i.e. the upperbound.” [27]

To do this, multiple new loops are created form the original, one for eachbranch, as shown in listings 2.5 and 2.6. For all those loops a ranking functionis computed and then because of the property described above it is possible touse the maximum of both as a general ranking function for the original loop.Therefore, a ranking function for the loop in listing 2.4 is i.

Listing 2.5: A branch from the loop in listing 2.4

1 while ( i > 0) {2 i−−;3 }

Listing 2.6: Another branch from the loop in listing 2.4

1 while ( i > 0) {2 i −=10;3 }

2.3 Working examples

2.3.1 Linear multivariate example

In this section a multivariate version of the example in the previous section willbe given. The loop used in this example is shown in Listing 2.7.

Listing 2.7: Example loop with 3 variables

1 public class Example2{2 public void method2 ( int i ) {3 //do something4 while ( x < 10 && y < 10 && z < 10) {5 z++;6 i f ( z == 10) {7 y++;8 z = 0 ;9 i f ( y == 10) {

10 x++;11 y = 0 ;12 }13 }14 }15 //do something16 }17 }

Page 18: A Feasibility Study of Loop Bound Analysis for Loops with ...

14 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

Extract and instrument loop

First the loop is extracted from its context and is instrumented with a counter,as shown in Listing 2.8.

Listing 2.8: Example loop with 3 variables

1 public class Example2{2 public void method2 ( int i ) {3 int count = 0 ;4 while ( x < 10 && y < 10 && z < 10) {5 z++;6 i f ( z == 10) {7 y++;8 z = 0 ;9 i f ( y == 10) {

10 x++;11 y = 0 ;12 }13 }14 count++;15 }16 return count ;17 }18 }

Test node generation

The example has three variables and it is expected to be linear, i.e. the expected

degree is 1. Therefore, there have to be N31 =

(43

)= 4 test nodes in NCA,

in order to be sure there is a (unique) ranking function.

For a multivariate case with k > 2 the definition for nodes to be in NCA isgiven inductively. In this case k = 3, so for any 0 ≤ i ≤ d, there have to bea (k − 1)-dimensional hyperplane, with Nk−1

d−1 nodes, which are on a (k − 1)-dimensional NCA for degree d− i and are not on any other hyperplane. In thiscase there have to be two 2-dimensional hyperplanes in NCA: one of degree 1(Hyperplane A), with 3 nodes, and one of degree 0 (Hyperplane B), with 1 node.

In order to have a 2-dimensional hyperplane in NCA, it exists of N2d nodes

and there exist lines γ1, . . . , γd+1, in such a way that d + 1 nodes are on lineγd+1, . . . , and 1 nodes lies on line γ1\(γ2∪ · · ·∪γd+1). For Hyperplane A, thereare two lines γ1 and γ2. Two nodes are on line γ2:

x y z0 0 01 0 0

and one node is on line γ1:

Page 19: A Feasibility Study of Loop Bound Analysis for Loops with ...

2.3. WORKING EXAMPLES 15

x y z0 1 0

For Hyperplane B, there is one line γ′1, with one node:

x y z0 0 1

Inferring a ranking function

The loop has three variables and the ranking function has an expected degreeof 1. Therefore, the polynomial of the ranking function has the following form:

ax+ by + cz + d = p(x, y, z)

Given the test nodes, the following results are found:

x y z p(x, y, z)0 0 0 10001 0 0 9000 1 0 9900 0 1 999

This gives the following system of equations:

d = 1000

a+ d = 900

b+ d = 990

c+ d = 999

This results in:

a = −100

b = −10

c = −1

d = 1000

Therefore a ranking function for the loop in Listing 2.7 is:

{1000− 100x− 10y − z if x < 10 ∧ y < 10 ∧ z < 100 otherwise

Page 20: A Feasibility Study of Loop Bound Analysis for Loops with ...

16 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

2.3.2 Quadratic example

The examples above were all of degree 1, i.e. linear. The following example willshow that the method can also handle higher degrees, in this case degree 2, i.e.quadratic.

Listing 2.9: Loop with a quadratic ranking function

1 while ( x < n && y < n) {2 y++;3 i f ( y == n) {4 y = 0 ;5 x++;6 }7 }

As said before, the ranking function for the loop will be quadratic. However,to show what happens when the degree is too low, first a ranking function withdegree 1 will be inferred.

Degree 1

The loop has three variables. Therefore, there need to be N31 = 4 nodes. The

polynomial will have the following form:

ax+ by + cn+ d = p(x, y, n)

The following test nodes, which are in NCA, could be used:

x y n p(x, y, n)0 0 2 41 0 2 20 1 2 30 0 1 1

This gives the following system of equations:

2c+ d = 4

a+ 2c+ d = 2

b+ 2c+ d = 3

c+ d = 1

This results in the following polynomial:

3n− 2x− y − 2 = p(x, y, n)

However, it can easily be shown that this ranking function is incorrect. Forexample when x = 0, y = 0 and n = 3, the loop has 9 iterations, but according tothe polynomial only 7. This underestimates the number of iterations. Thereforeit is an incorrect upper bound.

Page 21: A Feasibility Study of Loop Bound Analysis for Loops with ...

2.3. WORKING EXAMPLES 17

Degree 2

For three variables and a degree of 2, N32 = 10 test nodes are needed. The in

the following 10 test nodes, which are in NCA, are shown with the number ofiteration as a result of those values.

0 0 3 91 0 3 62 0 3 30 1 3 81 1 3 50 2 3 70 0 2 41 0 2 20 1 2 30 0 1 1

The polynomial will have the following form:

ax2 + by2 + cn2 + dxy + exn+ fyn+ gx+ hy + in+ j = p(x, y, n)

This gives the following system of equations:

9c+ 3i+ j = 9

a+ 9c+ 3e+ g + 3i+ j = 6

4a+ 9c+ 6e+ 2g + 3i+ j = 3

b+ 9c+ 3f + h+ 3i+ j = 8

a+ b+ 9c+ d+ 3e+ 3f + g + h+ 3i+ j = 5

4b+ 9c+ 6f + 2h+ 3i+ j = 7

4c+ 2i+ j = 4

a+ 4c+ 2e+ g + 2i+ j = 2

b+ 4c+ 2f + h+ 2i+ j = 3

c+ i+ j = 1

This results in the following polynomial:

n2 − xn− y = p(x, y, n)

Therefore, a ranking function for the loop in Listing 2.9 is:

{n2 − xn− y if x < n ∧ y < n0 otherwise

As shown above, the inferred ranking function will be incorrect, when theexpected degree is too low. However, a degree higher than needed, will lead to acorrect ranking function, though it leads to more calculations, since the numberof test nodes that are needed grows.

Page 22: A Feasibility Study of Loop Bound Analysis for Loops with ...

18 CHAPTER 2. L.B.A. WITH POLYNOMIAL INTERPOLATION

2.4 Soundness

The ranking functions found by the method described in this chapter is dependon which test nodes are used. Therefore, the method is not sound. However,the inferred ranking functions can be added to the Java code by using the JMLclause: @decreases, as shown in Listing 2.10.

Listing 2.10: Example class with decreases clause

1 //@ ensure s t rue ;2 public class Example{3 //@ a s s i g n a b l e i ;4 //@ l o o p i n v a r i a n t t rue ;5 //@ de c r e a s e s i<10 ? i−10 : 0 ;6 public void method1 ( int i ) {7 //do something8 while ( i < 10)9 i ++;

10 //do something e l s e11 }12 }

By adding this to the code, it is possible to prove the ranking function, i.e.prove that the loop will never have more iterations than given in the rankingfunction. There is a tool available that can do this (partly) automatically. Thetool is called KeY and is introduced in the article by Ahrendt et al. [1] and ismore detailed described by Beckert et al. in [6]. The KeY tool can be used toprove that certain JML clauses are correct given the Java code.

Note that this is the same method as used by Shkaravska et al. [30, 33, 29,31, 28]. Using polynomial interpolation for inference and use a formal methodto verify the polynomial returned by the inference.

Another tool which uses JML annotations is Extended Static Checker forJava (ESC/Java), as described in [14] and with its JML extension in [9]: ES-C/Java2. The main purpose of ESC/Java was to find common programmingerrors. However, ESC/Java2 can prove as well, since it is enhanced with JMLand theorem provers.

Page 23: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 3

Loop Bound Analysis forLoops with DisjunctiveGuards

The basic loop bound analysis method as described in section 2.1 handles loopswith conditions of the following form:

n∧i=1

(eli b eri)

where b ∈ {<,>,=, 6=,≤,≥}.However, in [27] an extension to the basic loop bound analysis method is

given, in order for the method to handle loops “with as exit condition anypropositional logical expression over arithmetical (in)equalities” [21], includingdisjunctions. This is done by the use of piecewise ranking functions. These areranking functions consisting of different pieces. The ranking function given atthe end of section 2.1.4, is a simple example of a piecewise ranking function:

{10− i if i > 00 otherwise

It consist of two pieces: 1) the loop condition is true and the computedranking function for the loop is given and 2) when the loop condition is falseand the is never entered, i.e. no iterations.

3.1 Piece-wise ranking functions

To allow disjunctions in the loop condition, Shkaravska et al. created the fol-lowing extension to the basic loop bound analysis method [27, 21].

The first step is to transform the loop condition to disjunctive normal form(DNF):

19

Page 24: A Feasibility Study of Loop Bound Analysis for Loops with ...

20 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

n∨i=1

(

mi∧i=1

(elijberij))

where b ∈ {<,>,=, 6=,≤,≥}.Then the transformed condition is spit into several conditions with the func-

tion DNFSplit :: Cd → {Cnd}, where Cd is a loop condition in DNF and Cnd

is a loop in the form as given at the beginning of this chapter (a conjunction ofarithmetical (in)equalities). The function DNFsplit is defined in [21] as follows:

DNFsplit(b1 ∧ · · · ∧ bn) := ∧bi∈BP

bi ∧∧

bj∈Brest

¬bj

∣∣∣∣∣BP ∈ P({b1, . . . , bn})\∅ ∧Brest = {b1, . . . , bn}\BP

This function transforms the condition in DNF to a set of 2n − 1 pieces (con-junctive conditions, as defined at the beginning of this chapter). The piecesare of a type that can be handled by the basic method (described in Chapter2). The ranking function is then calculated as follows: for every piece in theset a ranking function is calculated, which are then combined to one rankingfunction:

RFp1

if p1. . . if . . .RFpm

if pm0 else

Consider the example in Listing 3.1. The loop condition in DNF is:

(start < end ∧ end < 40) ∨ (start < end ∧ end > 100)

Using DNFsplit will result in the following pieces:

(start < end ∧ end < 40) ∧ ¬(start < end ∧ end > 100)

¬(start < end ∧ end < 40) ∧ (start < end ∧ end > 100)

(start < end ∧ end < 40) ∧ (start < end ∧ end > 100)

However, the last piece can be omitted, since there is no value for end <40∧ end > 100. Using the basic method for the other two pieces, gives for boththe following ranking function: end− start.

Therefore a ranking function for the loop in listing 3.1 is:

end− start if (start < end ∧ end < 40) ∧ ¬(start < end ∧ end > 100)end− start if (start < end ∧ end > 100) ∧ ¬(start < end ∧ end < 40)0 otherwise

Page 25: A Feasibility Study of Loop Bound Analysis for Loops with ...

3.2. THE CHALLENGE 21

Listing 3.1: Example of a loop condition with a disjunction (as given by Shkar-avska et al. in [27])

1 while ( s t a r t < end && ( end < 40 | | end > 100) )2 s t a r t ++;

3.1.1 Condition Jumping

In the previous section, piecewise ranking functions were introduced as a solu-tion to the challenge that arises when using disjunctions in the loop condition(Section 3.1). However, another challenge arises when using this method. Thisis mentioned by Kersten and Van Eekelen in [21]. When splitting the disjunc-tive condition into different pieces, each piece is considered independent, i.e.for every execution of the loop just one piece is true. However, it is possiblethat during the execution of the loop another piece becomes true. This is calledcondition jumping. In the first section of this chapter the challenge will beexplained and in the last section two solutions will be presented.

3.2 The challenge

As said above, condition jumping is a challenge that arises when disjunctiveloop conditions are used, e.g. a ∨ b, which results in the following pieces:

1. a ∧ ¬b

2. ¬a ∧ b

3. a ∧ b

The piece ¬a ∧ ¬b is omitted, since it represents the case where the loop isnot entered and thus has a ranking function of 0.

Condition jumping arises when at some point in execution one piece is trueand after the next iteration another piece is true, e.g. at some point a ∧ ¬bholds, but after the next iteration of the loop ¬a ∧ b holds. The challenge isthat the pieces created for piecewise ranking functions, can be underestimatingthe actual number of iterations, since the pieces are assumed to be independent.However, when condition jumping arises, this assumption is wrong.

Note that in every (finite) loop some sort of condition jumping arises, thejumping to the piece, for which the loop will be exited (¬a ∧ ¬b). However,this will not be considered condition jumping, since this jumping will result inexiting the loop and will therefore add no difference to the number of iterations.

3.2.1 Example of condition jumping

The loop in Listing 3.2 (as given in [21]) shows an example of condition jumping.

Listing 3.2: Condition jumping example

1 while ( ( i > 0 && i < 20) | | i > 22) {2 i f ( i > 22)

Page 26: A Feasibility Study of Loop Bound Analysis for Loops with ...

22 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

3 i−−;4 else5 i += 4 ;6 }

Using piecewise ranking functions, the following pieces will be created:

1. (i > 0 ∧ i < 20) ∧ ¬(i > 22)

2. ¬(i > 0 ∧ i < 20) ∧ (i > 22)

3. (i > 0 ∧ i < 20) ∧ (i > 22)

As above, the piece for which the loop is not entered (¬(i > 0∧ i < 20)∧¬(i >22)) is omitted. Moreover, the third piece can be omitted as well, since thereexists no i such that (i > 0 ∧ i < 20) ∧ (i > 22).

3.2.2 Solution

An algorithm to compute all the states which lead to condition jumping frompiece pi to piece pj is described below [21].

In the following a state s represents a set of values for the variables used inthe loop. s → s′ represents one iteration of the loop with s as the state beforethe iteration and s′ the state after the iteration. s ⇒ s′ represents that it ispossible to go from state s to state s′ in one or more iterations.

1. Check whether there is a state s for which holds: s → s′, where piece piis true in state s and piece pj is true in state s′. If there is such a state,add it to the list CASES.

2. Repeat the previous step to find other states s /∈ CASES, until there areno such states any more.

3. Pop a state from CASES: s

4. Check whether there are states which lead to that state and are not alreadycondition jumping cases: s′ → s and s′ /∈ CASES.

5. If so, add the state to CASES. Repeat until no new state is found, thenadd s to DONE and go back to step 3 until CASES is empty. Finally allstates that lead eventually to condition jumping are in DONE.

Steps 1 and 2 search for states which directly lead to condition jumping, i.e.in one step. Steps 3, 4 and 5 search for cases which lead eventually to conditionjumping, i.e. s⇒ s′, where in s piece pi is true and in s′ piece pj is true.

Executing this algorithm on the example above gives the following: in step1, the state where i = 19 results in condition jumping, since in that state thefirst piece is true, but after one iteration the second piece is true, since theni = 23. This is the only direct case of condition jumping. Therefore, the setCASES is as follows, when reaching step 3: {i = 19}. The next step is to checkif there is a state that reaches i = 19 after one iteration. This is only the casein the state i = 15. The following step is to check if there are states reachingi = 15 etc.

Finally the following cases of condition jumping are found:

Page 27: A Feasibility Study of Loop Bound Analysis for Loops with ...

3.3. IMPLEMENTATION 23

• i = 19

• i = 15

• i = 11

• i = 7

• i = 3

Note that these are all condition jumping cases from the first piece to the second.The cases for condition jumping from the second piece to the first have to becalculated as well. However, for this example, there are no such cases.

These states can be put into one new piece, since there is one case of conditionjumping and the other cases lead to that case. However, it is possible that thereare more cases of condition jumping, which will result in multiple pieces. Thepieces for the example will then be as follows:

• i > 0 ∧ i < 20 ∧ i mod 4 6= 3

• i > 0 ∧ i < 20 ∧ i mod 4 = 3

• i > 22∧

Using the basic method for each of these pieces, results in the followingranking function:

d(20− i)/4e+ 1 if (i > 0) ∧ (i < 20) ∧ i mod 4 = 3d(20− i)/4e if (i > 0) ∧ (i < 20) ∧ i mod 4 6= 3i− 22 if i > 220 else

3.2.3 Multi-jumping

The algorithm above defines how to detect condition jumping from one piece toanother. However, it is necessary to check every pair of conditions for conditionjumping:

1. DNF-split (see Section 3.1) the loop condition to n pieces.

2. Apply the algorithm above for any pairwise different pi and pj pieces inboth ways, i.e. condition jumping from pi to pj and condition jumpingfrom pj to pi.

3.3 Implementation

In the previous section an algorithm to detect condition jumping is given. Inthis section two different solutions to implement this algorithm are given andcompared.

Page 28: A Feasibility Study of Loop Bound Analysis for Loops with ...

24 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

3.3.1 Symbolic Execution and SMT solvers

In [21] Kersten et al. describe a method for detecting condition jumping ina loop using symbolic execution and a Satisfiability Modulo Theories (SMT)solver.

Symbolic Execution

Symbolic execution will be used to obtain update functions, which define how avariable is updated after one iteration of a given loop.

Symbolic execution is described by King in [22]. It is executing a pieceof code in a symbolical way, i.e. instead of executing the program with vari-ables, execute it with symbols. Then the result is not a set of values for inputsymbols/variables, but a set of symbolic formulas over input symbols.

The update functions obtained with symbolic execution are defined as fol-lows:

nextvi :: Tv1 → · · · → Tvi → · · · → Tvn → Tvi

where Tvi is the type of variable vi ∈ LV and n = |LV | and LV is the set ofprogram variables inside the loop.

These update functions are obtained using symbolic execution [21]. Thefirst step is to gives the variables v1, . . . , vn the symbolic values α1, . . . , αn.After the symbolic execution each variable v1, . . . , vn will have a symbolic value:polynomials over α1, . . . , αn, constants and path conditions (to handle branchinginside the loop). Update functions can then be derived by substituting thesymbolic values α1, . . . , αn by their corresponding program variables v1, . . . , vn.

For example for the loop in Listing 3.2, φi is the result of symbolic executionof the loop with αi used as symbolic value for i:

φi(αi) =

{αi − 1 if αi > 22αi + 4 if ¬(αi > 22)

When substituting i for αi results in the following update function:

nexti(i) =

{i− 1 if i > 22i+ 4 if ¬(i > 22)

These update functions will be used to determine a value for the variablesfor which condition jumping occurs. Let con1 and con2 be functions repre-senting the two pieces to check for condition jumping with the following type:v1 . . . vn → Bool. If there are values for the variables vc1 . . . vcm ∈ CV , whereCV is the set of program variables in the condition and m = |CV |, such thatthe following holds, then condition jumping occurs:

con1(v1, . . . , vn) ∧ con2(nextv1(v1, . . . , vn), . . . , nextvn(v1, . . . , vn))

Page 29: A Feasibility Study of Loop Bound Analysis for Loops with ...

3.3. IMPLEMENTATION 25

SMT scripts

To calculate all values for which condition jumping occurs, an SMT solver canbe used. An SMT solver1 solves Satisfiability Modulo Theories problems, whichare a generalisation of boolean satisfiability (SAT) problems. The goal for SATproblems is to determine given a certain set of boolean variables and formulas,if there is a valuation for those variables such that the formulas evaluate totrue. SMT problems generalise this by using underlying theories like equalityreasoning and arithmetics [7, 12].

SMT-LIB is a standard scripting language for SMT solvers, which is describesby Barrett et al. in [5]. The SMT-LIB script in Listing 3.3 is an example scriptfor the loop in Listing 3.2.

Listing 3.3: First SMT-LIB script

1 ( s e t l o g i c QF LIA)2 ( dec la re−fun i ( ) Int )3 ( de f ine−fun next i ( ( x Int ) ) Int ( i t e (> x 22) (− x 1) (+

x 4) ) )4 ( a s s e r t ( and ( and (> i 0) (< i 20) ) (> ( nex t i i ) 22) ) )5 ( check−sa t )6 ( e x i t )

The script does the following:

1. A variable i of type Int is created.

2. A function nexti is created, which contains the update function for variablei.

3. The assertion is made that there is a value for i, for which holds that0 < i < 20 and that after the next iteration i > 22, i.e. nexti(i) > 22.

4. The SMT solver then checks this assertion.

If the assertion holds,(get-value (i)) can be added to the script to getthe value of i for which condition jumping occurs.

The result of running this script will be that for i = 19 condition jumpingoccurs. In the next script it will be checked whether there are more values of ifor which condition jumping occurs. This is shown in Listing 3.4.

Listing 3.4: First SMT-LIB script

1 ( s e t l o g i c QF LIA)2 ( dec la re−fun i ( ) Int )3 ( de f ine−fun next i ( ( x Int ) ) Int ( i t e (> x 22) (− x 1) (+

x 4) ) )4 ( a s s e r t ( and ( and (> i 0) (< i 20) ) (> ( nex t i i ) 22) ) )5 ( a s s e r t ( d i s t i n c t i 19) )6 ( check−sa t )7 ( get−value ( i ) )8 ( e x i t )

1For example Z3 http://research.microsoft.com/en-us/um/redmond/projects/z3/

Page 30: A Feasibility Study of Loop Bound Analysis for Loops with ...

26 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

For this example, there are no other cases of condition jumping, so thisscript is unsatisfiable, i.e. the SMT solver can not find another i that leads tocondition jumping.

The next step is to check if there are values of i which lead to i = 19 afterthe next iteration. This is shown in Listing 3.5.

Listing 3.5: First SMT-LIB script

1 ( s e t l o g i c QF LIA)2 ( dec la re−fun i ( ) Int )3 ( de f ine−fun next i ( ( x Int ) ) Int ( i t e (> x 22) (− x 1) (+

x 4) ) )4 ( a s s e r t ( and ( and (> i 0) (< i 20) ) (= ( next i i ) 19) ) )5 ( a s s e r t ( d i s t i n c t i 19) )6 ( check−sa t )7 ( get−value ( i ) )8 ( e x i t )

This script will return i = 15. Then this step needs to be repeated for i = 15to check whether there are values of i, that will be after the next iteration i = 15and so on, until no new values can be added.

3.3.2 Binary Decision Diagrams

In this section a second solution to the detection of condition jumping willbe presented. The difference with the previous solution, is that it uses BinaryDecision Diagrams (BDDs), which are described by Akers in [2], instead of SMTscripts.

BDDs are used to find satisfying assignments for a given formula, like SMTsolvers. However, they use different methods. SMT solvers use logic to checkthe satisfiability of the assumption, whereas BDDs create a decision diagramconsidering every possible value for each variable and use logic to prune thedecision tree, as described in [10].

In this section the same example of condition jumping will be used as in theprevious sections, which is shown in Listing 3.2.

One of the challenges of the solution using SMT scripts is the generation ofthe update functions, which was implemented by the nexti function, to calculatethe value of i after one iteration. Kersten and Van Eekelen propose in [21] touse symbolic execution of the loop body.

However, this is not necessary when using BDDs, since the syntax of theloop body can be used in the update functions. This is possible, because thereare libraries for using BDDs in a programming language, like Java or C(++), sothe update functions can contain the original code of the loop body. Although,there are similar libraries available for SMT solvers2, it is not possible to usethe code of the loop body for update functions, since SMT libraries use theirown implementations for data structures for better performance.

In Listing 3.6 a C++ program is given to check if condition jumping occursin the loop in Listing 3.2 using the BDD library package BuDDy 3.

2For example the Java API for Z3 http://research.microsoft.com/en-us/um/redmond/

projects/z3/3A C++ library is used, since Java libraries were incomplete and had to be extended first.

Page 31: A Feasibility Study of Loop Bound Analysis for Loops with ...

3.3. IMPLEMENTATION 27

Listing 3.6: A C++ program using BDDs to check for condition jumping

1 #inc lude <s t d l i b . h>2 #inc lude <s t r i n g . h>3 #inc lude ”bdd . h”4 #inc lude ”bvec . h”56 const int VECTOR LENGTH = 6 ;78 us ing namespace std ;9

10 int next i ( int i ) {11 i f ( i > 22)12 i−−;13 else14 i += 4 ;15 return i ;16 }1718 bvec update i ( bvec vec )19 {20 int i = bvec va l ( vec ) ;21 i = next i ( i ) ;22 int d i f = i − bvec va l ( vec ) ;23 i f ( d i f == 0)24 return i ;25 else i f ( d i f > 0)26 return bvec add ( vec , bvec con (

VECTOR LENGTH, d i f ) ) ;27 else28 return bvec sub ( vec , bvec con (

VECTOR LENGTH, d i f ∗−1) ) ;29 }3031 bdd con1 ( bvec i )32 {33 return bdd and ( bvec gth ( i , bvec con (VECTOR LENGTH

, 0 ) ) , bve c l t h ( i , bvec con (VECTOR LENGTH, 2 0 ) ) ) ;34 }3536 bdd con2 ( bvec i )37 {38 return bvec gth ( i , bvec con (VECTOR LENGTH, 2 2 ) ) ;39 }4041 int main ( )42 {43 int domain [ 1 ] = {64} ;4445 b d d i n i t (100 ,100) ;

Page 32: A Feasibility Study of Loop Bound Analysis for Loops with ...

28 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

46 fdd extdomain ( domain , 1 ) ;4748 bvec i = bvec var fdd (0 ) ;49 bdd r e s u l t = bdd and ( con1 ( i ) , con2 ( update i ( i ) ) ) ;5051 cout << f dd s e t << r e s u l t << endl ;5253 return 0 ;54 }

In the following, the different functions of the C++ program will be ex-plained. In BDDs integers are implemented using a bit vector.

The pieces of the loop guard are implemented in the con1 and con2 functions.For example con2 is defined as

bvec gth(i, bvec con(VECTOR LENGTH, 22))

where bvec_gth is the > operator for bit vectors and bvec_con creates a con-stant bit vector of length VECTOR LENGTH with value 22, i.e. con2 returns:i > 22, and similar for con1: i > 0 ∧ i < 20.

The update function consists of two parts: update_i and nexti. The nexti

function consists of the loop body and returns an integer value of i after oneiteration. The update_i function updates the bit vectors according to the nextifunction. It first calculates the current integer value of the bit vector, passes iton to the nexti function and calculates the difference after one iteration andadds/subtracts the difference to the bit vector. It is also possible to create anexti function for bit vectors, so the update_i function is not needed anymore.However, this results in the same challenge as with SMT scripts, since theupdates of a variable need to be analysed and transformed to another formate.g. using update functions, which is not needed in the example above, sincethe loop body is used.

The main statement in the example is:

bdd result = bdd_and(con1(i), con2(update_i(i)));

which calculates the values of i for which con1 is true and in the next state con2is true.

3.3.3 Comparison

In this section a comparison between the two solutions is made and using thiscomparison a solution will be chosen to be implemented in the prototype ResAna.

The BDD approach has some advantages over the SMT approach. Themain advantage of the BDD approach is the use of the loop body of the originalcode, or at least the statements involving the variable that needs to be updated,instead of doing symbolic execution to analyse the new value after one iteration.In other words, the loop body can be used by itself, whereas update functionsfirst have to be calculated.

Another advantage is that is calculates all satisfiable cases at once. In theexample, i = 19 is a satisfiable case, i.e. condition jumping occurs. When using

Page 33: A Feasibility Study of Loop Bound Analysis for Loops with ...

3.3. IMPLEMENTATION 29

Value z3 2 variables z319 0.005 0.005119 0.005 0.0051019 0.005 0.00510019 0.006 0.006100019 0.005 0.0061000019 0.005 0.00710000019 0.006 0.007

Table 3.1: Execution time for SMT

the SMT approach, a check has to be done if there is another case of conditionjumping, where i 6= 19. However, the BDD approach will return them all atonce, so less executions need to be done.

Another advantage, especially when using a Java library, is that testing byexecuting a Java program is already used for the Loop Bound Analysis and caneasily be extended to execute condition jumping tests as well.

However, the BDD approach has some disadvantages as well. The maindisadvantage is that Integers are not used in BDDs, only boolean values. Thiscan be solved by using bit vectors, as is done in the BuDDy package for C(++).However, the implementation of bit vectors is incomplete for the C(++) pack-age, since only unsigned integers are supported. Other libraries for BDDs, likeJDD or JavaBDD (two Java implementations of BDDs), do not have bit vectorimplementations. Therefore, the BDD libraries all have to be extended to use(signed) integers as bit vectors.

Moreover, using bit vectors rises the assumption that execution time growsexponentially, with the size the integers used. Therefore, an execution timecomparison is made between the SMT and BDD approach.

Execution time comparison

An execution time comparison has been made, in order to test the extra timeneeded for running SMT or BDD scripts with increasing the size of the variables.

For both SMT and BDD the size of the condition jumping case 19 has beenincreased to 119, 1019, . . . , 10000019 for both one variable and two variables. InTable 3.1 the result for the approach SMT are shown. In Table 3.2 the resultsfor BDD approach are shown. Note that these results only involve running thescripts, i.e. the SMT results do not contain the execution time of the symbolicexecution, which takes a few seconds for these examples.

However, the results are quite clear. When using larger numbers BDDsbecome slow and it is assumed that it grows exponentially, whereas the executiontime of SMT is static and does not change much for larger values. Therefore, forthese timing issues, the SMT approach is regarded as better to create a generalimplementation. It will be slower for small values, because of symbolic executionand more executions of the SMT scripts. However, the execution time will notgrow exponentially and will perform better for larger values than BDDs.

Therefore, the SMT approach is used to solve the condition jumping chal-lenge in the ResAna prototype. Analysing the loop in Listing 3.2, results in the

Page 34: A Feasibility Study of Loop Bound Analysis for Loops with ...

30 CHAPTER 3. L.B.A. FOR LOOPS WITH DISJUNCTIVE GUARDS

Vector Length (Value) z3 2 variables z35 (19) 0.011 0.0097 (119) 0.012 0.01010 (1019) 0.012 0.01014 (10019) 0.021 0.01617 (100019) 0.030 0.04920 (1000019) 0.157 0.29724 (10000019) 2.472 4.92025 (10000019) 5.006 9.967

Table 3.2: Execution time for BDDs

following ranking function:

6 if (i > 0) ∧ (i < 20) ∧ (i = 19 ∨ i = 15 ∨ i = 11 ∨ i = 7 ∨ i = 3)5 if (i > 0) ∧ (i < 20)i− 22 if i > 220 else

This is not the precise ranking function as given before. However, it is avalid upper bound.

Page 35: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 4

Feasibility of Loop BoundAnalysis for Loops withDisjunctive Guards inPractice

In this chapter a feasibility study of Loop Bound Analysis for loops with dis-junctive guards will be performed. First a global study will be performed on16 Java projects. This global evaluation will focus on the number of disjunctiveloops in Java projects and will give an answer to the question: how many loopscontain disjunctive guards?

The second study will be a detailed loop bound analysis on the loops withdisjunctive guards in the source code of Eclipse IDE. Each loop will be exam-ined and a ranking function, if any, will be derived manually. In this chapter anevaluation of the basic method and condition jumping extension will be given.First an analysis of the ratio of condition jumping loops in existing Java pro-grams/projects will be made. This study will give an answer to the question:which loops can be analysed given the current methods?

Given the results of the detailed study the loops will be categorised andfor each category an extension, if possible, will be proposed to infer rankingfunctions for those loops.

4.1 Global Evaluation

In the following sections different Java programs/projects from practice areanalysed in order to find out how many loops contain disjunctive guards. Thisis done by counting first all while-loops and all for-loops and then for both counthow many contain disjunctive guards.

4.1.1 Apache harmony

Apache harmony is a Java runtime environment implementation. The sourcecode can be downloaded at http://harmony.apache.org/.

31

Page 36: A Feasibility Study of Loop Bound Analysis for Loops with ...

32 CHAPTER 4. FEASIBILITY STUDY

Number of loops Number of disjunctive loopswhile-loops 3792 39for-loops 14105 5Total 17897 44

4.1.2 Caliper

Caliper is a framework for microbenchmarks. The source code can be down-loaded at http://code.google.com/p/caliper/.

Number of loops Number of disjunctive loopswhile-loops 20 0for-loops 287 0Total 307 0

4.1.3 CDx

Collision Detector (CDx) is a real-time Java benchmark. The source code canbe downloaded at http://sss.cs.purdue.edu/projects/cdx/.

Number of loops Number of disjunctive loopswhile-loops 171 1for-loops 382 0Total 553 1

4.1.4 Eclipse IDE

Eclipse is an open-source Integrated Development Environment (IDE) for Java,but through the use of plug-ins several other programming and scripting lan-guages, like C(++) and python, are supported as well. The source code can bedownloaded at http://www.eclipse.org/.

Number of loops Number of disjunctive loopswhile-loops 9577 125for-loops 35672 9Total 45249 134

4.1.5 GA-Playground

GA-Playground is a toolkit for genetic algorithms written in Java. The sourcecode can be downloaded at http://www.aridolan.com/ofiles/ga/gaa/gaa.

aspx.

Number of loops Number of disjunctive loopswhile-loops 19 1for-loops 222 0Total 241 1

Page 37: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.1. GLOBAL EVALUATION 33

4.1.6 GWT-java-math

GWT-java-math is an efficient java.math implementation for Google Web Toolkit(GWT). The source code can be downloaded at http://code.google.com/p/

gwt-java-math/.

Number of loops Number of disjunctive loopswhile-loops 44 1for-loops 152 0Total 196 1

4.1.7 JAGA

JAGA is a Java API for genetic algorithms. The source code can be downloadedat http://www.jaga.org/.

Number of loops Number of disjunctive loopswhile-loops 34 1for-loops 139 0Total 173 1

4.1.8 Data Structures and Algorithm Analysis

Data Structures and Algorithm Analysis is a book by Shaffer [26]. The sourcecode of the examples in the book are used and can be downloaded at http:

//people.cs.vt.edu/~shaffer/Book/.

Number of loops Number of disjunctive loopswhile-loops 150 0for-loops 669 0Total 819 0

4.1.9 Lightweight Java Game Library

The Lightweight Java Game Library is a library which can be used to writegames in Java. The source code can be downloaded at http://lwjgl.org/.

Number of loops Number of disjunctive loopswhile-loops 5135 35for-loops 16824 0Total 21959 35

4.1.10 Java-ML

Java Machine Learning Library (Java-ML) is a collection of machine learningalgorithms written in Java. The source code can be downloaded at http://

java-ml.sourceforge.net/.

Number of loops Number of disjunctive loopswhile-loops 95 3for-loops 891 2Total 986 5

Page 38: A Feasibility Study of Loop Bound Analysis for Loops with ...

34 CHAPTER 4. FEASIBILITY STUDY

4.1.11 JavaNCSS

JavaNCSS is a source measurement suite for Java. The source code can bedownloaded at http://www.kclee.de/clemens/java/javancss/.

Number of loops Number of disjunctive loopswhile-loops 266 1for-loops 218 0Total 484 1

4.1.12 Jembench

Jembench is a Java benchmark for embedded systems. The source code can bedownloaded at http://sourceforge.net/projects/jembench/.

Number of loops Number of disjunctive loopswhile-loops 52 2for-loops 156 0Total 208 2

4.1.13 JGAP

JGAP is a genetic algorithms and genetic programming framework for Java.The source code can be downloaded at http://jgap.sourceforge.net/.

Number of loops Number of disjunctive loopswhile-loops 146 1for-loops 727 0Total 873 1

4.1.14 Jmatbench

Java-Matrix-Benchmark is a tool to evaluate linear algebra algorithms and li-braries in Java. The source code can be downloaded at http://code.google.

com/p/java-matrix-benchmark/.

Number of loops Number of disjunctive loopswhile-loops 21 0for-loops 436 0Total 457 0

4.1.15 NeoBio

NeoBio is a library for bio-inspired algorithms in Java. The source code can bedownloaded at http://neobio.sourceforge.net/.

Number of loops Number of disjunctive loopswhile-loops 13 3for-loops 68 0Total 81 3

Page 39: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 35

4.1.16 Weka

Weka is a collection of machine learning algorithms written in Java for datamining tasks. The source code can be downloaded at http://www.cs.waikato.ac.nz/ml/weka/.

Number of loops Number of disjunctive loopswhile-loops 1155 22for-loops 6026 2Total 7181 24

4.1.17 Totals

In total there were 97664 loops in the projects described above, from which only253 contained disjunctions in their condition, which is less than 0.26%. Thisshows that loops in which condition jumping can occur are very rare.

4.2 Detailed Feasibility Study

None of the loops in the Java programs/projects described in the previous exam-ple, were applicable for the method described in Chapter 3. Therefore, a manualderivation of ranking function will be done for the loops with disjunctive guardsof the Eclipse IDE.

The loops used in this detailed feasibility study are listed in Appendix A.

4.2.1 Detailed Loop Discussion

Listing A.1

The loop is bounded by the number of characters returned by nextChar(), whichis bounded by the size of the array fSmap. However, the function nextChar()is not well defined: the integer fPointer is only checked for equality with thelength of fSmap. Therefore, it is assuming that fPointer is always less thanor equal to the length of fSmap, resulting in an exception, when this is nottrue. It would be better to add an extra check, e.g. using >= or add an extraif-statement.

Upper bound:fSmap.lengthRanking function: fSmap.length− fPointer if fPointer < fSmap.length

1 if fPointer = fSmap.lengthundefined/exception otherwise

Listing A.2

The loop is bounded by the integer length, which is set to the length of string,i.e. the loop is bounded by the length of String string. There is no check inthe loop if i is negative, which would result in an exception, since i is out of thebounds of string. However, this check is not necessary, since i is set to −1 rightbefore the loop is entered.

Page 40: A Feasibility Study of Loop Bound Analysis for Loops with ...

36 CHAPTER 4. FEASIBILITY STUDY

Upper bound:lengthRanking function:{length− (i− 1) if (i− 1) < length0 otherwise

Listing A.3

The loop is bounded by the length of the array lexem. However, there is no checkif index i exceeds the boundaries of the array, which results in an exception.This happens when the array is filled with only spaces (’ ’) and tabs (’\t’).Moreover, the first assignment of variable c is not checked as well, i.e. if lexemis empty, the assignment would result in an exception as well. There is no checkfor i being negative, but this is not strictly necessary, since it is set to 0.

Upper bound:lexem.lenthRanking function:{lexem.length− i if i < lexem.lengthundefined/exception otherwise

The loop is better defined in the following way:

Listing 4.1: Improvement of Listing A.3

1 i f ( lexem . l ength > 0) {2 int i = 0 ;3 char c = lexem [ 0 ] ;4 while(++i < lexem . l ength && ( c == ’ ’ | | c == ’ \ t

’ ) ) {5 c = lexem [ i ] ;6 }7 }

Listing A.4

No upper bound/ranking function can be defined, since the exiting of theloop is defined by the type of the current state, e.g. if the current state isa HttpParser.STATE END state, the loop will be exited.

Listing A.5

No upper bound/ranking function can be defined, since the variables now andend depend on time.

Listing A.6

No upper bound/ranking function can be defined, since it is not possible topredict the value of len in each iteration, it is set using a switch on the variableto flush of which the value is not known statically, i.e. runtime information isneeded.

Page 41: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 37

Listing A.7

No upper bound/ranking function can be defined, since it depends on non-numerical values. Moreover, the check if id is a null-pointer can only be doneat runtime.

Listing A.8

No upper bound/ranking function can be defined. The loop depends on theelements in cache; the loop iterates until cache is empty. However, how manyelements are removed each iteration is unpredictable, since it depends on otherobjects, from which the value is only known at runtime.

Listing A.9

The number of iteration of this loop is bounded by the size of that data structurefor which iter has been created, i.e. destinationRepos.

Upper bound:destinationRepos.size()

It is not possible to define a ranking function given the current loop. It hasto be extended with a counter, which will be explained in Section 4.3.3.

Listing A.10

The number of iterations is bound by the number of elements in the data struc-ture for which iteratorIterator is created. The explanation given in the com-ments of the Java class, show that it is expected that iteratorIterator to con-tain iterators of a certain data type. However, the only type known is Iterator.Therefore, it is not possible to give a concrete upper bound or ranking function,since the Iterator class does not have a size method or field.

Listing A.11

The loop itself shows that the number of iterations is probably bound bythe number of tokens to be processed: nextToken(). However, the functionnextToken(), as defined in the superclass ExpressionParser, gives more infor-mation on the number of tokens, which is bounded by the length of the Stringexpression.

Upper bound:expression.length()Ranking function:{expression.length()− tokenPos if tokenPos < expression.length()0 otherwise

Note that in the function nextToken() the variable top is used to store thevalue of expression.length(). The latter is used in the upper bound and rankingfunction, since expression is a field and is globally accessible, whereas top isjust a local variable.

Listing A.12

The loop is bounded by the length of filterString. However, there is no check ifposition is in the right range, i.e. there should be a check of position is positive

Page 42: A Feasibility Study of Loop Bound Analysis for Loops with ...

38 CHAPTER 4. FEASIBILITY STUDY

and less than the length of filterString.In the following pos is the notation for the variable position.Upper bound:filterString.length()Ranking function: filterString.length()− pos if pos > 0 ∧ pos < filterString.length()

undefined/exception if pos > 0 ∧ pos > filterString.length()undefined/exception otherwise

A better loop would be:

Listing 4.2: Improvement of Listing A.12

1 i f ( p o s i t i o n > 0 && p o s i t i o n < f i l t e r S t r i n g . l ength ( ) ) {2 int begin = p o s i t i o n ;3 int end = p o s i t i o n ;4 char c = f i l t e r S t r i n g . charAt ( begin ) ;5 while ( p o s i t i o n++ < f i l t e r S t r i n g . l ength ( ) && ! ( c

== ’ ˜ ’ | | c == ’< ’ | | c == ’> ’ | | c == ’=’ | |c == ’ ( ’ | | c == ’ ) ’ ) ) {

6 i f ( ! Character . i sWhitespace ( c ) )7 end = p o s i t i o n ;8 c = f i l t e r S t r i n g . charAt ( p o s i t i o n ) ;9 }

10 }

Listing A.13

The loop itself shows that the number of iterations is probably bound bythe number of tokens to be processed: nextToken(). However, the functionnextToken(), as defined in the superclass ExpressionParser, gives more infor-mation on the number of tokens, which is bounded by the length of the Stringexpression.

Upper bound:expression.length()Ranking function:{expression.length()− tokenPos if tokenPos < expression.length()0 otherwise

Note that in the function nextToken() the variable top is used to store thevalue of expression.length(). The latter is used in the upper bound and rankingfunction, since expression is a field and is globally accessible, whereas top isjust a local variable.

Listing A.14

No upper bound/ranking function can be defined, since the variable delay de-pends on time.

Listing A.15

The loop condition consists of a conjunction. Therefore, both sides of the con-junction can be used as an upper bound. When only using the right part

Page 43: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 39

(readCnt < len) a ranking function can be found using the method describedin Section 2.1.

Upper bound:lenRanking function:{len− readCnt if readCnt < len0 otherwise

The left part of the conjunction can then be used to make the rankingfunction as described above more precise. However, in this case this is notpossible, since both pos and buffer depend on values, which are only availableat runtime.

Listing A.16

No upper bound/ranking function can be defined, since it depends on the exe-cution of other threads.

Listing A.17

No upper bound/ranking function can be defined, since it depends on the exe-cution of other threads.

Listing A.18

No upper bound/ranking function can be defined, since the update of j is re-stricted by some conditions, which depend on values which are only present atruntime. There is the value of j unpredictable.

Listing A.19

The loop is bounded by the number of elements in resources. This is an iteratordefined on selection, which is of the type IStructuredSelection. This has amethod size(), which returns the number of elements in selection.

Upper bound:selection.size()

It is not possible to define a ranking function given the current loop. It hasto be extended with a counter, which will be explained in Section 4.3.3.

Listing A.20

The loop is bound by index+ 1, since index decreases with one every iteration.Upper bound:index+ 1Ranking function:{index+ 1 if index > −10 otherwise

Listing A.21

No upper bound/ranking function can be defined, since scanner depends on astream, for which the number of elements are unknown.

Page 44: A Feasibility Study of Loop Bound Analysis for Loops with ...

40 CHAPTER 4. FEASIBILITY STUDY

Listing A.22

The number of iterations is bounded by the depth of node in the tree, i.e. thenumber of parents of node. The height/depth of the full tree is the upper bound.However, these numbers can only be specified at runtime, by checking for thisobject, how many times getParent() can be performed until arriving at the rootof the tree.

Listing A.23

The loop is bounded by the number of characters returned by nextChar().However, the number of characters this method returns depends on a stream.Therefore, no concrete upper bound/ranking function can be given.

Listing A.24

The number of iterations of this loop depends on the values of idx and ptr.However, ptr only updates given some constraints, which depend on runtimevalues, which make ptr unpredictable.

Listing A.25

To find a ranking function for this loop, the loop condition has to be split intodifferent pieces. For better understanding, consider the simplified version of theloop:

Listing 4.3: Simplified version of Listing A.25

1 do {2 i f ( f i e l d S t a r t < methodStart && f i e l d S t a r t <

typeStar t ) {3 f i e l d I n d e x ++;4 } else i f ( methodStart < f i e l d S t a r t &&

methodStart < typeStar t ) {5 methodIndex++;6 } else {7 typeIndex++;8 }9 } while ( ( f i e l d I n d e x < f i e ldCount ) | | ( typeIndex <

typeCount ) | | ( methodIndex < methodCount ) ) ;

The following notation will be used for the conditions and variables: A =(fieldIndex < fieldCount), B = (typeIndex < typeCount), C = (methodIndex <methodCount), fC = fieldCount, fI = fieldIndex, tC = typeCount, tI =typeIndex, mC = methodCount and mI = methodIndex.

Page 45: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 41

Upper bound:max(1,max(0, (fC − fI)) +max(0, (tC − tI)) +max(0, (mC −mI)))Ranking function:

fC − fI if A ∧ ¬B ∧ ¬CtC − tI if ¬A ∧B ∧ ¬CmC −mI if ¬A ∧ ¬B ∧ C(fC − fI) + (tC − tI) if A ∧B ∧ ¬C(fC − fI) + (mC −mI) if A ∧ ¬B ∧ C(tC − tI) + (mC −mI) if ¬A ∧B ∧ C(fC − fI) + (tC − tI) + (mC −mI) if A ∧B ∧ C1 otherwise

Listing A.26

The loop is bounded by the number of tokens, which are subsets of the stringfContent. Assuming each token contains at least one character, the loop isbounded by the length of fContent.

Upper bound:fContent.length

Listing A.27

The loop is bounded by the number of characters returned by nextChar(), whichis the same as in Listing A.23. However, the number of characters this methodreturns depends on a stream. Therefore, no concrete upper bound/rankingfunction can be given.

Listing A.28

The loop iterates over the characters returned by reader.read(). In the sourcecode it is shown that it either returns a character from fDocument or EOF ,which is −1 after which the loop is exited.

Upper bound:fDocument.getLength() + 1

In the current situation no ranking function can be defined. However, withthe use of a special counter it is possible, as will be explained in Section 4.3.3.

Listing A.29

The number of iterations is bounded by the depth of node in the tree, i.e. thenumber of parents of node. The height/depth of the full tree is the upper bound.However, these numbers can only be specified at runtime, by checking for thisobject how many times getParent() can be performed until arriving at the rootof the tree.

Listing A.30

The number of iterations is bounded by the depth of node in the tree, i.e. thenumber of parents of node. The height/depth of the full tree is the upper bound.However, these numbers can only be specified at runtime, by checking for thisobject how many times getParent() can be performed until arriving at the rootof the tree.

Page 46: A Feasibility Study of Loop Bound Analysis for Loops with ...

42 CHAPTER 4. FEASIBILITY STUDY

Listing A.31

Similar to Listing A.28. The loop iterates over the characters returned byreader.read(). In the source code it is shown that it either returns a characterfrom fDocument or EOF , which is −1 after which the loop is exited.

Upper bound:fDocument.getLength() + 1

In the current situation no ranking function can be defined. However, withthe use of a special counter it is possible, as will be explained in Section 4.3.3.

Listing A.32

The loop condition consists of two booleans. However, the loop can be simplifiedto the following:

Listing 4.4: Simplified version of Listing A.32

1 while ( i l o c a l < maxLocals | | i s c o p e < maxScopes ) {2 i f ( i s c o p e < maxScopes3 && ( i l o c a l >= maxLocals | | ( this .

subscopes [ i s c o p e ] . s t a r t Index ( ) <=i l o c a l ) ) ) {

4 i s c o p e++;5 } else {6 i l o c a l ++;7 }8 }

This makes the loop similar to the one in Listing A.25. The following no-tations will be used: iL = ilocal, mL = maxLocals, iS = iscope, mS =maxScopes, hasMoreV ariables = ilocal < maxLocals and hasMoreScopes =iscope < maxScopes.

Upper bound:max(0,mL− iL) +max(0,mS − iS)Ranking function:

mL− iL if hasMoreV ariables ∧ ¬hasMoreScopesmS − iS if ¬hasMoreV ariables ∧ hasMoreScopes(mL− iL) + (mS − iS) if hasMoreV ariables ∧ hasMoreScopes0 otherwise

Listing A.33

See Listing A.32.

Listing A.34

The loop iterates through the array unitSource. Therefore, the length of thatarray is the upper bound on the number of iterations. However, it should bechecked that the index begin does not exceed the boundaries of the array.

Page 47: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 43

Upper bound:unitSource.lengthRanking function: Undefined/exception if begin < 0

unitSource.length− begin if begin >= 0 ∧ begin < unitSource.lengthUndefined/exception otherwise

A better loop would be:

Listing 4.5: Improvement of Listing A.34

1 while ( begin > 0 && begin < uni tSource . l ength &&((c =unitSource [ begin ] ) == ’ ’ | | c == ’ \ t ’ ) ) begin++;

Listing A.35

No upper bound/ranking function can be defined, since it depends on non-numerical objects: unclaimedAnnotations.

Listing A.36

The loop iterates through the array unitSource. Therefore, the length of thatarray is the upper bound on the number of iterations. However, it should bechecked that the index begin does not exceed the boundaries of the array.

Upper bound:unitSource.lengthRanking function: Undefined/exception if begin < 0unitSource.length

unitSource.length− begin if begin >= 0 ∧ begin < unitSource.lengthUndefined/exception otherwise

A better loop would be:

Listing 4.6: Improvement of Listing A.36

1 while ( begin > 0 && begin < uni tSource . l ength &&((c =unitSource [ begin ] ) == ’ ’ | | c == ’ \ t ’ ) ) begin++;

Listing A.37

No upper bound/ranking function can be defined, since it depends on non-numerical objects: constructorBinding and enclosingTypeBinding.

Listing A.38

No upper bound/ranking function can be defined, since it depends on non-numerical objects: constructorBinding and enclosingTypeBinding.

Listing A.39

No upper bound/ranking function can be defined, since it depends on non-numerical objects: constructorBinding and enclosingTypeBinding.

Page 48: A Feasibility Study of Loop Bound Analysis for Loops with ...

44 CHAPTER 4. FEASIBILITY STUDY

Listing A.40

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.41

The loop iterates over an array this.source with this.currentPosition as astarting point.

Upper bound:this.source.lengthRanking function: Undefined/exception if pos < 0

length− pos if pos > 0 ∧ pos < lengthUndefined/exception otherwise

where pos = this.currentPosition and length = this.source.length.The loop would be better defined with the following loop condition:

Listing 4.7: Improvement of Listing A.41

1 while ( this . c u r r e n t P o s i t i o n > 0 && this . c u r r e n t P o s i t i o n <this . source . l ength && ( ( this . cur rentCharacter != ’ / ’ )| | ( ! s t a r ) ) )

Listing A.42

See Listing A.41.

Listing A.43

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.44

No upper bound/ranking function can be defined, since it depends on a non-numerical object: result.

Listing A.45

It seems that this loop searches for a given value inside an array, possibly startingin the middle of the array and work to the end and repeating at the beginningof the array. However, if the value does not exists in the array, the loop will notstop, since there is no check if a value is checked twice.

A better loop would be:

Listing 4.8: Improvement of Listing A.45

1 int s t a r t P o s i t i o n = index ;

Page 49: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 45

2 while ( index < this . keyTable . l ength && ( ( this . keyTable [index ] != 0) | | ( ( this . keyTable [ index ] == 0) &&(this .valueTable [ index ] != 0) ) ) ) {

3 i f ( this . keyTable [ index ] == key )4 return true ;5 i f (++index == length ) {6 index = 0 ;7 }8 else i f ( index == s t a r t P o s i t i o n )9 break ;

10 }

When arriving at the saved position the loop breaks, since that value has al-ready been checked. The extra check in the loop condition prevents an exceptionin the first iteration.

Upper bound:length

To define a ranking function, an extra counter has to be created, since theindex counter does not grow monotonically, it switches to 0 if it reaches the endof the array. This method will be explained in Section 4.3.3.

Listing A.46

See Listing A.45.

Listing A.47

See Listing A.45.

Listing A.48

See Listing A.45.

Listing A.49

See Listing A.45.

Listing A.50

See Listing A.45.

Listing A.51

The loop iterates through the array unitSource. Therefore, the length of thatarray is the upper bound on the number of iterations. However, it should bechecked that the index begin does not exceed the boundaries of the array.

Upper bound:unitSource.lengthRanking function: Undefined/exception if begin < 0unitSource.length

unitSource.length− begin if begin >= 0 ∧ begin < unitSource.lengthUndefined/exception otherwise

Page 50: A Feasibility Study of Loop Bound Analysis for Loops with ...

46 CHAPTER 4. FEASIBILITY STUDY

A better loop would be:

Listing 4.9: Improvement of Listing A.51

1 while ( begin > 0 && begin < uni tSource . l ength &&((c =unitSource [ begin ] ) == ’ ’ | | c == ’ \ t ’ ) ) begin++;

Listing A.52

See Listing A.51.

Listing A.53

See Listing A.51.

Listing A.54

The loop iterates through the array unitSource. Therefore, the length of thatarray is the upper bound on the number of iterations. However, it should bechecked that the index end does not exceed the boundaries of the array.

Upper bound:unitSource.lengthRanking function: Undefined/exception if end < 0unitSource.length

unitSource.length− end if end >= 0 ∧ end < unitSource.lengthUndefined/exception otherwise

A better loop would be:

Listing 4.10: Improvement of Listing A.54

1 while ( end > 0 && end < uni tSource . l ength &&((c =unitSource [ end ] ) == ’ ’ | | c == ’ \ t ’ ) ) end++;

Listing A.55

The loop by itself should contain some checks to prevent index out of boundsexception. However, these checks are not needed, since the entering conditionis obtained in the outer loop and the exit condition inside the loop.

Upper bound:length1− index1Ranking function:{length1− index1 if index1 < length11 otherwise

Listing A.56

The loop by itself should contain some checks to prevent index out of boundsexception. However, these checks are not needed, since the entering conditionis obtained in the outer loop and the exit condition inside the loop.

Page 51: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 47

Upper bound:length2− index2Ranking function:{length2− index2 if index2 < length21 otherwise

Listing A.57

The loop iterates over an array this.source with this.currentPosition as astarting point.

Upper bound:this.source.lengthRanking function: Undefined/exception if pos < 0

length− pos if pos > 0 ∧ pos < lengthUndefined/exception otherwise

where pos = this.currentPosition and length = this.source.length.The loop would be better defined with the following loop condition:

Listing 4.11: Improvement of Listing A.57

1 while ( this . c u r r e n t P o s i t i o n > 0 && this . c u r r e n t P o s i t i o n <this . source . l ength && ( ( this . cur rentCharacter != ’ / ’ )| | ( ! s t a r ) ) )

Listing A.58

No upper bound/ranking function can be defined, since it depends on a non-numerical object: field.

Listing A.59

The loop iterates over an array this.source with this.index as a starting point.Upper bound:this.source.lengthRanking function: Undefined/exception if this.index < 0

length− this.index if this.index > 0 ∧ this.index < lengthUndefined/exception otherwise

where length = this.source.length.The loop would be better defined with the following loop condition:

Listing 4.12: Improvement of Listing A.59

1 while ( this . index > 0 && this . index < this . source . l ength&& ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) )

Listing A.60

See Listing A.59.

Page 52: A Feasibility Study of Loop Bound Analysis for Loops with ...

48 CHAPTER 4. FEASIBILITY STUDY

Listing A.61

See Listing A.59.

Listing A.62

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.63

The loop iterates over a number of tokens returned by the variable fScanner,which is an IScanner object. An IScanner object cannot return the number oftokens it contains. However, it can return the source of the scanner, which is anarray of characters. Assuming, that one token represents one or more charactersin the source, the following upper bound can be defined:

Upper bound:fScanner.getSource().length

Listing A.64

The loop iterates as long i is smaller than the length of the array cleanUps,where i is used as index for the array, i.e. the loop iterates over the contents ofan array. However, it is never checked whether i >= 0.

Upper bound:cleanUps.lengthRanking function: Undefined/exception if i < 0

cleanUps.length if i >= 0 ∧ i < cleanUps.length0 otherwise

Listing A.65

No upper bound/ranking function can be defined, since it depends on a non-numerical object: javaElem.

Listing A.66

The number of iterations is bounded by the depth of container in the tree, i.e.the number of parents of node. The height/depth of the full tree is the upperbound. However, these numbers can only be specified at runtime, by checkingfor this object how many times getParent() can be performed until arriving atthe root of the tree.

Listing A.67

The number of iterations is bounded by the depth of node in the tree, i.e. thenumber of parents of node. The height/depth of the full tree is the upper bound.However, these numbers can only be specified at runtime, by checking for thisobject how many times getParent() can be performed until arriving at the rootof the tree.

Page 53: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 49

Listing A.68

No upper bound/ranking function can be defined, since it depends on a non-numerical object: id.

Listing A.69

The loop iterates over the contents of the array ZigZag8x8, until the index karrives at end, which probably contains the value of ZigZag8x8.length. How-ever, it would be better to check on ZigZag8x8.length itself instead of end or atleast whether end < ZigZag8x8.length and a check should be added for k > 0.

Upper bound:end+ 1Ranking function:

Undefined/exception if k < 0(end− k) + 1 if k >= 0 ∧ k <= end ∧ end < ZigZag8x8.endUndefined/exception if k >= 0 ∧ k <= end ∧ end >= ZigZag8x8.end0 otherwise

Listing A.70

The loop iterates until h < j. However, those variables are used to access anarray, so it should be checked that j < lengths.length and j > 0.

Upper bound:

d jheRanking function:

Undefined/exception if j < 0 ∧ j >= hif j > 0 ∧ j < lengths.lenth ∧ j >= h

Undefined/exception if j >= lengths.length ∧ j >= h0 otherwise

Listing A.71

No upper bound/ranking function can be defined, since it depends on a non-numerical object: cinfo.

Listing A.72

The loop iterates over the characters in fDocument, in the following abbreviatedto fDoc. However, the index end is not checked to be inside the boundaries, i.e.end > 0 ∧ end < fDoc.getLength().

Upper bound:fDoc.getLength()Ranking function:

Undefined/exception if end < 0fDoc.getLength()− end if end > 0 ∧ end < fDoc.getLength()Undefined/exception if end >= fDoc.getLength()0 otherwise

Page 54: A Feasibility Study of Loop Bound Analysis for Loops with ...

50 CHAPTER 4. FEASIBILITY STUDY

Listing A.73

No upper bound/ranking function can be defined, since it depends on non-numerical objects: e and p.

Listing A.74

The loop has to be divided in to three different pieces.Upper bound:max(max(0, back + 1),max(0, size− forth))Ranking function:

back + 1 if back >= 0 ∧ ¬(forth < size)size− forth if ¬(back ≥ 0) ∧ forth < sizemax(back + 1, size− forth) if back ≥ 0 ∧ forth < size0 otherwise

Listing A.75

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.76

The loop is bounded by l >= min.Upper bound:l −min+ 1Ranking function:{l −min+ 1 if l >= min0 otherwise

Listing A.77

The loop is bounded by l <= max.Upper bound:max− l + 1Ranking function:{max− l + 1 if max <= l0 otherwise

Listing A.78

The loop is bounded by the number of characters returned by nextChar(), whichis the same as in Listing A.23. However, the number of characters this methodreturns depends on a stream. Therefore, no concrete upper bound/rankingfunction can be given.

Listing A.79

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Page 55: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 51

Listing A.80

The loop iterates until count reaches 0.Upper bound:countRanking function:{count if count > 00 otherwise

Listing A.81

The loop is bounded by the number of tokens returned by the tokenizer. How-ever, the number of tokens is not accessible. This can only be known at runtimeby going through all tokens and count them. The number of tokens is likelybounded by the number of characters in the original text. This text is storedin an array of characters in the Tokenizer. Assuming one token consists of oneor more characters, it is an upper bound to the number of tokens. However,the variable value is marked as protected and is not accessible in this loop.Therefore, upper bound tokenize.value.length cannot be used, unless a getterwill be created for the value field.

Listing A.82

No upper bound/ranking function can be defined, since it depends on a non-numerical object: file.

Listing A.83

No upper bound/ranking function can be defined, since it depends on a non-numerical object: testShell.

Listing A.84

Variable it is a CharacterIterator, which has methods for returning the beginand end index

Upper bound:it.getEndIndex()− it.getBeginIndex()

Listing A.85

No upper bound/ranking function can be defined, since it depends on objects:myIter and yourIter.

Listing A.86

The number of iterations is bounded by the depth of superClass in the tree, i.e.the number of parents of node. The height/depth of the full tree is the upperbound. However, these numbers can only be specified at runtime, by checkingfor this object how many times getSuperclassName() can be performed untilarriving at the root of the tree.

Page 56: A Feasibility Study of Loop Bound Analysis for Loops with ...

52 CHAPTER 4. FEASIBILITY STUDY

Listing A.87

The number of iterations is bounded by the depth of o in the tree, i.e. thenumber of parents of node. The height/depth of the full tree is the upperbound. However, these numbers can only be specified at runtime, by checkingfor this object how many times getParent() can be performed until arriving atthe root of the tree.

Listing A.88

The loop is bounded by the number of lines in the IDocument doc.Upper bound:doc.getLength()

Listing A.89

The loop is bounded by the number of lines in the IDocument doc.Upper bound:doc.getLength()

Listing A.90

The loop is bounded by the number of characters in newStream. However, itis an input stream, for which the end is only known when its reached, i.e. thenumber of characters can only be known at runtime.

Listing A.91

The loop is bounded by the number of characters in oldStream. However, itis an input stream, for which the end is only known when its reached, i.e. thenumber of characters can only be known at runtime.

Listing A.92

The number of iterations is bounded by the depth of parentPath in the tree,i.e. the number of parents of node. The height/depth of the full tree is theupper bound. However, these numbers can only be specified at runtime, bychecking for this object how many times getParentPath() can be performeduntil arriving at the root of the tree.

Listing A.93

No upper bound/ranking function can be defined, since it depends on a non-numerical object: listener.

Listing A.94

The loop is bounded by the number of lines in reader. However, it is a readerover an input stream, for which the end is only known when its reached, i.e. thenumber of characters can only be known at runtime.

Page 57: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 53

Listing A.95

The loop is bounded by the number of existing names and reserved names.Upper bound:reservednames.size() + contents.length

Listing A.96

The loop is bounded by the number of Items i. The class Item is implementedas a linked list, i.e. adding a pointer to the next Item to the objects. However,the number of items can only be known by iterating all the items and countingthem, which can only be done at runtime.

Listing A.97

The loop iterates of the elements of the array a, using i as its index. However,there is no check on i for being larger than the length of the array. Moreover,the check i 6= −1 should be i > −1, since that would exclude negative numbers,which lead to an exception.

Upper bound:a.lengthRanking function:

Undefined/exception if i < −1Undefined/exception if i = −1i+ 1 if i > −1 ∧ i < a.lengthUndefined/exception otherwise

Listing A.98

See Listing A.97.

Listing A.99

See Listing A.97.

Listing A.100

See Listing A.97.

Listing A.101

See Listing A.97.

Listing A.102

See Listing A.97.

Listing A.103

The loop is bounded by the number of characters in reader.Upper bound:reader.size

Page 58: A Feasibility Study of Loop Bound Analysis for Loops with ...

54 CHAPTER 4. FEASIBILITY STUDY

Listing A.104

The loop is bounded by the number of characters in reader.Upper bound:reader.size

Listing A.105

No upper bound/ranking function can be defined, since it depends on updatesdone in other threads.

Listing A.106

No upper bound/ranking function can be defined, since it depends on updatesdone in other threads.

Listing A.107

No upper bound/ranking function can be defined, since it depends on updatesdone in other threads.

Listing A.108

No upper bound/ranking function can be defined, since it depends on updatesdone in other threads.

Listing A.109

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.110

No upper bound/ranking function can be defined, since it depends on a non-numerical object: current.

Listing A.111

No upper bound/ranking function can be defined, since it depends on a non-numerical object: bucketTable.

Listing A.112

The loop iterates over an array. Therefore, it should have more checks in theloop condition: offset > 0 and offset < b.length.

Two different ranking functions can be given for this loop.Upper bound:remainingRanking function:{remaining if remaining > 00 otherwise

The following ranking function uses the array b and its index offset.

Page 59: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 55

Upper bound:b.lengthRanking function:

Undefined/exception if offset < 0.¯length− offset if offset > 0 ∧ offset < b.lengthUndefined/exception if offset >= b.length0 otherwise

Listing A.113

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.114

No upper bound/ranking function can be defined, since it depends on updatesdone in other threads, since t is an object of the class Thread.

Listing A.115

The loop is bounded by the number of tokens in the StringTokenizer st.Upper bound:st.countTokens()

Listing A.116

The number of iterations is bounded by the number of readers returned bygetReader(), which is bounded by readerSources. However, that is an iteratorfor which the number of items has to be calculated at runtime.

Listing A.117

The loop is bounded by the number of lines in the reader in. However, this isa stream. Therefore, no upper bound/ranking functions can be defined.

Listing A.118

The loop is bounded by the number of lines in the reader in. However, this isa stream. Therefore, no upper bound/ranking functions can be defined.

Listing A.119

The loop is bounded by the number of lines in the reader in. However, this isa stream. Therefore, no upper bound/ranking functions can be defined.

Listing A.120

The loop iterates over an array. Therefore, it should have more checks in theloop condition: offset > 0 and offset < b.length.

Two different ranking functions can be given for this loop.

Page 60: A Feasibility Study of Loop Bound Analysis for Loops with ...

56 CHAPTER 4. FEASIBILITY STUDY

Upper bound:remainingRanking function:{remaining if remaining > 00 otherwise

The following ranking function uses the array b and its index offset.

Upper bound:b.lengthRanking function:

Undefined/exception if offset < 0b.length− offset if offset > 0 ∧ offset < b.lengthUndefined/exception if offset >= b.length0 otherwise

Listing A.121

The loop iterates through two arrays. However, there are no checks if the indexis out of boundary, which should be there.

Upper bound:max(result.length,m key.length)Ranking function:

Undefined/exception if index < 0Undefined/exception if ri < 0max(rl − ri,ml − index) if index > 0 ∧ index < ml ∧ rl >= ml ∧ ri < rlUndefined/exception if ri >= rltextUndefined/exception if index >= ml0 otherwise

where ri = rindex, rl = result.length and ml = m key .length.

Listing A.122

The loop is bounded by strength.

Upper bound:strengthRanking function: Undefined/exception if strength < 0

strength if strength > 0otherwise

Listing A.123

The loop needs to be divided in pieces.

In the following: m0 = m uitlIntBuffer [0], m1 = m uitlIntBuffer [1],m2 = m uitlIntBuffer [2], A = (cei << 1) < m0, B = cei < m1 andC = cei < m2.

Page 61: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.2. DETAILED FEASIBILITY STUDY 57

Upper bound:max(0,max(dm0− cei

2 e,max(m1− cei,m2− cei)))Ranking function:

dm0− cei2 e if A ∧ ¬B ∧ ¬C

m1− cei if ¬A ∧B ∧ ¬Cm2− cei if ¬A ∧ ¬B ∧ Cmax(dm0− cei

2 e,m1− cei) if A ∧B ∧ ¬Cmax(dm0− cei

2 e,m2− cei) if A ∧ ¬B ∧ Cmax(m1− cei,m2− cei) if ¬A ∧B ∧ Cmax(dm0− cei

2 e,max(m1− cei,m2− cei)) if A ∧B ∧ C0 otherwise

Listing A.124

The loop iterates until m optionarg is greater or equal to optionend.Upper bound:max(0, optionend−m optionarg )Ranking function:{optionend−m optionarg if m optionarg < optionend0 otherwise

Listing A.125

No upper bound/ranking function can be defined, since it depends on objects:the loop condition contains two booleans, which are set depending on runtimevalues.

Listing A.126

The loop is bounded by the number of items in the list changedItem.parent.children.Upper bound:changedItem.parent.children.size()

Listing A.127

The loop iterates over the array providers starting with index i = 0.Upper bound:providers.lengthRanking function:{providers.length− i if providers.length > 00 otherwise

Listing A.128

No upper bound/ranking function can be defined, since the variables in the loopcondition are assigned by objects instead of updated, which makes the variablesunpredictable.

Listing A.129

The loop is similar to the following:

Page 62: A Feasibility Study of Loop Bound Analysis for Loops with ...

58 CHAPTER 4. FEASIBILITY STUDY

Listing 4.13: Similar version of Listing A.129

1 int column = 0 ;2 do{3 column++;4 } while ( column < columnCount )

In the following cC = columnCount and c = column.Upper bound:columnCountRanking function: 1 if cC = 0

cC − c if cC > 0 ∧ c < cC0 otherwise

Listing A.130

See Listing A.129.

Listing A.131

See Listing A.129.

Listing A.132

The loop is similar to the following:

Listing 4.14: Similar version of Listing A.132

1 int i = 0 ;2 do{3 i ++;4 } while ( i < count )

Upper bound:columnCountRanking function: 1 if count = 0

count− i if count > 0 ∧ i < count0 otherwise

Listing A.133

The loop iterates over the array toSort starting with index i = 0.Upper bound:toSort.lengthRanking function:{toSort.length− i if toSort.length > 00 otherwise

Page 63: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.3. CATEGORIES OF LOOPS WITH DISJUNCTIVE GUARDS 59

Listing A.134

No upper bound/ranking function can be defined, since it depends on objects:the variables in the loop condition are assigned by objects instead of updated.

4.3 Categories of Loops with Disjunctive Guards

The loops analysed in the previous section can be sorted into different categories:

• Conjunctive Normal Form Elimination: A.2, A.15, A.76, A.77, A.80,A.112, A.122, A.124.

• Conjunctive Normal Form Elimination (with proposed edits as presentedin the previous section): A.1, A.3, A.12, A.34, A.36, A.41, A.42, A.45,A.46, A.47, A.48, A.49, A.50, A.51, A.52, A.53, A.54, A.57, A.59, A.60,A.61, A.64, A.69, A.70, A.72, A.97, A.98, A.99, A.100, A.101, A.102,A.112, A.112, A.120, A.121.

• Condition Jumping check error: A.25, A.32, A.33, A.74, A.123, A.129,A.130, A.131, A.132.

• Iterating through data structures using an index variable:

– Local data structure: A.1, A.3, A.12, A.34, A.36, A.41, A.42, A.51,A.52, A.53, A.54, A.57,A.59, A.60, A.61, A.64, A.69, A.70, A.72,A.97, A.98, A.99, A.100, A.101, A.102, A.112, A.120, A.121, A.127,A.133.

– Data structure through method calls: A.11, A.13.

• Iterating through data structures without using an index:

– Local data structure: A.19, A.45, A.46, A.47, A.48, A.49, A.50, A.88,A.89, A.115, A.126.

– Data structure through method calls: A.26, A.28, A.31, A.95.

– Using iterators: A.9, A.63, A.84, A.103, A.104.

• Plain iterators: A.10, A.116.

• Streams: A.21, A.23, A.27, A.78, A.90, A.91, A.94, A.117, A.118, A.119.

• Other iterating classes: A.81, A.96.

• Tree: A.22, A.29, A.30, A.66, A.67, A.86, A.87, A.92.

• Break: A.55, A.56.

• Time: A.5, A.14.

• Threads: A.16, A.17, A.105, A.106, A.107, A.108, A.114.

• Unpredictable updates: A.6, A.24, A.40, A.43, A.62, A.75, A.79, A.109,A.113, A.125, A.128.

• Runtime dependencies: A.4, A.7, A.8, A.18, A.35, A.37, A.38, A.39, A.44,A.58, A.65, A.68, A.71, A.73, A.82, A.83, A.85, A.93, A.110, A.111, A.134.

Page 64: A Feasibility Study of Loop Bound Analysis for Loops with ...

60 CHAPTER 4. FEASIBILITY STUDY

In the following sections those categories are defined and will be presentedwith an explanation of a possible solution and/or future work/research on thetopic.

4.3.1 Conjunctive Normal Form Elimination

The current method (as presented in Chapter 2) only deals with numerical loopconditions. However, many loop conditions contain non-numerical elements,which cannot be handled by the original method, e.g. in the loop in ListingA.2.

In this loop a character c is used. The use of a character is not the problemhere, since characters can be regarded as a numerical value, e.g. using its ASCIIcode. The problem is that the value of character c is unpredictable given thecode, since the next value for c depends on the character in String string atposition i, but the value of string can only be determined at runtime.

Although c cannot be used to determine a ranking function, a part of thecondition does not contain the variable c: + + i < length. Moreover this isconnected to the other parts of the condition using a conjunction. This meansthat to determine an upper bound on the number of iterations, either side ofthe conjunction can be used, since if either the left or the right part is false theloop is exited. Therefore, for loop bound analysis the loop can be transformedto:

Listing 4.15: Conjunctive Normal Form Elimination

1 while (++i < l ength )2 ;

This results in a ranking function of:

{length− (i− 1) if (i− 1) < length0 otherwise

General solution

In general if the loop condition contains parts, which cannot be used for deter-mining a ranking function, the following algorithm can be used:

1. Convert the loop condition to Conjunctive Normal Form (CNF).

2. Check which parts of the condition can be used for the loop bound analysis.For example by using a syntactical analysis to check if the which parts areof the following form:

n∨i=1

(eli b eri)

where b ∈ {<,>,=, 6=,≤,≥}.

3. For the analysis, remove any parts from the loop condition that cannotbe used.

Page 65: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.3. CATEGORIES OF LOOPS WITH DISJUNCTIVE GUARDS 61

4.3.2 Condition Jumping check error

In Section 3.3.1 a method is given to check for condition jumping in a loop.However, during the detailed study, this method showed insufficient in somecases. The problem is best to be shown with an example. The following is aslightly changed version of the loop in Listing 3.2.

Listing 4.16: Multivariate condition jumping

1 while ( ( i > 0 && i < ( var − 1) ) | | i > ( var + 1) ) {2 i f ( i > ( var + 1) )3 i−−;4 else5 i += 4 ;6 }

In the original version the variable var was a constant with the value 21,which leads to condition jumping when i = 19. Therefore, the SMT solver will(eventually) find the model (i = 19, var = 21) as a case of condition jumping.However, it will also find (i = 1, var = 3), (i = 2, var = 4), (i = 3, var = 5),(i = 4, var = 6), (i = 5, var = 7), (i = 6, var = 8) etc. In theory the listof condition jumping cases would be endless, since for any value of var > 2i = var − 2 will result in condition jumping. However, in reality this would bebounded by the maximum integer value for the SMT solver.

The problem is that var is used as a constant in the loop, since it does notchange during the loop. However, when checking for condition jumping it isregarded as a normal variable, so all the different cases will be summed up.To solve this problem another method should be used, since condition jumpingoccurs when i = var−2, which contains the symbol var and SMT solvers cannothandle symbolic variables by itself.

A possible solution could be to use the SMT solver in combination withpolynomial interpolation as described in Section 2.1.2, i.e. instead of constantcondition jumping cases, use a polynomial to define a set of condition jumpingcases. Let there be the possibility to mark a variable as constant, for examplevar in the example above and use that as a variable in the polynomial. Then tryto interpolate a polynomial for condition jumping cases of a chosen degree. Forthe example above a polynomial of degree one (with one variable var) suffices,i.e. two nodes are needed. Then use the SMT solver to get two models. In thecase of the example above the SMT solvers returns for example: (i = 1, var = 3)and (i = 2, var = 4). Then do polynomial interpolation to find the followingpolynomial: a · var + b = i.

3a+ b = 1

4a+ b = 2

Then a = 1 and b = −2, i.e. i = var − 2.

Page 66: A Feasibility Study of Loop Bound Analysis for Loops with ...

62 CHAPTER 4. FEASIBILITY STUDY

4.3.3 Iterating through data structures with size field ormethod

This category includes loops that iterate over elements of a data structure. Thiscan be any data structure, but the data structure needs a function or accessiblefield which represents its length, e.g. String.length(). This category is split intotwo subcategories, depending on the use of an index variable, since an index isused to derive a ranking function from the upper bound, i.e. the size of the datastructure.

Since these loops iterate over a data structure, its size will be an upperbound on the number of iterations. Using for example a syntactical analysismethod to check whether a data structure has a field/method which defines itssize, e.g. check if there is an accessible field size or length or a method length()etc.

Instead of using a syntactical analysis method, an annotation can be given tothe data structure, which points to the field or method which contains the sizeinformation of the data structure. This solution works better than a syntacticalanalysis, since it is possible to store the size of a data structure in a field whichis badly named, i.e. the name of the variable does not suggest a size value.However, this will move the responsibility of finding a size field or method fromthe analysis method (or tool) to the author of the code.

In the detailed study a difference is made between local data structuresand iterating through a method call. For the first an analysis can be done asdescribed above. However, for the latter the analysis becomes more complicated,since the data structure is hidden in a method call, which returns the nextvalue. Therefore, a more complex syntactical analysis is needed, which searchesthrough method calls for the iterating data structure and then use the methodabove to find the size of that data structure. However, in this case it is alsopossible to give the responsibility of finding the correct field or method to theauthor of the code, by using an annotation to the loop.

Another distinction made in the evaluation is iteration through a data struc-ture using an iterator. This subcategory contains the loops using an iterator,for which the iterator is created using a data structure. It is not possible to getthe size of standard iterators, since they mainly do not contain size information.However, using the declaration of the iterator, it is possible to derive the datastructure through which it iterates. Then use the method above to find the sizeof that data structure.

With an index variable

When an index variable is present, the derivation of a ranking function is trivial:just subtract the index from the upper bound given by the size of the datastructure.

Without an index variable

To obtain a ranking function, when there is no index variable, it is possible tocreate a new variable which will initial be 0 and increases with 1 every iteration,i.e. this variable simulates an index.

This can be done in two ways:

Page 67: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.3. CATEGORIES OF LOOPS WITH DISJUNCTIVE GUARDS 63

• add an extra variable which simulates the index. Define a variable beforethe loop and set it to 0 and increase its value every iteration with 1. Forexample in Listing A.9:

Listing 4.17: Index with variables

1 int index = 0 ;2 I t e r a t o r<Repos i toryDescr iptor> i t e r =

dest inat ionRepos . i t e r a t o r ( ) ;3 while ( i t e r . hasNext ( ) && ( a r t i f a c t R e p o D e s c r i p t o r ==

null | | metadataRepoDescriptor == null ) ) {4 Repos i to ryDesc r ip to r repo = i t e r . next ( ) ;5 i f ( repo . i s A r t i f a c t ( ) &&

a r t i f a c t R e p o D e s c r i p t o r == null )6 a r t i f a c t R e p o D e s c r i p t o r = repo ;7 i f ( repo . isMetadata ( ) &&

metadataRepoDescriptor == null )8 metadataRepoDescriptor = repo ;9 index++;

10 }

A ranking function is then:

{destinationRepos.size()− index if ¬destinationRepos.empty()0 otherwise

• use Java Modeling Language (JML) in which a ranking function can bedefined and use ghost variables to simulate an index. For example inListing A.9:

Listing 4.18: Index with JML annotations

1 //@ ghost i n t index ;2 //@ s e t index = 0 ;3 //@ de c r e a s e s ( ! des t inat ionRepos . empty ( ) ) ?

des t inat ionRepos . s i z e − index : 0 ;4 while ( i t e r . hasNext ( ) && ( a r t i f a c t R e p o D e s c r i p t o r ==

null | | metadataRepoDescriptor == null ) ) {5 Repos i to ryDesc r ip to r repo = i t e r . next ( ) ;6 i f ( repo . i s A r t i f a c t ( ) &&

a r t i f a c t R e p o D e s c r i p t o r == null )7 a r t i f a c t R e p o D e s c r i p t o r = repo ;8 i f ( repo . isMetadata ( ) &&

metadataRepoDescriptor == null )9 metadataRepoDescriptor = repo ;

10 //@ s e t index = index + 1 ;11 }

Note that the solutions above work when the iteration through a data struc-ture visits each element only once. If this is not true the upper bound may

Page 68: A Feasibility Study of Loop Bound Analysis for Loops with ...

64 CHAPTER 4. FEASIBILITY STUDY

be too small, for example when using both previous() and next() functions initerators. Using syntactical analysis, it is possible to detect this. Then extrapieces can be added, for which an element will be visited more than once.

4.3.4 Iterating through other data structures

This category contains data structures for which no method or field definingthe size of the data structure is available. This category is derived in foursubcategories.

Plain iterators

This subcategory contains loops using an iterator for which the type of the datastructure it iterates is not known. For example in Listing A.10, iteratorIteratoris set in the constructor of the class. However, it is set by an argument of thatconstructor, for which the only type known is Iterator, i.e. the original datastructure could be of any type that can return an Iterator.

The problem with plain iterators is that they do not contain size information,i.e. no upper bound is present. The only way to derive the size of an iterator isby counting the number of elements by iterating. A way to get an upper bound isto extend the iterator with an extra method, which saves the current location inthe data structure, iterates to the end of the data structures, while counting theelements, and then returns to the saved location. Then this function can be usedto in the upper bound. For example, if a variable iter is of the type Iterator,which has been extended with a method getSize(), iter.getSize() would be theupper bound. To obtain a ranking function an index variable needs to be addedas described in the previous section.

Streams

This subcategory contains streams. However, it is not possible to derive anupper bound on the length of a stream. Since the end of a stream is only knownwhen it is reached and it is not possible to go back. Moreover a stream cangrow in time, e.g. when using a stream for user import through the keyboard,it is unpredictable when new input will arrive. Therefore it is not possible tocalculate the length of the stream beforehand.

Other data structures

The last subcategory contains user defined classes which can be iterated. In thiscase, the author of the classes is responsible for creating a size method or field.However, the following generic approach could be used as well.

Generic approach

A generic approach to find the size of a data structure, e.g. linked lists or trees,is to extend the class of the data structure with an extra method. This methodcounts the number of elements in the data structure reachable from this element(including this element). For example in the case of the following class:

Page 69: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.3. CATEGORIES OF LOOPS WITH DISJUNCTIVE GUARDS 65

Listing 4.19: DataStructure Class

1 public class DataStructure {2 private DataStructure l e f t ;3 private DataStructure r i g h t ;4 }

This data structure is a tree. The following method calculates the number ofelements reachable from an element:

Listing 4.20: Size functions

1 public int g e t S i z e ( ) {2 1 + l e f t . g e t S i z e ( ) + r i g h t . g e t S i z e ( ) ;3 }

In general, the method to calculate the size, or the number of elementsreachable from a given node, is to calculate the recursive sum of 1 (for thiselement) and the size (or number of elements reachable) from the nodes whichthis elements points to, i.e. field pointers of the same type as the current element(in the example represented by variables left and right).

However, since this counts all elements, this can result in a overestimationof the upper bound of the number of iterations. For example in a tree structure,iterating through the nodes is mostly a path from root to leaf. Therefore, insuch cases the depth of the data structure is more useful than the number ofelements. This can be done using the following length function:

Listing 4.21: Max. size functions

1 public int g e t S i z e ( ) {2 1 + max( l e f t . g e t S i z e ( ) , r i g h t . g e t S i z e ( ) ) ;3 }

The Tree examples in the detailed feasibility study started at a node in thetree and would iterate to the root. The previous method would work, if thegetSize() function would be performed on the root. However, the followingwould be the applicable for the current node and would be the most precise:

Listing 4.22: Tree

1 public class DataStructure {2 private DataStructure parent ;3 }

Listing 4.23: Tree size

1 public int g e t S i z e ( ) {2 1 + parent . g e t S i z e ( ) ;3 }

A problem arises when cyclic data structures are used, i.e. if an elementof a data structure can be reached more than once when iterating through the

Page 70: A Feasibility Study of Loop Bound Analysis for Loops with ...

66 CHAPTER 4. FEASIBILITY STUDY

data structure. The solutions presented above will not terminate in the case ofcyclic data structures. A solution would be to save which elements already arecounted, so they can be skipped. However, in most cases cyclic data structuresare not desirable and are likely to be a bug.

4.3.5 Breaks

This section contains loops, which make use of breaks in the loop body, e.g.Listing A.55. The loop condition contains two statements, which are non-numerical, i.e. this cannot be used to determine a ranking function. However,since the loop contains a break statement, a possibility to derive a rankingfunction is to disregard the loop condition and try to make use of the breakinginside the loop, i.e. change the loop condition to true:

Listing 4.24: Replace loop guard

1 while ( true ) {2 i f (++index1 >= length1 ) break end ;3 }

This simplification can be made, since it will only overestimate the upperbound. However, this kind of loop can be derived using a program transforma-tion:

Listing 4.25: Program transformation

1 do {2 } while(++index1 < l ength1 ) ;

This loop can be derived using the basic method presented in Section 2.1,which results in the following:{

length1− index1 if index1 < length11 otherwise

4.3.6 Time

It is not possible to define an upper bound on loops that depend on time, sincetime is an uncontrollable external factor.

4.3.7 Threads

The same holds for loops that depend on the execution of threads, since waitingfor the execution of other threads is unpredictable.

4.3.8 Unpredictable updates

This category contains loops, which use numerical variables, but those are up-dated in an unpredictable way. For example, an integer is updated using thevalue of an object which can only be determined at runtime or a variable isonly updated given certain constraints, which can only be determined giventheir runtime values. The first is the case in Listing A.6, where integer len isupdated using a switch. The second is the case in Listing A.24, where ptr is

Page 71: A Feasibility Study of Loop Bound Analysis for Loops with ...

4.4. SUMMARY OF THE PROPOSED IMPROVEMENTS/EXTENSIONS67

only updated when some if-statements are true. However, the values of some ofthe variables in the if-statements are only available at runtime, for example thecontents of an array.

4.3.9 Loops depending on non-numerical values

This category consists of loops, which depend on non-numerical objects. There-fore, no upper bound can be defined.

For example, the loop in Listing A.4 depends on the fact if the current stateis a HttpParser.STATE SEEKING EOF.

4.4 Summary of the proposed improvements/ex-tensions

When parts of the loop condition are not usable for Loop Bound Analysis tryto simplify the loop condition by using Conjunctive Normal Form. If the loopcondition in CNF consists of different parts, check if at least one of the partsis useful. If so, remove all the parts that are not usable and simplify the loopcondition in such a way that loop bound analysis is possible.

When using multiple variables when checking for condition jumping, a prob-lem could occur, since it is possible that the number of condition jumping casesis infinite in theory. However, instead of checking for all distinct condition jump-ing cases, use polynomial interpolation to infer a polynomial which representthe set of condition jumping cases.

When iterating over a data structure, the upper bound on the number ofiterations is the size of that data structure. However, this is not defined for alldata structures. Therefore, it is sometimes needed to extend the code with amethod or field containing the size of a data structure. However, there are alsodata structures for which no upper bound can be given, e.g. streams. When theupper bound is inferred, transform it to a ranking function by using an index,which increases with each iteration.

When the loop condition is not usable and the CNF method cannot beapplied, but the loop can be exited by a break-statement in the loop. Thefollowing program transformation can be applied: create a do-while loop, wherethe loop condition contains the branch-condition of the break-statement.

4.5 Feasibility

In the detailed feasibility study (presented in Section 4.2), none of the loops wereapplicable to the original methods described in Chapters 2 and 3. Therefore, amanual derivation of ranking function was done for 134 loops with disjunctiveguards. This was possible for 84 of those loops. For all those loops a solutionis proposed, raising the number of loops with disjunctive guards for which aranking function can be inferred, from 0 to 84, i.e. from 0% to 62, 7%. Since thenumber of loops with disjunctive guards is 0, 26% of all loops, the gain for theLoop Bound Analysis method is 0, 26%×62, 7% ≈ 0.16% of all loops. Note thatthis only considers the use of the proposed solutions for loops with disjunctiveguards. However, some of the solutions are also applicable to loops without

Page 72: A Feasibility Study of Loop Bound Analysis for Loops with ...

68 CHAPTER 4. FEASIBILITY STUDY

disjunctive guards, e.g. loops that iterate over data structures, resulting in abigger gain.

The solution with the maximum gain in the detailed study was the solutionconsidering data structures with a size field or method. This solution will raisethe number of applicable loops with disjunctive guards to 52, which is 38, 8%of the total number of loops considered in the detailed study and 61, 9% of themaximum number of loops in the detailed study for which a ranking functioncan be inferred. In other words, more than half of the gain possible by analysingloops with disjunctive guards can be obtained by the proposed solution consid-ering data structures with a size field or method. Note that the total gain willeven be more.

The answer to the question if it is feasible to do Loop Bound Analysis onloops with disjunctive guard, is: yes, it is feasible. However, it is not possiblein all the cases, since it is not possible to define an upper bound on the numberof iterations in certain cases.

Page 73: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 5

Future work

This chapter contains other future work as an addition to the future work pre-sented in Section 4.3

5.1 Improved branch-splitting

In section 2.2.2 branch-splitting is explained. It is used to handle if-statementsin the loop body. Consider the following loop:

Listing 5.1: Branch-splitting example

1 while ( i > 0) {2 i f ( i > 100)3 i−−;4 else5 i −=10;6 }

Using the original method branch-splitting a ranking function would be d i10e.

However, this is an overestimation for any i > 100. More precise would be:

di10e if i > 0 ∧ i <= 100

(i− 100) + 10 if i > 1000 otherwise

This can be done by altering the node generation instead of splitting theif-statements in the loop. Divide the loop into different pieces, for each branchone and generate nodes for which the initial state satisfies the loop conditionand the branch-condition. However, this method generates some problems, e.g.for the loop in Listing 5.2. The upper bound of the loop is shown in Figure 5.1.

Listing 5.2: Loop with if-statements as given in [27]

1 while ( i > 0) {2 i f ( i > 100)3 i −= 10 ;

69

Page 74: A Feasibility Study of Loop Bound Analysis for Loops with ...

70 CHAPTER 5. FUTURE WORK

4 else5 i−−;6 }

Figure 5.1: Graph of the upper bound of Listing 2.4

In the previous example, the transition between two branches was with astep of 1. However, in the example shown in Figure 5.1 the transition betweenthe two branches uses a step of 10, resulting in a saw-like graph of the upperbound, called branch jumping. The result is that the precise upper bound of thebranch with i > 100 cannot be expressed in a polynomial. However, by choosingthe right test notes, the polynomial going through the tips of the saw can becalculated. Therefore, to get more precise ranking functions when using branch-splitting, branch jumping needs to be determined and the node generator hasto be altered to choose the right test nodes to get the right polynomial.

5.1.1 Using update functions

The original branch-splitting method, splits the loop on if-statements. How-ever, when calculating update functions (which are needed to determine whethercondition jumping occurs) the branches in the program are calculated, whichin some cases will result in less branches, since multiple if-statements could becombined into one branch.

Moreover, the updates in the loop can be transformed to the updates inupdate functions, since that will have the same effect.

5.2 Loop context

As explained in the basic method (presented in Section 2.1), one of the stepsof the main method is extracting the loop from its context, to place it into atesting context. However, this cannot be applied to every loop, e.g. the loop inListing 5.3.

Listing 5.3: A loop, which needs its context

Page 75: A Feasibility Study of Loop Bound Analysis for Loops with ...

5.2. LOOP CONTEXT 71

1 public void contextExample ( int i ) {2 Object o = new Object ( ) ;3 while ( i < 10) {4 o . t oS t r i ng ( ) ;5 i ++;6 }7 }

If this loop is extracted from its context, i.e. remove the declaration ofObject o, there will be compilation errors inside the loop, since the object usedinside the loop, o, is not declared then. A simple solution is to remove thestatement with object o inside the loop as well. However, this may lead toincorrect ranking functions. This is not the case for the example in Listing 5.3.However, it is possible that the loop variable is altered by an object declaredoutside the loop (as shown in the examples in Listings 5.4 and 5.5), so thenumber of iterations is dependent on the object and can for that reason notbe removed outside the loop, since it will lead to a wrong ranking function.However, it also does not have the context information it needs, since the objectis declared outside the loop and it may be dependent on values that are onlyavailable at runtime.

Listing 5.4: Loop counter incremented with object

1 public void Example ( int i ) {2 Incrementor incrementor = new Incrementor (2 ) ;3 while ( i < 10) {4 i = incrementor . inc ( i ) ;5 }6 }

Listing 5.5: Incrementor class

1 public class Incrementor {2 int incValue ;34 public Incrementor ( int incValue ) {5 this . incValue = incValue ;6 }78 public i n c ( int i ) {9 return i + incValue ;

10 }11 }

To solve this, two solutions have been devised. The first solution is addingJava Modelling Language (JML) contracts to the methods of the object, whichcontain information about what the function does to the loop variable, or moregenerally give information about what the method returns, since numerical loopvariables can only be changed through an assignment.

The second solution is creating a new testing environment, which will notextract the loop from its context, but will execute the program in such a way

Page 76: A Feasibility Study of Loop Bound Analysis for Loops with ...

72 CHAPTER 5. FUTURE WORK

that the loop will be entered and such that the runtime context information isavailable.

Page 77: A Feasibility Study of Loop Bound Analysis for Loops with ...

Chapter 6

Conclusion

In this thesis, the feasibility of Loop Bound Analysis for loops with disjunctiveguards has been researched. This gave the following results.

In the global evaluation the number of loops with disjunctive guards is lessthan 0.26% of all loops, i.e. loops with disjunctive guards are uncommon. There-fore, by adding method to analyse loops with disjunctive guards, result in a smallgain in the number of applicable loops.

A solution to the condition jumping challenge (as described in Chapter 3)has been implemented in the ResAna tool. However, none of the loops withdisjunctive guards in the global evaluation (Section 4.1) were applicable to themethods described in Chapters 2 and 3. In other words, loops with guards overdisjunctions and conjunctions of (in)equalities are even more uncommon.

In the detailed feasibility study, a ranking function and/or upper bound onthe number of iterations could be assigned to 62, 7% of the loops with disjunc-tive guards. The other 37, 3% of the loops with disjunctive guards were de-pendent of time, used threads, had unpredictable variable updates or involvednon-numerical objects.

Some extensions to the Loop Bound Analysis methods by Shkaravska et al.[27] and Kersten and Van Eekelen [21] have been proposed. Those extensionsinvolved: 1) Conjunctive Normal Form Elimination, which removes unusableparts of the loop guards, 2) polynomial interpolation on condition jumpingcases to handle more variables, 3) counting the number of elements of a datastructure and 4) do program transformation, in order to use break-statementsas exit condition.

The overall gain when adding methods to analyse loops with disjunctiveguards is approximately 0.16% of all loops. However, the methods used forloops with disjunctive guards are not exclusive to loops with disjunctive guard,i.e. other loops could be applicable as well. Therefore, the overall gain will bebigger, when considering the gain of loops without disjunctive guards as well.For example, the proposed solution to iterating over data structures is applicableto any loop which involves iterating over a data structure.

Therefore, Loop Bound Analysis on loops with disjunctive guards is feasiblefor certain cases. Adding methods to analyse loops with disjunctive guard,results in a small gain of analysable loops.

73

Page 78: A Feasibility Study of Loop Bound Analysis for Loops with ...

74 CHAPTER 6. CONCLUSION

Page 79: A Feasibility Study of Loop Bound Analysis for Loops with ...

Bibliography

[1] Wolfgang Ahrendt, Thomas Baar, Bernhard Beckert, Richard Bubel, Mar-tin Giese, Reiner Hahnle, Wolfram Menzel, Wojciech Mostowski, AndreasRoth, Steffen Schlager, and Peter H. Schmitt. The KeY tool. Software andSystem Modeling, 4:32–54, 2005.

[2] S. B. Akers. Binary decision diagrams. IEEE Trans. Comput., 27(6):509–516, June 1978.

[3] Elvira Albert, Puri Arenas, Samir Genaim, German Puebla, and DamianoZanardini. Cost Analysis of Object-Oriented Bytecode Programs. Theoret-ical Computer Science (Special Issue on Quantitative Aspects of Program-ming Languages), 413(1):142–159, 2012.

[4] Elvira Albert, Richard Bubel, Samir Genaim, Reiner Hahnle, GermanPuebla, and Guillermo Roman-Dıez. Verified resource guarantees usingCOSTA and KeY. In Proceedings of the 20th ACM SIGPLAN workshopon Partial evaluation and program manipulation, PEPM ’11, pages 73–76,New York, NY, USA, 2011. ACM.

[5] Clark Barrett, Aaron Stump, and Cesare Tinelli. The SMT-LIB standard:Version 2.0, September 2012.

[6] Bernhard Beckert, Reiner Hahnle, and Peter H. Schmitt. Verification ofobject-oriented software: The KeY approach. Springer-Verlag, Berlin, Hei-delberg, 2007.

[7] A. Biere, A. Biere, M. Heule, H. van Maaren, and T. Walsh. Handbook ofSatisfiability: Volume 185 Frontiers in Artificial Intelligence and Applica-tions. IOS Press, Amsterdam, The Netherlands, The Netherlands, 2009.

[8] C.K. Chui and M.J. Lai. Vandermonde determinant and langrange inter-polation in Rs. In Nonlinear and convex analysis, pages 23–35, 1987.

[9] David Cok and Joseph Kiniry. ESC/Java2: Uniting ESC/Java and JML.In Gilles Barthe, Lilian Burdy, Marieke Huisman, Jean-Louis Lanet, andTraian Muntean, editors, Construction and Analysis of Safe, Secure, andInteroperable Smart Devices, volume 3362 of Lecture Notes in ComputerScience, pages 108–128. Springer Berlin / Heidelberg, 2005.

[10] K. Czarnecki and A. Wasowski. Feature diagrams and logics: There andback again. In Software Product Line Conference, 2007. SPLC 2007. 11thInternational, pages 23–34, 2007.

75

Page 80: A Feasibility Study of Loop Bound Analysis for Loops with ...

76 BIBLIOGRAPHY

[11] Marianne de Michiel, Armelle Bonenfant, Hugues Casse, and Pascal Sain-rat. Static loop bound analysis of c programs based on flow analysis andabstract interpretation. In Proceedings of the 2008 14th IEEE Interna-tional Conference on Embedded and Real-Time Computing Systems andApplications, RTCSA ’08, pages 161–166, Washington, DC, USA, 2008.IEEE Computer Society.

[12] Leonardo de Moura and Nikolaj Bjrner. Z3: An efficient SMT solver. InC. Ramakrishnan and Jakob Rehof, editors, Tools and Algorithms for theConstruction and Analysis of Systems, volume 4963 of Lecture Notes inComputer Science, pages 337–340. Springer Berlin / Heidelberg, 2008.

[13] A. Ermedahl, C. Sandberg, J. Gustafsson, S. Bygde, and B. Lisper. Loopbound analysis based on a combination of program slicing, abstract inter-pretation, and invariant analysis. In 7th International Workshop on Worst-Case Execution Time Analysis, (WCET’2007), Pisa, Italy, July 2007.

[14] Cormac Flanagan, K. Rustan M. Leino, Mark Lillibridge, Greg Nelson,James B. Saxe, and Raymie Stata. Extended static checking for Java.SIGPLAN Not., 37(5):234–245, May 2002.

[15] Jdrzej Fulara and Krzysztof Jakubczyk. Practically applicable formal meth-ods. In Jan Leeuwen, Anca Muscholl, David Peleg, Jaroslav Pokorn, andBernhard Rumpe, editors, SOFSEM 2010: Theory and Practice of Com-puter Science, volume 5901 of Lecture Notes in Computer Science, pages407–418. Springer Berlin Heidelberg, 2010.

[16] Sumit Gulwani, Sagar Jain, and Eric Koskinen. Control-flow refinementand progress invariants for bound analysis. SIGPLAN Not., 44(6):375–385,June 2009.

[17] Sumit Gulwani, Krishna K. Mehra, and Trishul Chilimbi. SPEED: pre-cise and efficient static estimation of program computational complexity.SIGPLAN Not., 44(1):127–139, January 2009.

[18] Sumit Gulwani and Florian Zuleger. The reachability-bound problem. SIG-PLAN Not., 45(6):292–304, June 2010.

[19] James J. Hunt, Isabel Tonin, and Fridtjof B. Siebert. Using global dataflow analysis on bytecode to aid worst case execution time analysis for real-time java programs. In Proceedings of the 6th international workshop onJava technologies for real-time and embedded systems, JTRES ’08, pages97–105, New York, NY, USA, 2008. ACM.

[20] Rody Kersten, Olha Shkaravska, Bernard van Gastel, Manuel Montenegro,and Marko van Eekelen. Making resource analysis practical for real-timeJava. In Proceedings of the 10th International Workshop on Java Tech-nologies for Real-time and Embedded Systems, JTRES ’12, pages 135–144,New York, NY, USA, 2012. ACM.

[21] Rody Kersten and Marko van Eekelen. Ranking functions for loops withdisjunctive exit-conditions. Technical report, Dept. Computer Systems andComputing Universidad Complutense de Madrid, 2011.

Page 81: A Feasibility Study of Loop Bound Analysis for Loops with ...

BIBLIOGRAPHY 77

[22] James C. King. Symbolic execution and program testing. Commun. ACM,19(7):385–394, July 1976.

[23] Paul Lokuciejewski, Daniel Cordes, Heiko Falk, and Peter Marwedel. A fastand precise static loop analysis based on abstract interpretation, programslicing and polytope models. In Proceedings of the 7th annual IEEE/ACMInternational Symposium on Code Generation and Optimization, CGO ’09,pages 136–146, Washington, DC, USA, 2009. IEEE Computer Society.

[24] Manuel Montenegro, Olha Shkaravska, Marko van Eekelen, and RicardoPena. Interpolation-based height analysis for improving a recurrence solver.In Proceedings of the 2nd International Workshop on Foundational Practi-cal Aspects of Resource Analysis, FOPARA’11. Springer, 2012.

[25] Andreas Podelski and Andrey Rybalchenko. A complete method for thesynthesis of linear ranking functions. In Bernhard Steffen and Giorgio Levi,editors, Verification, Model Checking, and Abstract Interpretation, volume2937 of Lecture Notes in Computer Science, pages 239–251. Springer BerlinHeidelberg, 2004.

[26] Dr. Clifford A. Shaffer. Data Structures and Algorithm Analysis. DoverPublications, 2011.

[27] Olha Shkaravska, Rody Kersten, and Marko Van Eekelen. Test-based infer-ence of polynomial loop-bound functions. In Andreas Krall and HanspeterMossenbock, editors, PPPJ’10: Proceedings of the 8th International Con-ference on the Principles and Practice of Programming in Java, ACM Dig-ital Proceedings Series, pages 99–108, 2010.

[28] Olha Shkaravska, Marko van Eekelen, and Alejandro Tamalet. Collectedsize semantics for functional programs over lists. In Proceedings of the20th international conference on Implementation and application of func-tional languages, IFL’08, pages 118–137, Berlin, Heidelberg, 2011. Springer-Verlag.

[29] Olha Shkaravska, Marko C. J. D. van Eekelen, and Ron van Kesteren.Polynomial size analysis of first-order shapely functions. Logical Methodsin Computer Science, 5, issue 2, paper 10:1–35, 2009. Special Issue withSelected Papers from TLCA 2007.

[30] Olha Shkaravska, Ron van Kesteren, and Marko C. J. D. van Eekelen.Polynomial size analysis of first-order functions. In TLCA, pages 351–365,2007.

[31] Alejandro Tamalet, Olha Shkaravska, and Marko van Eekelen. Size analysisof algebraic data types. In Peter Achten, Pieter Koopman, and Marco T.Morazan, editors, Trends in Functional Programming Volume 9 (TFP’08),pages 33–48. Intellect Publishers, 2009.

[32] M. van Eekelen, O. Shkaravska, R. van Kesteren, B. Jacobs, E. Poll, andS. Smetsers. AHA: Amortized Heap Space Usage Analysis. In MarcoMorazan, editor, Trends in Functional Programming Volume 8: Selected

Page 82: A Feasibility Study of Loop Bound Analysis for Loops with ...

78 BIBLIOGRAPHY

Papers of the 8th International Symposium on Trends in Functional Pro-gramming (TFP07), New York, USA, pages 36–53. Intellect Publishers,UK, 2008.

[33] R. van Kesteren, O. Shkaravska, and M. van Eekelen. Inferring staticnon-monotonically sized types through testing. In Revised Selected Papersof the 16th international Workshop on Functional and (Constraint) LogicProgramming (WFLP) 2007, ENTCS, pages 45–63. Elsevier, 2008.

Page 83: A Feasibility Study of Loop Bound Analysis for Loops with ...

Appendix A

Loops used in the detailedfeasibility study

In this chapter the loops that are used in the detailed evaluation (Section 4.2) arelisted. Some loops contain extra code for better understanding. Code directlyabove the loop is code in the same method as the loop, Code separated withwhite space is from the same class as the loop and if annotated the code is froma superclass.

A.1 While-loops

Listing A.1: ./jdimodelsrc/org/eclipse/jdi/internal/SourceDebugExtension-Parser.java

1 private char [ ] fSmap ;2 private int fPo in t e r ;34 private char nextChar ( ) {5 i f (++fPo in t e r == fSmap . l ength ) {6 fEOF = true ;7 return ’ \000 ’ ;8 }9 fChar = fSmap [ fPo in t e r ] ;

10 return fChar ;11 }1213 while ( fChar == ’ ’ | | fChar == ’\ t ’ ) {14 nextChar ( ) ;15 }

Listing A.2: ./jdimodelsrc/org/eclipse/jdi/internal/SourceDebugExtension-Parser.java

1 int i = −1, l ength = s t r i n g . l ength ( ) ;2 char c ;3 while (++i < l ength && (( c = s t r i n g . charAt ( i ) ) == ’ ’ | | c == ’\ t ’ ) )4 ;

Listing A.3: ./jdimodelsrc/org/eclipse/jdi/internal/SourceDebugExtension-Parser.java

79

Page 84: A Feasibility Study of Loop Bound Analysis for Loops with ...

80 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

1 int i = 0 ;2 char c = lexem [ 0 ] ;3 while ( c == ’ ’ | | c == ’\ t ’ ) {4 c = lexem[++ i ] ;5 }

Listing A.4: ./org/eclipse/jetty/http/HttpParser.java

1 while ( contentView . l ength ( ) == 0 && ! ( i s S t a t e ( HttpParser .STATE END) | |i s S t a t e ( HttpParser .STATE SEEKING EOF) ) && endp !=null && endp .isOpen ( ) )

2 {3 i f ( ! endp . i sB l o ck ing ( ) )4 {5 i f ( parseNext ( )>0)6 continue ;78 i f ( ! endp . blockReadable (maxIdleTime ) )9 {

10 endp . c l o s e ( ) ;11 throw new EofException ( ” timeout ” ) ;12 }13 }1415 parseNext ( ) ;16 }

Listing A.5: ./org/eclipse/jetty/http/AbstractGenerator.java

1 while (now<end && ( content !=null && content . l ength ( )>0 | | bu f f e r !=null &&bu f f e r . l ength ( )>0) && endp . isOpen ( )&& ! endp . isOutputShutdown ( ) )

2 {3 blockForOutput ( end−now) ;4 now=System . cur rentTimeMi l l i s ( ) ;5 }

Listing A.6: ./org/eclipse/jetty/http/HttpGenerator.java

1 do2 {3 l a s t f l u s h=t o f l u s h ;4 switch ( t o f l u s h )5 {6 case 7 :7 throw new I l l e g a l S t a t eEx c ep t i o n ( ) ; // should

never happen !8 case 6 :9 l en = endp . f l u s h ( header , bu f f e r , null ) ;

10 break ;11 case 5 :12 l en = endp . f l u s h ( header , content , null ) ;13 break ;14 case 4 :15 l en = endp . f l u s h ( header ) ;16 break ;17 case 3 :18 l en = endp . f l u s h ( bu f f e r , content , null ) ;19 break ;20 case 2 :21 l en = endp . f l u s h ( b u f f e r ) ;22 break ;23 case 1 :24 l en = endp . f l u s h ( content ) ;25 break ;26 case 0 :27 {28 l en =0;29 // Nothing more we can wr i t e now .

Page 85: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 81

30 i f ( header != null )31 header . c l e a r ( ) ;3233 bypass = fa l se ;34 bufferChunked = fa l se ;3536 i f ( b u f f e r != null )37 {38 bu f f e r . c l e a r ( ) ;39 i f ( contentLength == HttpTokens .

CHUNKEDCONTENT)40 {41 // r e s e r v e some space f o r the

chunk header42 bu f f e r . setPutIndex (CHUNK SPACE)

;43 bu f f e r . setGetIndex (CHUNK SPACE)

;4445 // Spe c i a l case handl ing f o r

smal l l e f t over bu f f e r from46 // an addContent that caused a

bu f f e r f l u s h .47 i f ( content != null && content

. l ength ( ) < bu f f e r . space ( )&& s t a t e !=

STATE FLUSHING)48 {49 bu f f e r . put ( content ) ;50 content . c l e a r ( ) ;51 content=null ;52 }53 }54 }5556 // Are we complete ly f i n i s h e d f o r now?57 i f ( ! needCRLF && ! needEOC && ( content==null

| | content . l ength ( )==0))58 {59 i f ( s t a t e == STATE FLUSHING)60 s t a t e = STATE END;6162 i f ( s t a t e==STATE END && pe r s i s t e n t !=

null && ! p e r s i s t e n t && s t a t u s!=100 && method==null )

63 endp . shutdownOutput ( ) ;64 }65 else66 // Try to prepare more to wr i t e .67 prepareBu f f e r s ( ) ;68 }6970 }7172 i f ( l en > 0)73 t o t a l+=len ;7475 t o f l u s h = flushMask ( ) ;76 }77 // loop whi le p rog r e s s i s being made (OR we have prepared some bu f f e r s

that might make prog r e s s )78 while ( len>0 | | ( t o f l u s h !=0 && l a s t f l u s h==0)) ;

Listing A.7: ./org/eclipse/jetty/server/session/AbstractSessionIdManager.java

1 while ( id==null | | id . l ength ( ) ==0|| idInUse ( id ) )2 {3 long r0= weakRandom4 ?( hashCode ( ) ˆRuntime . getRuntime ( ) . freeMemory ( ) ˆ random . next Int ( )

ˆ ( ( ( long ) r eques t . hashCode ( ) )<<32))5 : random . nextLong ( ) ;6 i f ( r0<0)

Page 86: A Feasibility Study of Loop Bound Analysis for Loops with ...

82 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

7 r0=−r0 ;8 long r1= weakRandom9 ?( hashCode ( ) ˆRuntime . getRuntime ( ) . freeMemory ( ) ˆ random . next Int ( )

ˆ ( ( ( long ) r eques t . hashCode ( ) )<<32))10 : random . nextLong ( ) ;11 i f ( r1<0)12 r1=−r1 ;13 id=Long . t oS t r i ng ( r0 , 3 6 )+Long . t oS t r i ng ( r1 , 3 6 ) ;1415 //add in the id o f the node to ensure unique id ac ro s s c l u s t e r16 //NOTE th i s i s d i f f e r e n t to the node s u f f i x which denotes which

node the reques t was r e c e i v ed on17 i f ( workerName!=null )18 id= workerName + id ;19 }

Listing A.8: ./org/eclipse/jetty/server/ResourceCache.java

1 while ( cache . s i z e ( )>0 && ( cachedF i l e s . get ( )> maxCachedFiles | |cachedS i ze . get ( )> maxCacheSize ) )

2 {3 // Scan the e n t i r e cache and generate an ordered l i s t by l a s t

acce s s ed time .4 SortedSet<Content> so r t ed= new TreeSet<Content>(5 new Comparator<Content>()6 {7 public int compare ( Content c1 , Content

c2 )8 {9 i f ( c1 . l a s tAcce s s ed<c2 .

l a s tAcc e s s ed )10 return −1;1112 i f ( c1 . l a s tAcce s s ed>c2 .

l a s tAcc e s s ed )13 return 1 ;1415 i f ( c1 . l ength<c2 . l eng th )16 return −1;1718 return c1 . key . compareTo ( c2 . key

) ;19 }20 }) ;21 for ( Content content : cache . va lues ( ) )22 so r t ed . add ( content ) ;2324 // Inva l i d a t e l e a s t r e c en t l y used f i r s t25 for ( Content content : so r t ed )26 {27 i f ( c a chedF i l e s . get ( )<= maxCachedFiles && cachedS i ze .

get ( )<= maxCacheSize )28 break ;29 i f ( content== cache . remove ( content . getKey ( ) ) )30 content . i n v a l i d a t e ( ) ;31 }32 }

Listing A.9: ./org/eclipse/equinox/p2/internal/repository/tools/AbstractApplication.java

1 private List<Repos i toryDescr iptor> dest inat ionRepos = new ArrayList<Repos i toryDescr iptor >() ;

23 I t e r a t o r<Repos i toryDescr iptor> i t e r = dest inat ionRepos . i t e r a t o r ( ) ;4 while ( i t e r . hasNext ( ) && ( a r t i f a c tRepoDes c r i p t o r == null | |

metadataRepoDescriptor == null ) ) {5 Repos i to ryDesc r ip to r repo = i t e r . next ( ) ;6 i f ( repo . i s A r t i f a c t ( ) && ar t i f a c tRepoDes c r i p t o r == null )7 a r t i f a c tRepoDes c r i p t o r = repo ;8 i f ( repo . isMetadata ( ) && metadataRepoDescriptor == null )

Page 87: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 83

9 metadataRepoDescriptor = repo ;10 }

Listing A.10: ./org/eclipse/equinox/internal/p2/metadata/expression/CompoundIterator.java

1 private f ina l I t e r a t o r <? extends Object> i t e r a t o r I t e r a t o r ;2 private I t e r a t o r<T> c u r r e n t I t e r a t o r ;34 public CompoundIterator ( I t e r a t o r <? extends Object> i t e r a t o r ) {5 this . i t e r a t o r I t e r a t o r = i t e r a t o r ;6 }78 while ( c u r r e n t I t e r a t o r == null | | ! c u r r e n t I t e r a t o r . hasNext ( ) ) {9 i f ( ! i t e r a t o r I t e r a t o r . hasNext ( ) )

10 return fa l se ;1112 Object nex t I t o r = i t e r a t o r I t e r a t o r . next ( ) ;13 c u r r e n t I t e r a t o r = ( nex t I t o r instanceof I t e r a t o r <?>) ? ( I t e r a t o r<

T>) nex t I t o r : Repea tab l e I t e r a to r .<T> c r e a t e ( nex t I t o r ) ;14 }

Listing A.11: ./org/eclipse/equinox/internal/p2/metadata/expression/parser/QLParser.java

1 //Def ined in sup e r c l a s s Express ionParser :2 protected St r ing expr e s s i on ;3 protected int tokenPos ;4 protected int currentToken ;5 protected void nextToken ( ) {6 tokenValue = null ;7 int top = expre s s i on . l ength ( ) ;8 char c = 0 ;9 while ( tokenPos < top ) {

10 c = expre s s i on . charAt ( tokenPos ) ;11 i f ( ! Character . i sWhitespace ( c ) )12 break ;13 ++tokenPos ;14 }15 i f ( tokenPos >= top ) {16 lastTokenPos = top ;17 currentToken = TOKENEND;18 return ;19 }2021 lastTokenPos = tokenPos ;22 switch ( c ) {23 case ’ | ’ :24 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’ | ’ ) {25 tokenValue = OPERATOROR;26 currentToken = TOKENOR;27 tokenPos += 2 ;28 } else {29 currentToken = TOKEN PIPE;30 ++tokenPos ;31 }32 break ;3334 case ’& ’ :35 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’&’ ) {36 tokenValue = OPERATORAND;37 currentToken = TOKENAND;38 tokenPos += 2 ;39 } else40 currentToken = TOKENERROR;41 break ;4243 case ’= ’ :44 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {

Page 88: A Feasibility Study of Loop Bound Analysis for Loops with ...

84 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

45 tokenValue = OPERATOREQUALS;46 currentToken = TOKENEQUAL;47 tokenPos += 2 ;48 } else49 currentToken = TOKENERROR;50 break ;5152 case ’ ! ’ :53 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {54 tokenValue = OPERATORNOT EQUALS;55 currentToken = TOKENNOT EQUAL;56 tokenPos += 2 ;57 } else {58 currentToken = TOKENNOT;59 ++tokenPos ;60 }61 break ;6263 case ’ ˜ ’ :64 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {65 tokenValue = OPERATORMATCHES;66 currentToken = TOKENMATCHES;67 tokenPos += 2 ;68 } else69 currentToken = TOKENERROR;70 break ;7172 case ’> ’ :73 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {74 tokenValue = OPERATORGTEQUAL;75 currentToken = TOKENGREATEREQUAL;76 tokenPos += 2 ;77 } else {78 currentToken = TOKENGREATER;79 ++tokenPos ;80 }81 break ;8283 case ’< ’ :84 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {85 tokenValue = OPERATOR LT EQUAL;86 currentToken = TOKEN LESS EQUAL;87 tokenPos += 2 ;88 } else {89 currentToken = TOKEN LESS;90 ++tokenPos ;91 }92 break ;9394 case ’ ? ’ :95 currentToken = TOKEN IF;96 ++tokenPos ;97 break ;9899 case ’ : ’ :

100 currentToken = TOKEN ELSE;101 ++tokenPos ;102 break ;103104 case ’ . ’ :105 currentToken = TOKENDOT;106 ++tokenPos ;107 break ;108109 case ’ $ ’ :110 currentToken = TOKENDOLLAR;111 ++tokenPos ;112 break ;113114 case ’{ ’ :

Page 89: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 85

115 currentToken = TOKEN LC;116 ++tokenPos ;117 break ;118119 case ’} ’ :120 currentToken = TOKENRC;121 ++tokenPos ;122 break ;123124 case ’ ( ’ :125 currentToken = TOKEN LP;126 ++tokenPos ;127 break ;128129 case ’ ) ’ :130 currentToken = TOKEN RP;131 ++tokenPos ;132 break ;133134 case ’ [ ’ :135 currentToken = TOKEN LB;136 ++tokenPos ;137 break ;138139 case ’ ] ’ :140 currentToken = TOKENRB;141 ++tokenPos ;142 break ;143144 case ’ , ’ :145 currentToken = TOKENCOMMA;146 ++tokenPos ;147 break ;148149 case ’ ” ’ :150 case ’ \ ’ ’ :151 par s eDe l im i t edSt r ing ( c ) ;152 break ;153154 case ’ / ’ :155 par s eDe l im i t edSt r ing ( c ) ;156 i f ( currentToken == TOKEN LITERAL)157 tokenValue = SimplePattern . compile ( (

S t r ing ) tokenValue ) ;158 break ;159160 default :161 i f ( Character . i sD i g i t ( c ) ) {162 int s t a r t = tokenPos++;163 while ( tokenPos < top && Character .

i sD i g i t ( exp r e s s i on . charAt ( tokenPos )) )

164 ++tokenPos ;165 tokenValue = In t eg e r . valueOf ( exp r e s s i on .

sub s t r i ng ( s ta r t , tokenPos ) ) ;166 currentToken = TOKEN LITERAL;167 break ;168 }169 i f ( Character . i s J a v a I d e n t i f i e r S t a r t ( c ) ) {170 int s t a r t = tokenPos++;171 while ( tokenPos < top && Character .

i s J a v a I d e n t i f i e rP a r t ( expr e s s i on .charAt ( tokenPos ) ) )

172 ++tokenPos ;173 St r ing word = expre s s i on . sub s t r i ng ( s ta r t

, tokenPos ) ;174 In t eg e r token = keywordToTokenMap ( ) . get (

word ) ;175 i f ( token == null )176 currentToken = TOKEN IDENTIFIER;177 else178 currentToken = token . intValue ( ) ;179 tokenValue = word ;180 break ;

Page 90: A Feasibility Study of Loop Bound Analysis for Loops with ...

86 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

181 }182 throw syntaxError ( ) ;183 }184 }185186 while ( currentToken == TOKENDOT | | currentToken == TOKEN LB) {187 int savePos = tokenPos ;188 int saveToken = currentToken ;189 Object saveTokenValue = tokenValue ;190 nextToken ( ) ;191 i f ( saveToken == TOKENDOT) {192 switch ( currentToken ) {193 case TOKEN IDENTIFIER :194 name = ( St r ing ) tokenValue ;195 nextToken ( ) ;196 i f ( currentToken == TOKEN LP) {197 nextToken ( ) ;198 IExpres s ion [ ] c a l lA rg s =

parseArray ( ) ;199 assertToken (TOKEN RP) ;200 nextToken ( ) ;201 expr = fa c t o ry . memberCall ( expr ,

name , ca l lA rg s ) ;202 } else203 expr = fa c t o ry .member( expr , name

) ;204 break ;205206 default :207 tokenPos = savePos ;208 currentToken = saveToken ;209 tokenValue = saveTokenValue ;210 return expr ;211 }212 } else {213 IExpres s ion atExpr = parseMember ( ) ;214 assertToken (TOKENRB) ;215 nextToken ( ) ;216 expr = fa c t o ry . at ( expr , atExpr ) ;217 }218 }

Listing A.12: ./org/eclipse/equinox/internal/p2/metadata/expression/parser/LDAPFilterParser.java

1 int begin = po s i t i o n ;2 int end = po s i t i o n ;3 char c = f i l t e r S t r i n g . charAt ( begin ) ;4 while ( ! ( c == ’ ˜ ’ | | c == ’< ’ | | c == ’> ’ | | c == ’=’ | | c == ’ ( ’ | | c

== ’ ) ’ ) ) {5 po s i t i o n++;6 i f ( ! Character . i sWhitespace ( c ) )7 end = po s i t i o n ;8 c = f i l t e r S t r i n g . charAt ( po s i t i o n ) ;9 }

Listing A.13: ./org/eclipse/equinox/internal/p2/metadata/expression/parser/ExpressionParser.java

1 protected St r ing expr e s s i on ;2 protected int tokenPos ;3 protected int currentToken ;4 protected void nextToken ( ) {5 tokenValue = null ;6 int top = expre s s i on . l ength ( ) ;7 char c = 0 ;8 while ( tokenPos < top ) {9 c = expre s s i on . charAt ( tokenPos ) ;

10 i f ( ! Character . i sWhitespace ( c ) )11 break ;12 ++tokenPos ;13 }

Page 91: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 87

14 i f ( tokenPos >= top ) {15 lastTokenPos = top ;16 currentToken = TOKENEND;17 return ;18 }1920 lastTokenPos = tokenPos ;21 switch ( c ) {22 case ’ | ’ :23 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’ | ’ ) {24 tokenValue = OPERATOROR;25 currentToken = TOKENOR;26 tokenPos += 2 ;27 } else {28 currentToken = TOKEN PIPE;29 ++tokenPos ;30 }31 break ;3233 case ’& ’ :34 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’&’ ) {35 tokenValue = OPERATORAND;36 currentToken = TOKENAND;37 tokenPos += 2 ;38 } else39 currentToken = TOKENERROR;40 break ;4142 case ’= ’ :43 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {44 tokenValue = OPERATOREQUALS;45 currentToken = TOKENEQUAL;46 tokenPos += 2 ;47 } else48 currentToken = TOKENERROR;49 break ;5051 case ’ ! ’ :52 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {53 tokenValue = OPERATORNOT EQUALS;54 currentToken = TOKENNOT EQUAL;55 tokenPos += 2 ;56 } else {57 currentToken = TOKENNOT;58 ++tokenPos ;59 }60 break ;6162 case ’ ˜ ’ :63 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {64 tokenValue = OPERATORMATCHES;65 currentToken = TOKENMATCHES;66 tokenPos += 2 ;67 } else68 currentToken = TOKENERROR;69 break ;7071 case ’> ’ :72 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {73 tokenValue = OPERATORGTEQUAL;74 currentToken = TOKENGREATEREQUAL;75 tokenPos += 2 ;76 } else {77 currentToken = TOKENGREATER;78 ++tokenPos ;79 }80 break ;81

Page 92: A Feasibility Study of Loop Bound Analysis for Loops with ...

88 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

82 case ’< ’ :83 i f ( tokenPos + 1 < top && expre s s i on . charAt (

tokenPos + 1) == ’=’ ) {84 tokenValue = OPERATOR LT EQUAL;85 currentToken = TOKEN LESS EQUAL;86 tokenPos += 2 ;87 } else {88 currentToken = TOKEN LESS;89 ++tokenPos ;90 }91 break ;9293 case ’ ? ’ :94 currentToken = TOKEN IF;95 ++tokenPos ;96 break ;9798 case ’ : ’ :99 currentToken = TOKEN ELSE;

100 ++tokenPos ;101 break ;102103 case ’ . ’ :104 currentToken = TOKENDOT;105 ++tokenPos ;106 break ;107108 case ’ $ ’ :109 currentToken = TOKENDOLLAR;110 ++tokenPos ;111 break ;112113 case ’{ ’ :114 currentToken = TOKEN LC;115 ++tokenPos ;116 break ;117118 case ’} ’ :119 currentToken = TOKENRC;120 ++tokenPos ;121 break ;122123 case ’ ( ’ :124 currentToken = TOKEN LP;125 ++tokenPos ;126 break ;127128 case ’ ) ’ :129 currentToken = TOKEN RP;130 ++tokenPos ;131 break ;132133 case ’ [ ’ :134 currentToken = TOKEN LB;135 ++tokenPos ;136 break ;137138 case ’ ] ’ :139 currentToken = TOKENRB;140 ++tokenPos ;141 break ;142143 case ’ , ’ :144 currentToken = TOKENCOMMA;145 ++tokenPos ;146 break ;147148 case ’ ” ’ :149 case ’ \ ’ ’ :150 par s eDe l im i t edSt r ing ( c ) ;151 break ;152153 case ’ / ’ :154 par s eDe l im i t edSt r ing ( c ) ;

Page 93: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 89

155 i f ( currentToken == TOKEN LITERAL)156 tokenValue = SimplePattern . compile ( (

S t r ing ) tokenValue ) ;157 break ;158159 default :160 i f ( Character . i sD i g i t ( c ) ) {161 int s t a r t = tokenPos++;162 while ( tokenPos < top && Character .

i sD i g i t ( exp r e s s i on . charAt ( tokenPos )) )

163 ++tokenPos ;164 tokenValue = In t eg e r . valueOf ( exp r e s s i on .

sub s t r i ng ( s ta r t , tokenPos ) ) ;165 currentToken = TOKEN LITERAL;166 break ;167 }168 i f ( Character . i s J a v a I d e n t i f i e r S t a r t ( c ) ) {169 int s t a r t = tokenPos++;170 while ( tokenPos < top && Character .

i s J a v a I d e n t i f i e rP a r t ( expr e s s i on .charAt ( tokenPos ) ) )

171 ++tokenPos ;172 St r ing word = expre s s i on . sub s t r i ng ( s ta r t

, tokenPos ) ;173 In t eg e r token = keywordToTokenMap ( ) . get (

word ) ;174 i f ( token == null )175 currentToken = TOKEN IDENTIFIER;176 else177 currentToken = token . intValue ( ) ;178 tokenValue = word ;179 break ;180 }181 throw syntaxError ( ) ;182 }183 }184185 while ( currentToken == TOKENDOT | | currentToken == TOKEN LB) {186 int savePos = tokenPos ;187 int saveToken = currentToken ;188 Object saveTokenValue = tokenValue ;189 nextToken ( ) ;190 i f ( saveToken == TOKENDOT) {191 switch ( currentToken ) {192 case TOKEN IDENTIFIER :193 name = ( St r ing )

tokenValue ;194 nextToken ( ) ;195 expr = fa c t o ry .member(

expr , name) ;196 break ;197198 default :199 tokenPos = savePos ;200 currentToken = saveToken

;201 tokenValue =

saveTokenValue ;202 return expr ;203 }204 } else {205 IExpres s ion atExpr = parseMember ( ) ;206 assertToken (TOKENRB) ;207 nextToken ( ) ;208 expr = fa c t o ry . at ( expr , atExpr ) ;209 }210 }

Listing A.14: ./org/eclipse/equinox/internal/app/EclipseAppHandle.java

1 while ( ! s e tRe su l t && ( delay > 0 | | timeout == 0) ) {

Page 94: A Feasibility Study of Loop Bound Analysis for Loops with ...

90 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

2 wait ( de lay ) ; // only wait f o r the s p e c i f i e d amount o f time3 i f ( t imeout > 0)4 delay −= (System . cur rentTimeMi l l i s ( ) − startTime ) ;5 }

Listing A.15: ./org/eclipse/equinox/console/common/ConsoleInput-Stream.java

1 public synchronized int read ( ) {2 while ( cur rent == null && bu f f e r . isEmpty ( ) && ! i sC lo s ed ) {3 try {4 wait ( ) ;5 } catch ( Inter ruptedExcept ion e ) {6 return −1;7 }8 }9 i f ( i sC lo s ed ) {

10 return −1;11 }1213 try {14 i f ( cur rent == null ) {15 cur rent = bu f f e r . remove (0) ;16 return cur rent [ pos++] & 0xFF ;17 } else {1819 return cur rent [ pos++] & 0xFF ;20 }21 } f ina l ly {22 i f ( cur rent != null ) {23 i f ( pos == current . l ength ) {24 cur rent = null ;25 pos = 0 ;26 }27 }28 }29 }3031 while ( ( pos > 0 | | ! b u f f e r . isEmpty ( ) ) && readCnt < l en ) {32 i = read ( ) ;33 i f ( i == −1) {34 return ( readCnt > 0) ? readCnt : i ;35 }36 b [ cur rOf f ] = (byte ) i ;37 cur rOf f++;38 readCnt++;39 }

Listing A.16: ./org/eclipse/equinox/log/internal/BasicReadWriteLock.java

1 while ( wr i t i ng != null | | wri te r sWait ing != 0) {2 try {3 i f ( wr i t i ng == Thread . currentThread ( ) )4 throw new I l l e g a l S t a t eEx c ep t i o n ( ”Attempted to

nest read lock i n s i d e a wr i t e l ock ” ) ; //$NON−NLS−1$

5 wait ( ) ;6 } catch ( Inter ruptedExcept ion e ) {7 // r e s e t i n t e r rup t ed s t a t e but keep wait ing8 Thread . currentThread ( ) . i n t e r r up t ( ) ;9 }

10 }

Listing A.17: ./org/eclipse/equinox/log/internal/BasicReadWriteLock.java

1 while ( wr i t i ng != null | | currentReaders . s i z e ( ) != 0) {2 try {

Page 95: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 91

3 i f ( wr i t i ng == Thread . currentThread ( ) | | currentReaders .conta in s (Thread . currentThread ( ) ) )

4 throw new I l l e g a l S t a t eEx c ep t i o n ( ”Attempted tonest wr i t e l ock i n s i d e a read or wr i t e l ock” ) ; //$NON−NLS−1$

5 wait ( ) ;6 } catch ( Inter ruptedExcept ion e ) {7 // r e s e t i n t e r rup t ed s t a t e but keep wai t ing8 Thread . currentThread ( ) . i n t e r r up t ( ) ;9 }

10 }

Listing A.18: ./org/eclipse/ui/internal/quickaccess/QuickAccessContents.java

1 do {2 // w i l l be s e t to f a l s e i f we f i nd a prov ider with remaining3 // elements4 done = true ;5 for ( int i = 0 ; i < prov ide r s . l ength6 && ( showAllMatches | | countTotal < maxCount) ; i

++) {7 i f ( e n t r i e s [ i ] == null ) {8 e n t r i e s [ i ] = new ArrayList ( ) ;9 indexPerProvider [ i ] = 0 ;

10 }11 int count = 0 ;12 QuickAccessProvider prov ide r = prov ide r s [ i ] ;13 i f ( f i l t e r . l ength ( ) > 014 | | prov ide r . i sAlwaysPresent ( )15 | | showAllMatches ) {16 QuickAccessElement [ ] e lements = prov ide r17 . getElementsSorted ( ) ;18 int j = indexPerProvider [ i ] ;19 while ( j < e lements . l ength20 && ( showAllMatches | | ( count <

countPerProvider &&countTotal < maxCount) ) ) {

21 QuickAccessElement element = elements [ j] ;

22 QuickAccessEntry entry ;23 i f ( f i l t e r . l ength ( ) == 0) {24 i f ( i == 0 | | showAllMatches ) {25 entry = new

QuickAccessEntry (element , provider ,

26 new int[ 0 ] [ 0 ] ,

new

int[ 0 ] [ 0 ] );

27 } else {28 entry = null ;29 }30 } else {31 entry = element . match ( f i l t e r ,

p rov ide r ) ;32 }33 i f ( entry != null ) {34 e n t r i e s [ i ] . add ( entry ) ;35 count++;36 countTotal++;37 i f ( i == 0 && entry . element ==

perfectMatch ) {38 perfectMatchAdded = true

;39 maxCount =

MAXCOUNTTOTAL;40 }41 }

Page 96: A Feasibility Study of Loop Bound Analysis for Loops with ...

92 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

42 j++;43 }44 indexPerProvider [ i ] = j ;45 i f ( j < e lements . l ength ) {46 done = fa l se ;47 }48 }49 }50 // from now on , add one element per prov ider51 countPerProvider = 1 ;52 } while ( ( showAllMatches | | countTotal < maxCount) && ! done ) ;

Listing A.19: ./org/eclipse/ui/internal/navigator/resources/actions/Re-sourceMgmtActionProvider.java

1 IS t r u c tu r edSe l e c t i on s e l e c t i o n = ( IS t ru c tu r edSe l e c t i on ) getContext ( ) .g e t S e l e c t i o n ( ) ;

2 I t e r a t o r r e s ou r c e s = s e l e c t i o n . i t e r a t o r ( ) ;3 while ( r e s ou r c e s . hasNext ( ) && ( ! hasOpenProjects | | ! hasClosedPro j ec t s | |

hasBui lder | | i s P r o j e c t S e l e c t i o n ) ) {4 Object next = r e s ou r c e s . next ( ) ;5 IP ro j e c t p r o j e c t = null ;67 i f ( next instanceof IP ro j e c t ) {8 p r o j e c t = ( IP ro j e c t ) next ;9 } else i f ( next instanceof IAdaptable ) {

10 p r o j e c t = ( IP ro j e c t ) ( ( IAdaptable ) next ) . getAdapter (IP ro j e c t . class ) ;

11 }1213 i f ( p r o j e c t == null ) {14 i s P r o j e c t S e l e c t i o n = fa l se ;15 continue ;16 }17 i f ( p r o j e c t . isOpen ( ) ) {18 hasOpenProjects = true ;19 i f ( hasBui lder && ! hasBui lder ( p r o j e c t ) ) {20 hasBui lder = fa l se ;21 }22 } else {23 hasClosedPro j ec t s = true ;24 hasBui lder = fa l se ;25 }26 }

Listing A.20: ./org/eclipse/ui/internal/console/ConsoleDocumentAdapter.java

1 while ( index > −1 && ( l i n e . charAt ( index )==’\n ’ | | l i n e . charAt ( index )==’\ r’ ) ) {

2 index−−;3 }

Listing A.21: ./org/eclipse/jdt/ui/text/folding/DefaultJavaFoldingStructure-Provider.java

1 while ( te rmina l != ITerminalSymbols .TokenNameEOF && ! ( te rmina l ==ITerminalSymbols . TokenNameclass | | te rmina l == ITerminalSymbols .TokenNameinterface | | te rmina l == ITerminalSymbols . TokenNameenum | |( foundComment && ( termina l == ITerminalSymbols . TokenNameimport | |

te rmina l == ITerminalSymbols . TokenNamepackage ) ) ) ) {23 i f ( te rmina l == ITerminalSymbols .TokenNameCOMMENT JAVADOC | |

te rmina l == ITerminalSymbols .TokenNameCOMMENT BLOCK | |te rmina l == ITerminalSymbols .TokenNameCOMMENT LINE) {

4 i f ( ! foundComment )5 headerStart= scanner .

getCurrentTokenStartPos i t ion ( ) ;

Page 97: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 93

6 headerEnd= scanner . getCurrentTokenEndPosition ( ) ;7 foundComment= true ;8 }9 termina l= scanner . getNextToken ( ) ;

10 }

Listing A.22: ./org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java

1 while ( s t a r t < cu r rS ta r t | | end > currEnd ) { // go up un t i l a nodecover s a l l

2 node= node . getParent ( ) ;3 cu r rS ta r t= node . g e tS t a r tPo s i t i on ( ) ;4 currEnd= cur rS ta r t + node . getLength ( ) ;5 }

Listing A.23: ./org/eclipse/jdt/internal/formatter/comment/HTMLEn-tity2JavaReader.java

1 //As de f ined in sup e r c l a s s Subst i tut ionTextReader :2 protected int nextChar ( ) throws IOException {3 this . fReadFromBuffer= ( this . fBu f f e r . l ength ( ) > 0) ;4 i f ( this . fReadFromBuffer ) {5 char ch= this . fBu f f e r . charAt ( this . f Index++) ;6 i f ( this . f Index >= this . fBu f f e r . l ength ( ) ) {7 this . fBu f f e r . setLength (0) ;8 this . f Index= 0 ;9 }

10 return ch ;11 } else {12 int ch= this . fCharAfterWhiteSpace ;13 i f ( ch == −1) {14 ch= this . fReader . read ( ) ;15 }16 i f ( this . fSkipWhiteSpace && ScannerHelper . i sWhitespace ( (

char ) ch ) ) {17 do {18 ch= this . fReader . read ( ) ;19 } while ( ScannerHelper . i sWhitespace ( ( char ) ch ) ) ;20 i f ( ch != −1) {21 this . fCharAfterWhiteSpace= ch ;22 return ’ ’ ;23 }24 } else {25 this . fCharAfterWhiteSpace= −1;26 }27 return ch ;28 }29 }3031 while ( ScannerHelper . i sL e t t e rOrD ig i t ( ( char ) ch ) | | ch == ’#’ ) {32 buf . append ( ( char ) ch ) ;33 ch= nextChar ( ) ;34 }

Listing A.24: ./org/eclipse/jdt/internal/formatter/FormatJavadocText.java

1 while ( idx<=this . s epa ra to r sPt r | | ( this . htmlNodesPtr != −1 && ptr <=this . htmlNodesPtr ) ) {

2 i f ( idx > this . s epa ra to r sPt r ) {3 // l a s t node4 FormatJavadocNode node = this . htmlNodes [ ptr++];5 node . toStringDebug ( bu f f e r , source ) ;6 return ;7 }8 int end = ( int ) ( this . s epa ra to r s [ idx ] >>> 32) ;9 i f ( this . htmlNodesPtr >= 0 && ptr <= this . htmlNodesPtr && end >

this . htmlNodes [ ptr ] . s ou r c eS ta r t ) {10 FormatJavadocNode node = this . htmlNodes [ ptr++];

Page 98: A Feasibility Study of Loop Bound Analysis for Loops with ...

94 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

11 node . toStringDebug ( bu f f e r , source ) ;12 } else {13 i f ( idx > 1 && source [ nextStar t ] != ’< ’ ) {14 bu f f e r . append ( ’\n ’ ) ;15 for ( int t=0; t<this . depth ; t++) bu f f e r . append ( ’

\ t ’ ) ;16 }17 bu f f e r . append ( source , nextStart , end − nextStar t + 1) ;18 }19 nextStar t = ( int ) this . s epa ra to r s [ idx++];20 }

Listing A.25: ./org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java

1 do {2 i f ( f i e l d S t a r t < methodStart && f i e l d S t a r t < typeStar t ) {3 i f ( f i e l d . getKind ( ) == Abst rac tVar iab l eDec la ra t i on .

ENUMCONSTANT) {4 // f i l t e r out enum constants5 p r ev i ou sF i e l dS ta r t = f i e l d S t a r t ;6 i f (++f i e l d I nd e x < f i e ldCount ) { // f i nd next

f i e l d i f any7 f i e l d S t a r t = ( f i e l d = typeDec la rat ion .

f i e l d s [ f i e l d I nd e x ] ) .d e c l a r a t i onSou r c eS ta r t ;

8 } else {9 f i e l d S t a r t = In t eg e r .MAXVALUE;

10 }11 continue ;12 }13 // next member i s a f i e l d14 i f ( f i e l d S t a r t == prev i ou sF i e l dS ta r t ){15 ASTNode previousMember = members [ index − 1 ] ;16 i f ( previousMember instanceof

Mult iF i e ldDec la ra t i on ) {17 Mul t iF i e ldDec la ra t i on mul t iF i e ld = (

Mul t iF i e ldDec la ra t i on )previousMember ;

18 int l ength = mul t iF i e ld . d e c l a r a t i o n s .l ength ;

19 System . arraycopy ( mul t iF i e ld . d e c l a r a t i on s, 0 , mu l t iF i e ld . d e c l a r a t i o n s=newFi e ldDec l a r a t i on [ l ength +1] , 0 ,l ength ) ;

20 mul t iF i e ld . d e c l a r a t i o n s [ l ength ] = f i e l d ;21 } else {22 F i e l dDec l a ra t i on f i e l dD e c l a r a t i o n = (

F i e ldDec l a r a t i on ) previousMember ;23 f ina l Mult iF i e ldDec la ra t i on

mu l t iF i e l dDec l a ra t i on = newMult iF i e ldDec la ra t i on (newFi e ldDec l a r a t i on [ ] {f i e l dDe c l a r a t i o n , f i e l d }) ;

24 mu l t iF i e l dDec l a ra t i on . annotat ions =f i e l dDe c l a r a t i o n . annotat ions ;

25 members [ index − 1 ] =mul t iF i e l dDec l a ra t i on ;

26 }27 } else {28 members [ index++] = f i e l d ;29 }30 p r ev i ou sF i e l dS ta r t = f i e l d S t a r t ;31 i f (++f i e l d I nd e x < f i e ldCount ) { // f i nd next f i e l d i f

any32 f i e l d S t a r t = ( f i e l d = typeDec la rat ion . f i e l d s [

f i e l d I nd e x ] ) . d e c l a r a t i onSou r c eS ta r t ;33 } else {34 f i e l d S t a r t = In t eg e r .MAXVALUE;35 }36 } else i f ( methodStart < f i e l d S t a r t && methodStart < typeStar t )

{37 // next member i s a method

Page 99: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 95

38 i f ( ! method . i sDe fau l tCons t ruc to r ( ) && ! method . i s C l i n i t ( )) {

39 members [ index++] = method ;40 }41 i f (++methodIndex < methodCount ) { // f i nd next method

i f any42 methodStart = (method = typeDec la rat ion . methods [

methodIndex ] ) . d e c l a r a t i onSou r c eS ta r t ;43 } else {44 methodStart = In t eg e r .MAXVALUE;45 }46 } else {47 // next member i s a type48 members [ index++] = type ;49 i f (++typeIndex < typeCount ) { // f i nd next type i f any50 typeStar t = ( type = typeDec la rat ion . memberTypes [

typeIndex ] ) . d e c l a r a t i onSou r c eS ta r t ;51 } else {52 typeStar t = In t eg e r .MAXVALUE;53 }54 }55 } while ( ( f i e l d I nd e x < f i e ldCount ) | | ( typeIndex < typeCount ) | | (

methodIndex < methodCount ) ) ;

Listing A.26: ./org/eclipse/jdt/internal/ui/text/spelling/PropertiesFile-SpellCheckIterator.java

1 //Def ined in the s up e r c l a s s Spe l lCheck I t e r a to r :2 protected f ina l St r ing fContent ;3 protected St r ing nextToken ( ) {45 St r ing token= null ;67 fPrev ious= fPrede c e s s o r ;8 f S ta r t sS en t enc e= fa l se ;9

10 nextBreak ( ) ;1112 boolean update= fa l se ;13 i f ( fNext − fPrev ious > 0) {1415 i f ( f Suc c e s s o r != Break I t e ra to r .DONE && fContent . charAt (

fPrev ious ) == IJavaDocTagConstants .JAVADOC TAG PREFIX) {

1617 nextBreak ( ) ;18 i f ( Character . i s L e t t e r ( fContent . charAt ( fPrev ious

+ 1) ) ) {19 update= true ;20 token= fContent . sub s t r i ng ( fPrev ious ,

fNext ) ;21 } else22 fPr edec e s s o r= fNext ;2324 } else i f ( f Suc c e s s o r != Break I t e ra to r .DONE && fContent .

charAt ( fPrev ious ) == IHtmlTagConstants .HTML TAG PREFIX && ( Character . i s L e t t e r ( fContent .charAt ( fNext ) ) | | fContent . charAt ( fNext ) == ’ / ’ ) ) {

2526 i f ( fContent . s tartsWith ( IHtmlTagConstants .

HTML CLOSE PREFIX, fPrev ious ) )27 nextBreak ( ) ;2829 nextBreak ( ) ;3031 i f ( f Suc c e s s o r != Break I t e ra to r .DONE && fContent

. charAt ( fNext ) == IHtmlTagConstants .HTML TAG POSTFIX) {

3233 nextBreak ( ) ;34 i f ( f Suc c e s s o r != Break I t e ra to r .DONE) {35 update= true ;

Page 100: A Feasibility Study of Loop Bound Analysis for Loops with ...

96 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

36 token= fContent . sub s t r i ng (fPrev ious , fNext ) ;

37 }38 }39 } else i f ( f Suc c e s s o r != Break I t e ra to r .DONE && fContent .

charAt ( fPrev ious ) == IHtmlTagConstants .HTML ENTITY START && ( Character . i s L e t t e r ( fContent .charAt ( fNext ) ) ) ) {

40 nextBreak ( ) ;41 i f ( f Suc c e s s o r != Break I t e ra to r .DONE && fContent

. charAt ( fNext ) == IHtmlTagConstants .HTML ENTITY END) {

42 nextBreak ( ) ;43 i f ( isToken ( fContent . sub s t r i ng ( fPrev ious

, fNext ) , IHtmlTagConstants .HTML ENTITY CODES) ) {

44 skipTokens ( fPrev ious ,IHtmlTagConstants .HTML ENTITY END) ;

45 update= true ;46 } else47 token= fContent . sub s t r i ng (

fPrev ious , fNext ) ;48 } else49 token= fContent . sub s t r i ng ( fPrev ious ,

fNext ) ;5051 update= true ;52 } else i f ( ! i sWhitespace ( fPrev ious , fNext ) &&

isAlphaNumeric ( fPrev ious , fNext ) ) {5354 i f ( isUrlToken ( fPrev ious ) )55 skipTokens ( fPrev ious , WHITE SPACE TOKEN)

;56 else i f ( isToken ( IJavaDocTagConstants .

JAVADOCPARAMTAGS) )57 fLastToken= null ;58 else i f ( isToken ( IJavaDocTagConstants .

JAVADOC REFERENCE TAGS) ) {59 fLastToken= null ;60 skipTokens ( fPrev ious , fDe l im i t e r . charAt

(0) ) ;61 } else i f ( fNext − fPrev ious > 1 | |

i s S i n g l e L e t t e r ( fPrev ious ) && !f I s I g n o r i n g S i n g l e L e t t e r s )

62 token= fContent . sub s t r i ng ( fPrev ious ,fNext ) ;

6364 update= true ;65 }66 }6768 i f ( update && fSentenceBreaks . s i z e ( ) > 0) {6970 i f ( fPrev ious >= nextSentence ( ) ) {7172 while ( fSentenceBreaks . s i z e ( ) > 0 && fPrev ious

>= nextSentence ( ) )73 fSentenceBreaks . removeFirst ( ) ;7475 fS ta r t sSen t enc e= ( fLastToken == null ) | | ( token

!= null ) ;76 }77 }78 return token ;79 }8081 while ( f Suc c e s s o r != Break I t e ra to r .DONE && ( token == null | | fContent .

charAt ( fNext ) == ’&’ ) ) {82 i f ( token != null ) {83 i f ( prev ious == −1)84 prev ious= fPrev ious ;85 St r ing nextToken= nextToken ( ) ;86 i f ( nextToken != null )

Page 101: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 97

87 token= token + nextToken . sub s t r i ng (1) ;88 else89 token= token + ’&’ ;90 } else91 token= nextToken ( ) ;92 }

Listing A.27: ./org/eclipse/jdt/internal/ui/text/javadoc/-JavaDoc2HTMLTextReader.java

1 //As de f ined in sup e r c l a s s Subst i tut ionTextReader :2 protected int nextChar ( ) throws IOException {3 this . fReadFromBuffer= ( this . fBu f f e r . l ength ( ) > 0) ;4 i f ( this . fReadFromBuffer ) {5 char ch= this . fBu f f e r . charAt ( this . f Index++) ;6 i f ( this . f Index >= this . fBu f f e r . l ength ( ) ) {7 this . fBu f f e r . setLength (0) ;8 this . f Index= 0 ;9 }

10 return ch ;11 } else {12 int ch= this . fCharAfterWhiteSpace ;13 i f ( ch == −1) {14 ch= this . fReader . read ( ) ;15 }16 i f ( this . fSkipWhiteSpace && ScannerHelper . i sWhitespace ( (

char ) ch ) ) {17 do {18 ch= this . fReader . read ( ) ;19 } while ( ScannerHelper . i sWhitespace ( ( char ) ch ) ) ;20 i f ( ch != −1) {21 this . fCharAfterWhiteSpace= ch ;22 return ’ ’ ;23 }24 } else {25 this . fCharAfterWhiteSpace= −1;26 }27 return ch ;28 }29 }3031 while ( c == ’ . ’ | | c != −1 && Character . i s L e t t e r ( ( char ) c ) ) {32 bu f f e r . append ( ( char ) c ) ;33 c= nextChar ( ) ;34 }

Listing A.28: ./org/eclipse/jdt/internal/ui/text/java/hover/JavaSource-Hover.java

1 //Def ined in the s up e r c l a s s JavaCodeReader2 public stat ic f ina l int EOF= −1;3 public int read ( ) throws IOException {4 try {5 return fForward ? readForwards ( ) : readBackwards ( ) ;6 } catch ( BadLocationException x ) {7 throw new IOException (x . getMessage ( ) ) ;8 }9 }

10 private int readForwards ( ) throws BadLocationException {11 while ( fO f f s e t < fEnd ) {12 char cur rent= fDocument . getChar ( fO f f s e t++) ;1314 switch ( cur rent ) {15 case ’ / ’ :16 i f ( fSkipComments && fO f f s e t < fEnd ) {17 char next= fDocument . getChar (

fO f f s e t ) ;18 i f ( next == ’∗ ’ ) {

Page 102: A Feasibility Study of Loop Bound Analysis for Loops with ...

98 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

19 // a comment s t a r t s ,advance to thecomment end

20 ++ fO f f s e t ;21 gotoCommentEnd ( ) ;22 continue ;23 } else i f ( next == ’ / ’ ) {24 // ’// ’−comment s t a r t s ,

advance to the l i n eend

25 gotoLineEnd ( ) ;26 continue ;27 }28 }29 return cur rent ;3031 case ’ ” ’ :32 case ’ \ ’ ’ :33 i f ( f Sk i pS t r i n g s ) {34 gotoStringEnd ( cur rent ) ;35 continue ;36 }37 return cur rent ;38 }39 return cur rent ;40 }41 return EOF;42 }43 private int readBackwards ( ) throws BadLocationException {44 while (0 < fO f f s e t ) {45 −− fO f f s e t ;4647 handleSingleLineComment ( ) ;4849 char cur rent= fDocument . getChar ( fO f f s e t ) ;50 switch ( cur rent ) {51 case ’ / ’ :52 i f ( fSkipComments && fO f f s e t > 1) {53 char next= fDocument . getChar (

fO f f s e t − 1) ;54 i f ( next == ’∗ ’ ) {55 // a comment ends ,

advance to thecomment s t a r t

56 fO f f s e t −= 2 ;57 gotoCommentStart ( ) ;58 continue ;59 }60 }61 return cur rent ;6263 case ’ ” ’ :64 case ’ \ ’ ’ :6566 i f ( f Sk i pS t r i n g s ) {67 −− fO f f s e t ;68 go toS t r i ngS ta r t ( cur rent ) ;69 continue ;70 }7172 return cur rent ;73 }74 return cur rent ;75 }76 return EOF;77 }78 }7980 while ( c != −1 && ( c == ’\ r ’ | | c == ’\n ’ ) ) {81 c= reader . read ( ) ;82 }

Page 103: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 99

Listing A.29: ./org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java

1 while ( l o c == Qual i f iedType .NAMEPROPERTY | | l o c == Qualif iedName .NAMEPROPERTY | | l o c == SimpleType .NAMEPROPERTY | | l o c ==ParameterizedType .TYPE PROPERTY) {

2 node= node . getParent ( ) ;3 l o c= node . getLocat ionInParent ( ) ;4 }

Listing A.30: ./org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrat-egy.java

1 while ( node != null && ( r e l a t i v eO f f s e t == node . g e tS t a r tPo s i t i on ( ) | |r e l a t i v eO f f s e t == node . g e tS t a r tPo s i t i on ( ) + node . getLength ( ) ) )

2 node= node . getParent ( ) ;

Listing A.31: ./org/eclipse/jdt/internal/ui/infoviews/SourceView.java

1 //Def ined in the s up e r c l a s s JavaCodeReader2 public stat ic f ina l int EOF= −1;3 public int read ( ) throws IOException {4 try {5 return fForward ? readForwards ( ) : readBackwards ( ) ;6 } catch ( BadLocationException x ) {7 throw new IOException (x . getMessage ( ) ) ;8 }9 }

10 private int readForwards ( ) throws BadLocationException {11 while ( fO f f s e t < fEnd ) {12 char cur rent= fDocument . getChar ( fO f f s e t++) ;1314 switch ( cur rent ) {15 case ’ / ’ :16 i f ( fSkipComments && fO f f s e t < fEnd ) {17 char next= fDocument . getChar (

fO f f s e t ) ;18 i f ( next == ’∗ ’ ) {19 // a comment s t a r t s ,

advance to thecomment end

20 ++ fO f f s e t ;21 gotoCommentEnd ( ) ;22 continue ;23 } else i f ( next == ’ / ’ ) {24 // ’// ’−comment s t a r t s ,

advance to the l i n eend

25 gotoLineEnd ( ) ;26 continue ;27 }28 }29 return cur rent ;3031 case ’ ” ’ :32 case ’ \ ’ ’ :33 i f ( f Sk i pS t r i n g s ) {34 gotoStringEnd ( cur rent ) ;35 continue ;36 }37 return cur rent ;38 }39 return cur rent ;40 }41 return EOF;42 }43 private int readBackwards ( ) throws BadLocationException {44 while (0 < fO f f s e t ) {45 −− fO f f s e t ;46

Page 104: A Feasibility Study of Loop Bound Analysis for Loops with ...

100 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

47 handleSingleLineComment ( ) ;4849 char cur rent= fDocument . getChar ( fO f f s e t ) ;50 switch ( cur rent ) {51 case ’ / ’ :52 i f ( fSkipComments && fO f f s e t > 1) {53 char next= fDocument . getChar (

fO f f s e t − 1) ;54 i f ( next == ’∗ ’ ) {55 // a comment ends ,

advance to thecomment s t a r t

56 fO f f s e t −= 2 ;57 gotoCommentStart ( ) ;58 continue ;59 }60 }61 return cur rent ;6263 case ’ ” ’ :64 case ’ \ ’ ’ :6566 i f ( f Sk i pS t r i n g s ) {67 −− fO f f s e t ;68 go toS t r i ngS ta r t ( cur rent ) ;69 continue ;70 }7172 return cur rent ;73 }74 return cur rent ;75 }76 return EOF;77 }78 }7980 while ( c != −1 && ( c == ’\ r ’ | | c == ’\n ’ | | c == ’\ t ’ ) ) {81 c= reader . read ( ) ;82 }

Listing A.32: ./org/eclipse/jdt/internal/compiler/lookup/BlockScope.java

1 while ( hasMoreVariables | | hasMoreScopes ) {2 i f ( hasMoreScopes3 && ( ! hasMoreVariables | | ( this . subscopes [ i s c ope ] .

s t a r t Index ( ) <= i l o c a l ) ) ) {4 // cons id e r subscope f i r s t5 i f ( this . subscopes [ i s c ope ] instanceof BlockScope ) {6 BlockScope subscope = ( BlockScope ) this .

subscopes [ i s c ope ] ;7 int subOf f s e t = subscope . s h i f t S c op e s == null ?

this . o f f s e t : subscope . maxShi f tedOf f set ( ) ;8 subscope . computeLoca lVar iab lePos i t ions (0 ,

subOffset , codeStream ) ;9 i f ( subscope . maxOffset > this . maxOffset )

10 this . maxOffset = subscope . maxOffset ;11 }12 hasMoreScopes = ++i s cope < maxScopes ;13 } else {1415 // cons id e r va r i ab l e f i r s t16 Loca lVar iab leBinding l o c a l = this . l o c a l s [ i l o c a l ] ; // i f

no l o c a l at a l l , w i l l be l o c a l s [ i l o c a l ]==nu l l1718 // check i f v a r i ab l e i s a c t ua l l y used , and may f o r c e i t

to be prese rved19 boolean generateCurrentLocalVar = ( l o c a l . useFlag >

Loca lVar iab leBinding .UNUSED && l o c a l . constant ( ) ==Constant . NotAConstant ) ;

2021 // do not r epor t fake used va r i ab l e22 i f ( l o c a l . useFlag == Loca lVar iab leBinding .UNUSED

Page 105: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 101

23 && ( l o c a l . d e c l a r a t i on != null ) // unused ( andnon s e c r e t ) l o c a l

24 && (( l o c a l . d e c l a r a t i on . b i t s & ASTNode .I sLoca lDec la ra t ionReachab l e ) != 0) ) { //de c l a r a t i on i s r eachab le

2526 i f ( ! ( l o c a l . d e c l a r a t i on instanceof Argument ) ) //

do not r epor t unused catch arguments27 problemReporter ( ) . unusedLocalVar iable (

l o c a l . d e c l a r a t i on ) ;28 }2930 // could be opt imized out , but does need to pre s e rve

unread va r i a b l e s ?31 i f ( ! generateCurrentLocalVar ) {32 i f ( l o c a l . d e c l a r a t i on != null && compi lerOptions

( ) . p r e s e rv eA l lLoca lVa r i ab l e s ) {33 generateCurrentLocalVar = true ; // f o r c e

i t to be prese rved in thegenerated code

34 i f ( l o c a l . useFlag ==Loca lVar iab leBinding .UNUSED)

35 l o c a l . useFlag =Loca lVar iab leBinding .USED;

36 }37 }3839 // a l l o c a t e va r i ab l e40 i f ( generateCurrentLocalVar ) {4142 i f ( l o c a l . d e c l a r a t i on != null ) {43 codeStream . record ( l o c a l ) ; // record user

−de f ined l o c a l v a r i a b l e s f o ra t t r i bu t e genera t i on

44 }45 // a s s i gn va r i ab l e p o s i t i o n46 l o c a l . r e s o l v edPo s i t i on = this . o f f s e t ;4748 i f ( ( l o c a l . type == TypeBinding .LONG) | | ( l o c a l .

type == TypeBinding .DOUBLE) ) {49 this . o f f s e t += 2 ;50 } else {51 this . o f f s e t++;52 }53 i f ( this . o f f s e t > 0xFFFF) { // no more than

65535 words o f l o c a l s54 problemReporter ( ) .

noMoreAvailableSpaceForLocal (55 l o ca l ,56 l o c a l . d e c l a r a t i on == null ? (

ASTNode)methodScope ( ) .r e f e r enceContext : l o c a l .d e c l a r a t i on ) ;

57 }58 } else {59 l o c a l . r e s o l v edPo s i t i on = −1; // not generated60 }61 hasMoreVariables = ++i l o c a l < maxLocals ;62 }63 }

Listing A.33: ./org/eclipse/jdt/internal/compiler/lookup/BlockScope.java

1 while ( hasMoreVariables | | hasMoreScopes ) {2 i f ( hasMoreScopes3 && ( ! hasMoreVariables | | ( this . subscopes [ i s c ope ] .

s t a r t Index ( ) <= i l o c a l ) ) ) {4 // cons ide r subscope f i r s t5 Scope subscope = this . subscopes [ i s c ope ] ;6 i f ( subscope . kind == Scope .BLOCK SCOPE) { // do not dive

in nested types

Page 106: A Feasibility Study of Loop Bound Analysis for Loops with ...

102 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

7 l o c a lDe c l a r a t i o n s = ( ( BlockScope ) subscope ) .f i ndLoca lVa r i ab l eDec l a r a t i on s ( p o s i t i o n ) ;

8 i f ( l o c a lD e c l a r a t i o n s != null ) {9 return l o c a lD e c l a r a t i o n s ;

10 }11 }12 hasMoreScopes = ++i s cope < maxScopes ;13 } else {14 // cons id e r va r i ab l e f i r s t15 Loca lVar iab leBinding l o c a l = this . l o c a l s [ i l o c a l ] ; // i f

no l o c a l at a l l , w i l l be l o c a l s [ i l o c a l ]==nu l l16 i f ( l o c a l != null ) {17 Loca lDec la ra t i on l o c a lDe c l = l o c a l . d e c l a r a t i on ;18 i f ( l o c a lDe c l != null ) {19 i f ( l o c a lDe c l . d e c l a r a t i onSou r c eS ta r t <=

po s i t i o n ) {20 i f ( p o s i t i o n <= lo ca lDe c l .

dec larat ionSourceEnd ) {21 i f ( l o c a lD e c l a r a t i o n s ==

null ) {22 l o c a lD e c l a r a t i o n s

= newLoca lDec la ra t i on[ maxLocals] ;

23 }24 l o c a lDe c l a r a t i o n s [

dec lPtr++] =l o c a lDe c l ;

25 }26 } else {27 return l o c a lD e c l a r a t i o n s ;28 }29 }30 }31 hasMoreVariables = ++i l o c a l < maxLocals ;32 i f ( ! hasMoreVariables && l o c a lDe c l a r a t i o n s != null ) {33 return l o c a lD e c l a r a t i o n s ;34 }35 }36 }

Listing A.34: ./org/eclipse/jdt/internal/compiler/apt/util/Util.java

1 while ( ( c = unitSource [ begin ] ) == ’ ’ | | c == ’\ t ’ ) begin++;

Listing A.35: ./org/eclipse/jdt/internal/compiler/apt/dispatch/RoundDis-patcher.java

1 while ( s ea rchForStar | | ! uncla imedAnnotat ions . isEmpty ( ) ) {2 Proce s s o r In f o p i = prov id e r . d i s coverNextProces so r ( ) ;3 i f ( null == pi ) {4 // There are no more p r o c e s s o r s to be d i s cove r ed .5 break ;6 }7 handleProcessor ( p i ) ;8 }

Listing A.36: ./org/eclipse/jdt/internal/compiler/tool/Util.java

1 while ( ( c = unitSource [ begin ] ) == ’ ’ | | c == ’\ t ’ ) begin++;

Listing A.37: ./org/eclipse/jdt/internal/compiler/ast/JavadocAllocationEx-pression.java

Page 107: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 103

1 while ( ! contructorBind ing . i sVa l idBind ing ( ) && ( enclos ingTypeBinding .isMemberType ( ) | | enclos ingTypeBinding . i sLocalType ( ) ) ) {

2 enclos ingTypeBinding = enclos ingTypeBinding . enc los ingType ( ) ;3 contructorBind ing = scope . getConstructor ( enclos ingTypeBinding ,

argumentTypes , this ) ;4 }

Listing A.38: ./org/eclipse/jdt/internal/compiler/ast/JavadocMessage-Send.java

1 while ( ! methodBinding . i sVa l idB ind ing ( ) && ( enclos ingTypeBinding .isMemberType ( ) | | enclos ingTypeBinding . i sLocalType ( ) ) ) {

2 enclos ingTypeBinding = enclos ingTypeBinding . enc los ingType ( ) ;3 methodBinding = scope . getMethod ( enclos ingTypeBinding , this .

s e l e c t o r , argumentTypes , this ) ;4 }

Listing A.39: ./org/eclipse/jdt/internal/compiler/ast/JavadocMessage-Send.java

1 while ( ! contructorBind ing . i sVa l idBind ing ( ) && ( enclos ingTypeBinding .isMemberType ( ) | | enclos ingTypeBinding . i sLocalType ( ) ) ) {

2 enclos ingTypeBinding = enclos ingTypeBinding . enc los ingType ( ) ;3 i f ( CharOperation . equa l s ( this . s e l e c t o r , enc los ingTypeBinding .

shortReadableName ( ) ) ) {4 contructorBind ing = scope . getConstructor ( (

ReferenceBinding ) enclos ingTypeBinding ,argumentTypes , this ) ;

5 }6 }

Listing A.40: ./org/eclipse/jdt/internal/compiler/Compiler.java

1 do {2 // ex t ra c t un i t s to proce s s3 int l ength = top − bottom ;4 Compi lat ionUnitDec larat ion [ ] cur rentUni t s = new

Compi lat ionUnitDec larat ion [ l ength ] ;5 int index = 0 ;6 for ( int i = bottom ; i < top ; i++) {7 Compi lat ionUnitDec larat ion currentUnit = this .

un i tsToProcess [ i ] ;8 i f ( ( currentUnit . b i t s & ASTNode . I s Imp l i c i tUn i t ) == 0) {9 cur rentUni t s [ index++] = currentUnit ;

10 }11 }12 i f ( index != length ) {13 System . arraycopy ( currentUnits , 0 , ( cur rentUni t s = new

Compi lat ionUnitDec larat ion [ index ] ) , 0 , index ) ;14 }15 this . annotat ionProcessorManager . processAnnotat ions ( currentUnits ,

binaryTypeBindingsTemp , fa l se ) ;16 ICompi lat ionUnit [ ] newUnits = this . annotat ionProcessorManager .

getNewUnits ( ) ;17 newUnitSize = newUnits . l ength ;18 ReferenceBinding [ ] newClassF i l e s = this .

annotat ionProcessorManager . getNewClassFi les ( ) ;19 binaryTypeBindingsTemp = newClassF i l e s ;20 newCla s sF i l e sS i z e = newClassF i l e s . l ength ;21 i f ( newUnitSize != 0) {22 ICompilat ionUnit [ ] newProcessedUnits = ( ICompilat ionUnit

[ ] ) newUnits . c l one ( ) ; // remember new un i t s in casea source type c o l l i s i o n occurs

23 try {24 this . lookupEnvironment . i sProce s s ingAnnota t i ons =

true ;25 internalBeginToCompile ( newUnits , newUnitSize ) ;

Page 108: A Feasibility Study of Loop Bound Analysis for Loops with ...

104 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

26 } catch ( SourceTypeCol l i s ionExcept ion e ) {27 e . newAnnotationProcessorUnits =

newProcessedUnits ;28 throw e ;29 } f ina l ly {30 this . lookupEnvironment . i sProce s s ingAnnota t i ons =

fa l se ;31 this . annotat ionProcessorManager . r e s e t ( ) ;32 }33 bottom = top ;34 top = this . t o t a lUn i t s ; // l a s t un i t added35 } else {36 bottom = top ;37 this . annotat ionProcessorManager . r e s e t ( ) ;38 }39 } while ( newUnitSize != 0 | | newClas sF i l e sS i z e != 0) ;

Listing A.41: ./org/eclipse/jdt/internal/compiler/parser/Scanner.java

1 while ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) {2 i f ( this . c u r r en tPo s i t i on >= this . e o fPo s i t i o n ) {3 throw new Inva l id InputExcept ion (UNTERMINATEDCOMMENT) ;4 }5 i f ( ( this . cur rentCharacter == ’\ r ’ ) | | ( this . cur rentCharacter ==

’\n ’ ) ) {6 i f ( this . r e cordL ineSeparator ) {7 i f ( i sUnicode ) {8 pushUnicodeLineSeparator ( ) ;9 } else {

10 pushLineSeparator ( ) ;11 }12 }13 }14 switch ( this . cur rentCharacter ) {15 case ’∗ ’ :16 s t a r = true ;17 break ;18 case ’@ ’ :19 i f ( f i r s tTag == 0 && this . i sF i r s tTag ( ) ) {20 f i r s tTag = prev ious ;21 }22 //$FALL−THROUGH$ de f au l t case to s e t s t a r to

f a l s e23 default :24 s t a r = fa l se ;25 }26 // get next char27 prev ious = this . c u r r en tPo s i t i on ;28 i f ( ( ( this . cur rentCharacter = this . source [ this . c u r r en tPo s i t i on

++]) == ’ \\ ’ )29 && ( this . source [ this . c u r r en tPo s i t i on ] == ’u ’ ) ) {30 //−−−−−−−−−−−−−unicode t ra i t ement −−−−−−−−−−−−31 getNextUnicodeChar ( ) ;32 i sUnicode = true ;33 } else {34 i sUnicode = fa l se ;35 }36 // handle the \\u case manually in to comment37 i f ( this . cur rentCharacter == ’ \\ ’ ) {38 i f ( this . source [ this . c u r r en tPo s i t i on ] == ’ \\ ’ )39 this . c u r r en tPo s i t i on++;40 } //jump over the \\41 }

Listing A.42: ./org/eclipse/jdt/internal/compiler/parser/Scanner.java

1 while ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) {2 i f ( this . c u r r en tPo s i t i on >= this . e o fPo s i t i o n ) {3 return ;4 }

Page 109: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 105

5 i f ( ( this . cur rentCharacter == ’\ r ’ ) | | ( this . cur rentCharacter ==’\n ’ ) ) {

6 i f ( this . r e cordL ineSeparator ) {7 i f ( i sUnicode ) {8 pushUnicodeLineSeparator ( ) ;9 } else {

10 pushLineSeparator ( ) ;11 }12 }13 }14 switch ( this . cur rentCharacter ) {15 case ’∗ ’ :16 s t a r = true ;17 break ;18 case ’@ ’ :19 i f ( f i r s tTag == 0 && this . i sF i r s tTag ( ) ) {20 f i r s tTag = prev ious ;21 }22 //$FALL−THROUGH$ de f au l t case to s e t s t a r to

f a l s e23 default :24 s t a r = fa l se ;25 }26 // get next char27 prev ious = this . c u r r en tPo s i t i on ;28 i f ( ( ( this . cur rentCharacter = this . source [ this . c u r r en tPo s i t i on

++]) == ’ \\ ’ )29 && ( this . source [ this . c u r r en tPo s i t i on ] == ’u ’ ) ) {30 getNextUnicodeChar ( ) ;31 i sUnicode = true ;32 } else {33 i sUnicode = fa l se ;34 }35 // handle the \\u case manually in to comment36 i f ( this . cur rentCharacter == ’ \\ ’ ) {37 i f ( this . source [ this . c u r r en tPo s i t i on ] == ’ \\ ’ )38 this . c u r r en tPo s i t i on++;39 } //jump over the \\40 }

Listing A.43: ./org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseP-arser.java

1 while ( act > ERROR ACTION | | act < ACCEPT ACTION) { // SHIFT−REDUCEact i on or SHIFT act i on ?

2 this . nextStackTop = this . tempStackTop + 1 ;3 for ( int i = next pos + 1 ; i <= this . nextStackTop ; i++)4 this . nextStack [ i ] = this . tempStack [ i ] ;56 for ( int i = pos + 1 ; i <= this . nextStackTop ; i++) {7 this . l o ca t i onS tack [ i ] = this . l o ca t i onS tack [ this .

stateStackTop ] ;8 this . l o c a t i onS ta r tS t a ck [ i ] = this . l o c a t i onS ta r tS t a ck [

this . stateStackTop ] ;9 }

1011 //12 // I f we have a s h i f t−reduce , p roce s s i t as we l l as13 // the goto−reduce a c t i on s that f o l l ow i t .14 //15 i f ( act > ERROR ACTION) {16 act −= ERROR ACTION;17 do {18 this . nextStackTop −= ( Parser . rhs [ act ]−1) ;19 act = Parser . ntAction ( this . nextStack [ this .

nextStackTop ] , Parser . l h s [ act ] ) ;20 } while ( act <= NUM RULES) ;21 pos = pos < this . nextStackTop ? pos : this . nextStackTop ;22 }2324 i f ( this . nextStackTop + 1 >= this . stackLength )25 r e a l l o c a t e S t a c k s ( ) ;

Page 110: A Feasibility Study of Loop Bound Analysis for Loops with ...

106 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

2627 this . tempStackTop = this . nextStackTop ;28 this . nextStack[++this . nextStackTop ] = act ;29 next pos = this . nextStackTop ;3031 //32 // Simulate the par s e r through the next token without33 // de s t roy ing STACK or next s tack .34 //35 this . currentToken = this . lexStream . getToken ( ) ;36 tok = this . lexStream . kind ( this . currentToken ) ;37 act = Parser . tAct ion ( act , tok ) ;38 while ( act <= NUM RULES) {39 //40 // . . . Process a l l goto−reduce a c t i on s f o l l ow ing41 // reduct ion , u n t i l a goto ac t i on i s computed . . .42 //43 do {44 int lhs symbol = Parser . l h s [ act ] ;45 i f (DEBUG) {46 System . out . p r i n t l n ( Parser . name [ Parser .

non te rmina l index [ lhs symbol ] ] ) ;47 }48 this . tempStackTop −= ( Parser . rhs [ act ]−1) ;49 act = ( this . tempStackTop > next pos50 ? this . tempStack [ this .

tempStackTop ]51 : this . nextStack [ this .

tempStackTop ] ) ;52 act = Parser . ntAction ( act , lhs symbol ) ;53 } while ( act <= NUM RULES) ;5455 //56 // . . . Update the maximum us e f u l p o s i t i o n o f the57 // (STATE )STACK, push GOTO s ta t e in to stack , and58 // compute next ac t i on on cur rent symbol . . .59 //60 i f ( this . tempStackTop + 1 >= this . stackLength )61 r e a l l o c a t e S t a c k s ( ) ;6263 next pos = next pos < this . tempStackTop ? next pos :

this . tempStackTop ;64 this . tempStack [ this . tempStackTop + 1 ] = act ;65 act = Parser . tAct ion ( act , tok ) ;66 }6768 // i f ( ( tok != TokenNameRBRACE | | (

forceRecoveryToken != currentToken && ( lexStream . f l a g s ( currentToken) & LexStream .LBRACE MISSING) != 0) )

69 // && ( lexStream . f l a g s ( currentToken) & LexStream . IS AFTER JUMP) !=0) {

70 // act = ERROR ACTION;71 // i f ( forceRecoveryToken !=

currentToken72 // && ( lexStream . f l a g s (

currentToken ) & LexStream .LBRACE MISSING) != 0) {73 //

forceRecoveryAfterLBracketMiss ing = true ;74 // forceRecoveryToken =

currentToken ;75 // }76 // }7778 //79 // No e r r o r was detected , Read next token in to80 // PREVTOK element , advance CURTOK po in t e r and81 // update s tack s .82 //83 i f ( act != ERROR ACTION) {84 this . prevStackTop = this . stateStackTop ;85 for ( int i = prev pos + 1 ; i <= this . prevStackTop ; i++)86 this . prevStack [ i ] = this . s tack [ i ] ;87 prev pos = pos ;88

Page 111: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 107

89 this . stateStackTop = this . nextStackTop ;90 for ( int i = pos + 1 ; i <= this . stateStackTop ; i++)91 this . s tack [ i ] = this . nextStack [ i ] ;92 this . l o ca t i onS tack [ this . stateStackTop ] = this .

currentToken ;93 this . l o c a t i onS ta r tS t a ck [ this . stateStackTop ] = this .

lexStream . s t a r t ( this . currentToken ) ;94 pos = next pos ;95 }96 }

Listing A.44: ./org/eclipse/jdt/internal/compiler/ReadManager.java

1 while ( r e s u l t == this . readInProcessMarker | | r e s u l t == null ) {2 // l e t the readingThread know we ’ re wai t ing3 //System . out . p r i n t ( ’ | ’ ) ;4 this . contentsRead [ this . readyToReadPosition ] = null ;5 try {6 wait (250) ;7 } catch ( Inter ruptedExcept ion ignore ) { // ignore8 }9 i f ( this . caughtException != null ) {

10 // rethrow the caught except ion from the readingThreadsin the main compi ler thread

11 i f ( this . caughtException instanceof Error )12 throw ( Error ) this . caughtException ;13 throw ( RuntimeException ) this . caughtException ;14 }15 r e s u l t = this . contentsRead [ this . readyToReadPosition ] ;16 }

Listing A.45: ./org/eclipse/jdt/internal/compiler/codegen/LongCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) &&(this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return true ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Listing A.46: ./org/eclipse/jdt/internal/compiler/codegen/LongCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) && (this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return this . valueTable [ index ] = value ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Listing A.47: ./org/eclipse/jdt/internal/compiler/codegen/LongCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) && (this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return this . valueTable [ index ] ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Page 112: A Feasibility Study of Loop Bound Analysis for Loops with ...

108 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

Listing A.48: ./org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) &&(this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return true ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Listing A.49: ./org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) && (this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return this . valueTable [ index ] = value ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Listing A.50: ./org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java

1 while ( ( this . keyTable [ index ] != 0) | | ( ( this . keyTable [ index ] == 0) && (this . valueTable [ index ] != 0) ) ) {

2 i f ( this . keyTable [ index ] == key )3 return this . valueTable [ index ] ;4 i f (++index == length ) {5 index = 0 ;6 }7 }

Listing A.51: ./org/eclipse/jdt/internal/compiler/problem/DefaultProb-lem.java

1 while ( ( c = unitSource [ begin ] ) == ’ ’ | | c == ’\ t ’ ) begin++;

Listing A.52: ./org/eclipse/jdt/internal/compiler/batch/Main.java

1 while ( ( c = unitSource [ begin ] ) == ’ ’ | | c == ’\ t ’ ) begin++;

Listing A.53: ./org/eclipse/jdt/internal/compiler/batch/Main.java

1 while ( ( c = unitSource [ begin ] ) == ’ ’ | | c == ’\ t ’ ) begin++;

Listing A.54: ./org/eclipse/jdt/internal/compiler/batch/Main.java

1 while ( ( c = unitSource [ end ] ) == ’ ’ | | c == ’\ t ’ ) end−−;

Listing A.55: ./org/eclipse/jdt/internal/compiler/classfmt/ClassFil-eReader.java

1 int l ength1 = currentMethodInfos == null ? 0 : currentMethodInfos . l ength;

2 int l ength2 = otherMethodInfos == null ? 0 : otherMethodInfos . l ength ;3 int index1 = 0 ;4 int index2 = 0 ;

Page 113: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 109

5 /∗ outer loop cond i t i on : ∗/ while ( index1 < l ength1 && index2 < l ength2 ){

6 while ( (m = currentMethodInfos [ index1 ] ) . i s S yn th e t i c ( ) | | m. i s C l i n i t ( ) ) {7 i f (++index1 >= length1 ) break end ;8 }

Listing A.56: ./org/eclipse/jdt/internal/compiler/classfmt/ClassFil-eReader.java

1 int l ength1 = currentMethodInfos == null ? 0 : currentMethodInfos . l ength;

2 int l ength2 = otherMethodInfos == null ? 0 : otherMethodInfos . l ength ;3 int index1 = 0 ;4 int index2 = 0 ;5 /∗ outer loop cond i t i on : ∗/ while ( index1 < l ength1 && index2 < l ength2 )

{6 while ( (m = otherMethodInfos [ index2 ] ) . i s S yn th e t i c ( ) | | m. i s C l i n i t ( ) ) {7 i f (++index2 >= length2 ) break end ;8 }

Listing A.57: ./org/eclipse/jdt/internal/codeassist/complete/CompletionScan-ner.java

1 while ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) {2 i f ( ( this . cur rentCharacter == ’\ r ’ ) | | ( this . cur rentCharacter ==

’\n ’ ) ) {3 // checkNonExterna l i zedStr ing ( ) ;4 i f ( this . r e cordL ineSeparator ) {5 i f ( ! i sUnicode ) {6 pushLineSeparator ( ) ;7 }8 }9 }

10 switch ( this . cur rentCharacter ) {11 case ’∗ ’ :12 s t a r = true ;13 break ;14 case ’@ ’ :15 i f ( f i r s tTag == 0 && this . i sF i r s tTag ( ) ) {16 f i r s tTag = prev ious ;17 }18 //$FALL−THROUGH$ de f au l t case to s e t s t a r to

f a l s e19 default :20 s t a r = fa l se ;21 }22 // get next char23 prev ious = this . c u r r en tPo s i t i on ;24 i f ( ( ( this . cur rentCharacter = this . source [ this . c u r r en tPo s i t i on

++]) == ’ \\ ’ )25 && ( this . source [ this . c u r r en tPo s i t i on ] == ’u ’ ) ) {26 //−−−−−−−−−−−−−unicode t ra i t ement −−−−−−−−−−−−27 getNextUnicodeChar ( ) ;28 i sUnicode = true ;29 } else {30 i sUnicode = fa l se ;31 }32 // handle the \\u case manually in to comment33 i f ( this . cur rentCharacter == ’ \\ ’ ) {34 i f ( this . source [ this . c u r r en tPo s i t i on ] == ’ \\ ’ )35 this . c u r r en tPo s i t i on++;36 } //jump over the \\37 }

Listing A.58: ./org/eclipse/jdt/internal/core/jdom/DOMField.java

1 while ( f i e l d . i sVa r i ab l eDec l a r a t o r ( ) | | f i e l d .ha sMul t ip l eVar i ab l eDec l a ra to r s ( ) ) {

Page 114: A Feasibility Study of Loop Bound Analysis for Loops with ...

110 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

2 i f ( f i e l d . fNextNode instanceof DOMField && ((DOMField) f i e l d .fNextNode ) . i sVa r i ab l eDec l a r a t o r ( ) ) {

3 f i e l d= (DOMField) f i e l d . fNextNode ;4 } else {5 break ;6 }7 }

Listing A.59: ./org/eclipse/jdt/internal/core/util/BindingKeyParser.java

1 while ( this . index < this . source . l ength && ( this . source [ this . index ] == ’<’ | | this . source [ this . index ] == ’%’ ) )

2 this . index++;

Listing A.60: ./org/eclipse/jdt/internal/core/util/PublicScanner.java

1 while ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) {2 i f ( this . c u r r en tPo s i t i on >= this . e o fPo s i t i o n ) {3 throw new Inva l id InputExcept ion (UNTERMINATEDCOMMENT) ;4 }5 i f ( ( this . cur rentCharacter == ’\ r ’ ) | | ( this . cur rentCharacter ==

’\n ’ ) ) {6 i f ( this . r e cordL ineSeparator ) {7 i f ( i sUnicode ) {8 pushUnicodeLineSeparator ( ) ;9 } else {

10 pushLineSeparator ( ) ;11 }12 }13 }14 switch ( this . cur rentCharacter ) {15 case ’∗ ’ :16 s t a r = true ;17 break ;18 case ’@ ’ :19 i f ( f i r s tTag == 0 && this . i sF i r s tTag ( ) ) {20 f i r s tTag = prev ious ;21 }22 //$FALL−THROUGH$ de f au l t case to s e t s t a r to

f a l s e23 default :24 s t a r = fa l se ;25 }26 // get next char27 prev ious = this . c u r r en tPo s i t i on ;28 i f ( ( ( this . cur rentCharacter = this . source [ this . c u r r en tPo s i t i on

++]) == ’ \\ ’ )29 && ( this . source [ this . c u r r en tPo s i t i on ] == ’u ’ ) ) {30 //−−−−−−−−−−−−−unicode t ra i t ement −−−−−−−−−−−−31 getNextUnicodeChar ( ) ;32 i sUnicode = true ;33 } else {34 i sUnicode = fa l se ;35 }36 // handle the \\u case manually in to comment37 i f ( this . cur rentCharacter == ’ \\ ’ ) {38 i f ( this . source [ this . c u r r en tPo s i t i on ] == ’ \\ ’ )39 this . c u r r en tPo s i t i on++;40 } //jump over the \\41 }

Listing A.61: ./org/eclipse/jdt/internal/core/util/PublicScanner.java

1 while ( ( this . cur rentCharacter != ’ / ’ ) | | ( ! s t a r ) ) {2 i f ( this . c u r r en tPo s i t i on >= this . e o fPo s i t i o n ) {3 return ;4 }

Page 115: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 111

5 i f ( ( this . cur rentCharacter == ’\ r ’ ) | | ( this . cur rentCharacter ==’\n ’ ) ) {

6 i f ( this . r e cordL ineSeparator ) {7 i f ( i sUnicode ) {8 pushUnicodeLineSeparator ( ) ;9 } else {

10 pushLineSeparator ( ) ;11 }12 }13 }14 switch ( this . cur rentCharacter ) {15 case ’∗ ’ :16 s t a r = true ;17 break ;18 case ’@ ’ :19 i f ( f i r s tTag == 0 && this . i sF i r s tTag ( ) ) {20 f i r s tTag = prev ious ;21 }22 //$FALL−THROUGH$ de f au l t case to s e t s t a r to

f a l s e23 default :24 s t a r = fa l se ;25 }26 // get next char27 prev ious = this . c u r r en tPo s i t i on ;28 i f ( ( ( this . cur rentCharacter = this . source [ this . c u r r en tPo s i t i on

++]) == ’ \\ ’ )29 && ( this . source [ this . c u r r en tPo s i t i on ] == ’u ’ ) ) {30 getNextUnicodeChar ( ) ;31 i sUnicode = true ;32 } else {33 i sUnicode = fa l se ;34 }35 // handle the \\u case manually in to comment36 i f ( this . cur rentCharacter == ’ \\ ’ ) {37 i f ( this . source [ this . c u r r en tPo s i t i on ] == ’ \\ ’ )38 this . c u r r en tPo s i t i on++;39 } //jump over the \\40 }

Listing A.62: ./org/eclipse/jdt/internal/core/JavadocContents.java

1 while ( ( index = CharOperation . indexOf ( JavadocConstants .ANCHOR PREFIX START, this . content , false , fromIndex ) ) != −1 && (index < indexOfSectionBottom | | indexOfSectionBottom == −1) ) {

2 fromIndex = index + 1 ;34 int anchorEndStart = index + JavadocConstants .

ANCHOR PREFIX START LENGHT;56 this . tempLastAnchorFoundIndex = anchorEndStart ;78 i f ( CharOperation . p r e f i xEqua l s ( anchor , this . content , false ,

anchorEndStart ) ) {9 return computeChildRange ( anchorEndStart , anchor ,

indexOfSectionBottom ) ;10 } else {11 i f ( this . tempAnchorIndexes . l ength == this .

tempAnchorIndexesCount ) {12 System . arraycopy ( this . tempAnchorIndexes , 0 , this

. tempAnchorIndexes = new int [ this .tempAnchorIndexesCount + 20 ] , 0 , this .tempAnchorIndexesCount ) ;

13 }1415 this . tempAnchorIndexes [ this . tempAnchorIndexesCount++] =

anchorEndStart ;16 }17 }

Listing A.63: ./org/eclipse/jdt/internal/corext/dom/TokenScanner.java

Page 116: A Feasibility Study of Loop Bound Analysis for Loops with ...

112 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

1 private IScanner fScanner ;2 private int readNextWithEOF(boolean ignoreComments ) throws CoreException

{3 int curr= 0 ;4 do {5 try {6 curr= fScanner . getNextToken ( ) ;7 } catch ( Inva l id InputExcept ion e ) {8 throw new CoreException ( c r ea t eEr ro r (

LEXICAL ERROR, e . getMessage ( ) , e ) ) ;9 }

10 } while ( ignoreComments && isComment ( curr ) ) ;11 return curr ;12 }1314 while ( curr == ITerminalSymbols .TokenNameCOMMENT LINE | | curr ==

ITerminalSymbols .TokenNameCOMMENT BLOCK) {15 int cu r rS ta r tL ine= getL ineOfOf f s e t ( g e tCur r en tS ta r tOf f s e t ( ) ) ;16 int l i n e sD i f f e r e n c e= cur rS ta r tL ine − prevEndLine ;1718 i f ( l i n e sD i f f e r e n c e > 1) {19 return prevEndPos ; // separated comments20 }2122 i f ( curr == ITerminalSymbols .TokenNameCOMMENT LINE) {23 prevEndPos= getLineEnd ( cur rS ta r tL ine ) ;24 prevEndLine= cur rS ta r tL ine ;25 } else {26 prevEndPos= getCurrentEndOffset ( ) ;27 prevEndLine= getL ineOfOf f s e t ( prevEndPos − 1) ;28 }29 i f ( sameLineComment ) {30 i f ( l i n e sD i f f e r e n c e == 0) {31 r e s= prevEndPos ;32 } else {33 sameLineComment= fa l se ;34 }35 }36 curr= readNextWithEOF( fa l se ) ;37 }

Listing A.64: ./org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java

1 do {2 ICleanUp cleanUp= cleanUps [ i ] ;3 ICleanUpFix f i x ;4 i f ( slowCleanUps != null ) {5 long t imeBefore= System . cur rentTimeMi l l i s ( ) ;6 f i x= cleanUp . c r ea t eF ix ( context ) ;7 i f ( System . cur rentTimeMi l l i s ( ) − t imeBefore >

SLOW CLEAN UP THRESHOLD)8 slowCleanUps . add ( cleanUp ) ;9 } else {

10 f i x= cleanUp . c r ea t eF ix ( context ) ;11 }12 i f ( f i x != null ) {13 CompilationUnitChange cur rent= f i x . createChange ( null ) ;14 TextEdit cur rentEd i t= current . getEdit ( ) ;1516 i f ( s o l u t i o n != null ) {17 i f ( TextEditUt i l . ove r l ap s ( currentEdit , s o l u t i o n .

getEdit ( ) ) ) {18 undoneCleanUps . add ( cleanUp ) ;19 } else {20 CleanUpChange merge= new CleanUpChange (

FixMessages .CleanUpRefactor ing c lean up mult i chang name, context . getCompi lat ionUnit ( ) ) ;

21 merge . s e tEd i t ( TextEditUt i l . merge (currentEdit , s o l u t i o n . getEdit ( ) ) ) ;

2223 copyChangeGroups (merge , s o l u t i o n ) ;

Page 117: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 113

24 copyChangeGroups (merge , cur rent ) ;2526 s o l u t i o n= merge ;27 }28 } else {29 s o l u t i o n= new CleanUpChange ( cur rent . getName ( ) ,

context . getCompi lat ionUnit ( ) ) ;30 s o l u t i o n . s e tEd i t ( cur rentEd i t ) ;3132 copyChangeGroups ( so lu t i on , cur rent ) ;33 }34 }35 i++;36 } while ( i < cleanUps . l ength && ( context . getAST ( ) == null | | ! c leanUps [ i

] . getRequirements ( ) . requiresFreshAST ( ) ) ) ;

Listing A.65: ./org/eclipse/jdt/internal/corext/buildpath/ClasspathModi-fier.java

1 do {2 i f ( conta ine r instanceof IFo lder )3 javaElem= JavaCore . c r e a t e ( ( IFo lder ) conta ine r ) ;4 i f ( conta ine r . getFul lPath ( ) . equa l s ( p r o j e c t . getPath ( ) ) ) {5 javaElem= pro j e c t ;6 break ;7 }8 conta ine r= conta ine r . getParent ( ) ;9 i f ( conta ine r == null )

10 return null ;11 } while ( javaElem == null | | ! ( javaElem instanceof IPackageFragmentRoot )

) ;

Listing A.66: ./org/eclipse/jdt/internal/corext/refactoring/reorg/Refactor-ingModifications.java

1 while ( conta ine r != null && ! ( conta ine r . e x i s t s ( ) | |ge tResourceMod i f i ca t i ons ( ) . w i l l E x i s t ( conta ine r ) ) ) {

2 ge tResourceMod i f i ca t i ons ( ) . addCreate ( conta ine r ) ;3 conta ine r= conta ine r . getParent ( ) ;4 }

Listing A.67: ./org/eclipse/jdt/internal/corext/refactoring/code/Extract-MethodRefactoring.java

1 do {2 node= node . getParent ( ) ;3 } while ( node != null && ! ( node instanceof AbstractTypeDeclarat ion | |

node instanceof AnonymousClassDeclaration ) ) ;

Listing A.68: ./org/eclipse/jdt/internal/debug/ui/jres/InstalledJREs-Block.java

1 do {2 id= Str ing . valueOf ( System . cur rentTimeMi l l i s ( ) ) ;3 } while (vmType . f indVMInsta l l ( id ) != null | | id . equa l s ( fgLastUsedID ) ) ;

Listing A.69: ./org/eclipse/swt/internal/image/JPEGFileFormat.java

1 while ( ( z e r o s < r | | dataUnit [ zzIndex ] != 0) && k <= end ) {2 i f ( dataUnit [ zzIndex ] != 0) {3 dataUnit [ zzIndex ] = ref ineAC ( dataUnit [ zzIndex ] ,

approxBit ) ;

Page 118: A Feasibility Study of Loop Bound Analysis for Loops with ...

114 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

4 } else {5 ze ro s++;6 }7 k++;8 zzIndex = ZigZag8x8 [ k ] ;9 }

Listing A.70: ./org/eclipse/swt/internal/image/PngHuffmanTable.java

1 while ( j >= h && ( l eng ths [ j − h ] > v | | ( l eng ths [ j − h ] == v &&codeValues [ j − h ] > codeValuesTemp ) ) ) {

2 l eng ths [ j ] = l eng ths [ j − h ] ;3 codeValues [ j ] = codeValues [ j − h ] ;4 j −= h ;5 }

Listing A.71: ./org/eclipse/swt/internal/image/JPEGDecoder.java

1 while ( c i n f o . input scan number < c i n f o . output scan number | |2 ( c i n f o . input scan number == c i n f o . output scan number &&3 c i n f o . input iMCU row <= c i n f o . output iMCU row ) )4 {5 i f ( consume input ( c i n f o ) == JPEG SUSPENDED)6 return JPEG SUSPENDED;7 }

Listing A.72: ./org/eclipse/jface/text/formatter/ContentFormatter.java

1 while ( ’\ t ’ == c | | ’ ’ == c )2 c= fDocument . getChar(++end ) ;

Listing A.73: ./org/eclipse/jface/text/rules/RuleBasedPartitioner.java

1 do {2 −− f i r s t ;3 i f ( f i r s t < 0)4 break ;56 p= category [ f i r s t ] ;78 } while (p . overlapsWith ( e . g e tO f f s e t ( ) , e . getLength ( ) ) | |9 ( e . g e tO f f s e t ( ) == fPreviousDocumentLength &&

10 (p . g e tO f f s e t ( ) + p . getLength ( ) ==fPreviousDocumentLength ) ) ) ;

Listing A.74: ./org/eclipse/jface/text/AbstractDocument.java

1 while ( back >= 0 | | f o r th < s i z e ) {2 i f ( back >= 0) {3 i f ( p o s i t i o n == po s i t i o n s . get ( back ) ) {4 po s i t i o n s . remove ( back ) ;5 return ;6 }7 back−−;8 }9

10 i f ( f o r th < s i z e ) {11 i f ( p o s i t i o n == po s i t i o n s . get ( f o r th ) ) {12 po s i t i o n s . remove ( f o r th ) ;13 return ;14 }15 f o r th++;16 }17 }

Page 119: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 115

Listing A.75: ./org/eclipse/jface/text/source/DefaultCharacterPair-Matcher.java

1 while ( ( pos1 >= lowerBoundary && ! lowerFound ) | | ( pos2 < upperBoundary&& ! upperFound ) ) {

2 for ( int i= 0 ; i < counts . l ength ; i++) {3 counts [ i ] [ 0 ]= counts [ i ] [ 1 ]= 0 ;4 }56 outer1 : while ( pos1 >= lowerBoundary && ! lowerFound ) {7 f ina l char c= doc . getChar ( pos1 ) ;8 int i= getCharacterIndex ( c , document , pos1 ) ;9 i f ( i != −1 && doc . i nPa r t i t i o n ( pos1 ) ) {

10 i f ( i % 2 == 0) {11 counts [ i / 2] [0]−− ; // s t a r t12 } else {13 counts [ i / 2 ] [ 0 ]++; //end14 }15 for ( int j= 0 ; j < counts . l ength ; j++) {16 i f ( counts [ j ] [ 0 ] == −1) {17 lowerFound= true ;18 break outer1 ;19 }20 }21 }22 pos1= doc . getNextPos i t ion ( pos1 , fa l se ) ;23 }2425 outer2 : while ( pos2 < upperBoundary && ! upperFound ) {26 f ina l char c= doc . getChar ( pos2 ) ;27 int i= getCharacterIndex ( c , document , pos2 ) ;28 i f ( i != −1 && doc . i nPa r t i t i o n ( pos2 ) ) {29 i f ( i % 2 == 0) {30 counts [ i / 2 ] [ 1 ]++; // s t a r t31 } else {32 counts [ i / 2] [1]−− ; //end33 }34 for ( int j= 0 ; j < counts . l ength ; j++) {35 i f ( counts [ j ] [ 1 ] == −1 && counts [ j ] [ 0 ]

== −1) {36 upperFound= true ;37 break outer2 ;38 }39 }40 }41 pos2= doc . getNextPos i t ion ( pos2 , true ) ;42 }4344 i f ( pos1 > s t a r t | | pos2 < end − 1) {45 //match i n s i d e s e l e c t i o n => d i s ca rd46 pos1= doc . getNextPos i t ion ( pos1 , fa l se ) ;47 pos2= doc . getNextPos i t ion ( pos2 , true ) ;48 lowerFound= fa l se ;49 upperFound= fa l se ;50 }51 }

Listing A.76: ./org/eclipse/jface/text/source/LineChangeHover.java

1 while ( l >= min && in f o != null && ( i n f o . getChangeType ( ) ==IL i n eD i f f I n f o .CHANGED | | i n f o . getChangeType ( ) == IL i n eD i f f I n f o .ADDED) ) {

2 i n f o= d i f f e r . g e tL ine In f o(−− l ) ;3 }

Listing A.77: ./org/eclipse/jface/text/source/LineChangeHover.java

1 while ( l <= max && in f o != null && ( i n f o . getChangeType ( ) ==IL i n eD i f f I n f o .CHANGED | | i n f o . getChangeType ( ) == IL i n eD i f f I n f o .ADDED) ) {

Page 120: A Feasibility Study of Loop Bound Analysis for Loops with ...

116 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

2 i n f o= d i f f e r . g e tL ine In f o(++l ) ;3 }

Listing A.78: ./org/eclipse/jface/internal/text/html/HTML2TextReader.java

1 //As de f ined in sup e r c l a s s Subst i tut ionTextReader :2 protected int nextChar ( ) throws IOException {3 this . fReadFromBuffer= ( this . fBu f f e r . l ength ( ) > 0) ;4 i f ( this . fReadFromBuffer ) {5 char ch= this . fBu f f e r . charAt ( this . f Index++) ;6 i f ( this . f Index >= this . fBu f f e r . l ength ( ) ) {7 this . fBu f f e r . setLength (0) ;8 this . f Index= 0 ;9 }

10 return ch ;11 } else {12 int ch= this . fCharAfterWhiteSpace ;13 i f ( ch == −1) {14 ch= this . fReader . read ( ) ;15 }16 i f ( this . fSkipWhiteSpace && ScannerHelper . i sWhitespace ( (

char ) ch ) ) {17 do {18 ch= this . fReader . read ( ) ;19 } while ( ScannerHelper . i sWhitespace ( ( char ) ch ) ) ;20 i f ( ch != −1) {21 this . fCharAfterWhiteSpace= ch ;22 return ’ ’ ;23 }24 } else {25 this . fCharAfterWhiteSpace= −1;26 }27 return ch ;28 }29 }3031 while ( Character . i sL e t t e rOrD ig i t ( ( char ) ch ) | | ch == ’#’ ) {32 buf . append ( ( char ) ch ) ;33 ch= nextChar ( ) ;34 }

Listing A.79: ./org/eclipse/team/internal/c-cvs/ssh2/CVSSSH2ServerConnection.java

1 while ( f i r s tT ime | | tryAgain ) {2 tryAgain = fa l se ; // r e s e t the try again f l a g3 s e s s i o n = JSchSess ion . g e tSe s s i on ( l o ca t i on , l o c a t i o n . getUsername

( ) , password , l o c a t i o n . getHost ( ) , l o c a t i o n . getPort ( ) ,monitor ) ;

4 channel = s e s s i o n . g e tSe s s i on ( ) . openChannel ( ” exec ” ) ; //$NON−NLS−1$

5 ( ( ChannelExec ) channel ) . setCommand(COMMAND) ;6 channe l out = channel . getOutputStream ( ) ;7 channe l in = channel . getInputStream ( ) ;8 try {9 channel . connect ( ) ;

10 } catch ( JSchException ee ) {11 // This s t range l o g i c i s here due to how the JSch c l i e n t

share s s e s s i o n s .12 // I t i s p o s s i b l e that we have obtained a s e s s i o n that

th inks i t i s connected13 // but i s not . Channel connect ion only works i f the

s e s s i o n i s connected so the14 // above channel connect may f a i l because the s e s s i o n i s

down . For t h i s reason ,15 // we want to r e t r y i f the connect ion f a i l s .16 try {17 i f ( f i r s tT ime && ( isSess ionDownError ( ee ) | |

isChannelNotOpenError ( ee ) ) ) {18 tryAgain = true ;

Page 121: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 117

19 }20 i f ( ! tryAgain ) {21 throw ee ;22 }23 } f ina l ly {24 // Always d i spo s e o f the cur rent s e s s i o n when a

f a i l u r e occurs so we can s t a r t from sc ra t ch25 s e s s i o n . d i spo s e ( ) ;26 }27 }28 f i r s tT ime = fa l se ; // the f i r s t time i s done29 }

Listing A.80: ./org/eclipse/osgi/framework/internal/core/Tokenizer.java

1 while ( count > 0 && ( va l [ begin + count − 1 ] == ’ ’ | | va l [ begin + count− 1 ] == ’\ t ’ ) )

2 count−−;

Listing A.81: ./org/eclipse/osgi/util/ManifestElement.java

1 while ( c == ’=’ | | c == ’ : ’ ) {2 while ( c == ’ : ’ ) { // may not r e a l l y be a :=3 c = token i z e r . getChar ( ) ;4 i f ( c != ’=’ ) {5 St r ing restOfNext = token i z e r . getToken ( ”=:” ) ; //

$NON−NLS−1$6 i f ( restOfNext == null )7 throw new BundleException (NLS. bind (Msg .

MANIFEST INVALID HEADER EXCEPTION,header , va lue ) , BundleException .MANIFEST ERROR) ;

8 next += ” : ” + c + restOfNext ; //$NON−NLS−1$9 c = token i z e r . getChar ( ) ;

10 } else11 d i r e c t i v e = true ;12 }13 // determine i f the a t t r i bu t e i s the form a t t r : L i s t<type>14 St r ing prese rveEscapes = null ;15 i f ( ! d i r e c t i v e && next . indexOf ( ” L i s t ” ) > 0) { //$NON−NLS−1$16 Tokenizer l i s tTok en i z e r = new Tokenizer ( next ) ;17 St r ing attrKey = l i s tTok en i z e r . getToken ( ” : ” ) ; //$NON−NLS

−1$18 i f ( attrKey != null && l i s tTok en i z e r . getChar ( ) == ’ : ’ &&

” L i s t ” . equa l s ( l i s tTok en i z e r . getToken ( ”<” ) ) ) { //$NON−NLS−1$//$NON−NLS−2$

19 // we assume we must pre s e rve escapes f o r , and”

20 prese rveEscapes = ”\\ , ” ; //$NON−NLS−1$21 }22 }23 St r ing va l = token i z e r . g e tS t r i ng ( ” ; , ” , prese rveEscapes ) ; //$NON−

NLS−1$24 i f ( va l == null )25 throw new BundleException (NLS. bind (Msg .

MANIFEST INVALID HEADER EXCEPTION, header , va lue ) ,BundleException .MANIFEST ERROR) ;

2627 i f (Debug .DEBUG MANIFEST)28 Debug . p r i n t ( ” ; ” + next + ”=” + val ) ; //$NON−NLS−1$ //

$NON−NLS−2$29 try {30 i f ( d i r e c t i v e )31 manifestElement . addDirect ive ( next , va l ) ;32 else33 manifestElement . addAttr ibute ( next , va l ) ;34 d i r e c t i v e = fa l se ;35 } catch ( Exception e ) {36 throw new BundleException (NLS. bind (Msg .

MANIFEST INVALID HEADER EXCEPTION, header , va lue ) ,BundleException .MANIFEST ERROR, e ) ;

Page 122: A Feasibility Study of Loop Bound Analysis for Loops with ...

118 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

37 }38 c = token i z e r . getChar ( ) ;39 i f ( c == ’ ; ’ ) /∗ more ∗/{40 next = token i z e r . getToken ( ”=:” ) ; //$NON−NLS−1$41 i f ( next == null )42 throw new BundleException (NLS. bind (Msg .

MANIFEST INVALID HEADER EXCEPTION, header ,va lue ) , BundleException .MANIFEST ERROR) ;

43 c = token i z e r . getChar ( ) ;44 }45 }

Listing A.82: ./org/eclipse/ant/internal/ui/launchConfigurations/Ant-LaunchShortcut.java

1 while ( f i l e == null | | f i l e . getType ( ) != IResource . FILE) {2 for ( int i = 0 ; i < names . l ength ; i++) {3 St r ing s t r i n g = names [ i ] ;4 f i l e= lpa r en t . findMember ( s t r i n g ) ;5 i f ( f i l e != null && f i l e . getType ( ) == IResource . FILE) {6 break ;7 }8 }9 lpa r en t = lpa r en t . getParent ( ) ;

10 i f ( l pa r en t == null ) {11 return null ;12 }13 }

Listing A.83: ./org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java

1 while ( ( ( t e s t S h e l l != null && ! t e s t S h e l l . i sD i sposed ( ) ) | | ( ! theApp2 . getChi ldren ( ) . isEmpty ( ) && someAreVis ib le ( theApp3 . getChi ldren ( ) ) ) )4 && ! d i sp l ay . i sD i sposed ( ) ) {5 try {6 i f ( ! d i sp l ay . readAndDispatch ( ) ) {7 runContext . processWait ing ( ) ;8 i f ( spinOnce )9 return ;

10 adv i so r . eventLoopIdle ( d i sp l ay ) ;11 }12 } catch ( ThreadDeath th ) {13 throw th ;14 } catch ( Exception ex ) {15 handle ( ex , adv i so r ) ;16 } catch ( Error e r r ) {17 handle ( err , adv i so r ) ;18 }19 }

Listing A.84: ./org/eclipse/e4/core/services/util/JSONObject.java

1 while ( Character . i sD i g i t ( c ) | | c == ’− ’ | | c == ’+’ | | c == ’ . ’ | | c ==’ e ’ | | c == ’E ’ ) {

2 bu f f e r . append ( c ) ;3 c = i t . next ( ) ;4 }

Listing A.85: ./org/eclipse/compare/rangedifferencer/RangeDifferencer.java

1 while ( myIter . fD i f f e r e n c e != null | | your I t e r . fD i f f e r e n c e != null ) {23 D i f f e r e n c e s I t e r a t o r startThread ;4 myIter . removeAll ( ) ;

Page 123: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 119

5 your I t e r . removeAll ( ) ;6 //7 // take the next d i f f that i s c l o s e r to the s t a r t8 //9 i f ( myIter . fD i f f e r e n c e == null )

10 startThread= your I t e r ;11 else i f ( you r I t e r . fD i f f e r e n c e == null )12 startThread= myIter ;13 else { // not at end o f both s c r i p t s take the lowest range14 i f ( myIter . fD i f f e r e n c e . l e f t S t a r t < your I t e r . fD i f f e r e n c e .

l e f t S t a r t ) { // 2 −> common ( Ancestor ) change range15 startThread= myIter ;16 } else i f ( myIter . fD i f f e r e n c e . l e f t S t a r t > your I t e r .

fD i f f e r e n c e . l e f t S t a r t ) {17 startThread= your I t e r ;18 } else {19 i f ( myIter . fD i f f e r e n c e . l e f tLeng th == 0 &&

your I t e r . fD i f f e r e n c e . l e f tLeng th == 0) {20 // i n s e r t i o n in to the same po s i t i o n i s

c o n f l i c t .21 changeRangeStart= myIter . fD i f f e r e n c e .

l e f t S t a r t ;22 changeRangeEnd= myIter . fD i f f e r e n c e .

l e f tEnd ( ) ;23 myIter . next ( ) ;24 your I t e r . next ( ) ;25 d i f f 3 . add ( c reateRangeDi f f e r ence3 ( fac tory

, myIter , your I te r , d i f f 3 , r i ght ,l e f t , changeRangeStart ,changeRangeEnd ) ) ;

26 continue ;27 } else i f ( myIter . fD i f f e r e n c e . l e f tLeng th == 0)

{28 // i n s e r t i o n in to a pos i t i on , and

mod i f i c a t i on to the next l i n e , i snot c o n f l i c t .

29 startThread= myIter ;30 } else i f ( you r I t e r . fD i f f e r e n c e . l e f tLeng th == 0)

{31 startThread = your I t e r ;32 } else {33 // mod i f i c a t i on s to over lapp ing l i n e s i s

c o n f l i c t .34 startThread= myIter ;35 }36 }3738 }39 changeRangeStart= startThread . fD i f f e r e n c e . l e f t S t a r t ;40 changeRangeEnd= startThread . fD i f f e r e n c e . l e f tEnd ( ) ;4142 startThread . next ( ) ;43 monitor . worked (1) ;44 //45 // check f o r over lapp ing changes with other thread46 // merge over lapp ing changes with t h i s range47 //48 D i f f e r e n c e s I t e r a t o r other= startThread . other ( myIter , you r I t e r ) ;49 while ( other . fD i f f e r e n c e != null && other . fD i f f e r e n c e . l e f t S t a r t

< changeRangeEnd ) {50 int newMax= other . fD i f f e r e n c e . l e f tEnd ( ) ;51 other . next ( ) ;52 monitor . worked (1) ;53 i f (newMax > changeRangeEnd ) {54 changeRangeEnd= newMax ;55 other= other . other ( myIter , you r I t e r ) ;56 }57 }58 d i f f 3 . add ( c rea teRangeDi f f e r ence3 ( fac tory , myIter , your I te r ,

d i f f 3 , r i ght , l e f t , changeRangeStart , changeRangeEnd ) ) ;59 }

Page 124: A Feasibility Study of Loop Bound Analysis for Loops with ...

120 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

Listing A.86: ./org/eclipse/pde/api/tools/internal/comparator/ClassFileCom-parator.java

1 while ( superName != null && ( ! Ut i l . i sJavaLangObject ( superName ) | |inc ludeObject ) ) {

2 superClass = superClass . g e tSupe r c l a s s ( ) ;3 int v i s i b i l i t y = V i s i b i l i t yMod i f i e r s .PRIVATE;4 IApiComponent superComponent = superClass . getApiComponent ( ) ;5 IAp iDesc r ip t i on ap iDe s c r i p t i on = superComponent .

ge tApiDescr ipt ion ( ) ;6 IApiAnnotations e l ementDescr ipt ion = ap iDes c r i p t i on .

r e so lveAnnotat ions ( superClass . getHandle ( ) ) ;7 i f ( e l ementDesc r ipt ion != null ) {8 v i s i b i l i t y = e lementDescr ipt ion . g e t V i s i b i l i t y ( ) ;9 }

10 i f ( i n c ludePr i va t e | | ( ( v i s i b i l i t y & v i s i b i l i t yM o d i f i e r s ) != 0) ){

11 l i s t . add ( superClass ) ;12 }13 superName = superClass . getSuperclassName ( ) ;14 }

Listing A.87: ./org/eclipse/pde/internal/ui/editor/schema/ElementSec-tion.java

1 while ( ( o instanceof SchemaElementReference ) | | ! ( o instanceofISchemaElement ) ) {

2 o = o . getParent ( ) ;3 r e s u l t++;4 }

Listing A.88: ./org/eclipse/pde/internal/ui/editor/contentassist/Manifest-ContentAssistProcessor.java

1 while ( ( index = value . indexOf ( ’ : ’ ) ) == −1 | | ( ( value . l ength ( ) − 1 !=index ) && ( value . charAt ( index + 1) == ’=’ ) ) ) {

2 int s t a r tL in e = doc . g e tL ineOf f s e t ( lineNum ) ;3 value = doc . get ( s ta r tL ine , o f f s e t − s t a r tL in e ) ;4 lineNum−−;5 }

Listing A.89: ./org/eclipse/pde/internal/ui/editor/contentassist/Manifest-ContentAssistProcessor.java

1 do {2 s ta r tOfL ine = doc . g e tL ineOf f s e t ( l i n e ) ;3 newValue = doc . get ( o f f s e t , doc . getLineLength ( l i n e ) − o f f s e t +

star tOfL ine ) ;4 ++l i n e ;5 co lon = newValue . l a s t IndexOf ( ’ : ’ ) ;6 } while ( ( co lon == −1 | | ( newValue . l ength ( ) > co lon && newValue . charAt (

co lon + 1) == ’=’ ) ) && ( ent i reHeader | | newValue . indexOf ( ’ , ’ ) ==−1) && ! ( doc . getNumberOfLines ( ) == l i n e ) ) ;

Listing A.90: ./org/eclipse/core/internal/localstore/FileSystemResourceMan-ager.java

1 while ( newChar == ’\ r ’ | | newChar == ’\n ’ )2 newChar = newStream . read ( ) ;

Listing A.91: ./org/eclipse/core/internal/localstore/FileSystemResourceMan-ager.java

Page 125: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 121

1 while ( oldChar == ’\ r ’ | | oldChar == ’\n ’ )2 oldChar = oldStream . read ( ) ;

Listing A.92: ./org/eclipse/debug/internal/ui/viewers/model/TreeModelCon-tentProvider.java

1 while ( parentRequests == null | | parentRequests . isEmpty ( ) ) {2 parentPath = parentPath . getParentPath ( ) ;3 i f ( parentPath == null ) {4 // no running r eque s t s : s t a r t r eques t5 return fa l se ;6 }7 parentRequests = ( L i s t ) fReques t s InProgre s s . get ( parentPath ) ;8 }

Listing A.93: ./org/eclipse/debug/internal/ui/viewers/model/VirtualFindAc-tion.java

1 while ( ( ! l i s t e n e r . fLabelUpdatesComplete | | ! l i s t e n e r .fViewerUpdatesComplete ) && ! l i s t e n e r . fProgressMonitor . i sCance l ed ( ) ){

2 Thread . s l e ep (1) ;3 }

Listing A.94: ./org/eclipse/debug/internal/core/LaunchManager.java

1 while ( l i n e . indexOf ( ’=’ ) < 0 | | ( l i n e . l ength ( )>0 && ! Character .i s J a v a I d e n t i f i e r S t a r t ( l i n e . charAt (0) ) ) ) {

2 value += newLine + l i n e ;3 l i n e = reader . readLine ( ) ;4 i f ( l i n e == null ) {5 // i f next l i n e read i s the end o f the f i l e qu i t the loop6 break ;7 }8 }

Listing A.95: ./org/eclipse/debug/internal/core/LaunchManager.java

1 protected synchronized St r ing [ ] getAllSortedConfigNames ( ) {2 i f ( fSortedConfigNames == null ) {3 ILaunchConf igurat ion [ ] c o n f i g s = getLaunchConf igurat ions

( ) ;4 fSortedConfigNames = new St r ing [ c on f i g s . l ength ] ;5 for ( int i = 0 ; i < c on f i g s . l ength ; i++) {6 fSortedConfigNames [ i ] = c on f i g s [ i ] . getName ( ) ;7 }8 Arrays . s o r t ( fSortedConfigNames ) ;9 }

10 return fSortedConfigNames ;11 }12 public boolean i sExist ingLaunchConf igurat ionName ( St r ing name) {13 St r ing [ ] sortedConfigNames = getAllSortedConfigNames ( ) ;14 int index = Arrays . b inarySearch ( sortedConfigNames , name) ;15 i f ( index < 0) {16 return fa l se ;17 }18 return true ;19 }2021 while ( isExist ingLaunchConf igurat ionName (newname) | | reservednames .

conta in s (newname) ) {22 bu f f e r = new St r i ngBu f f e r ( base ) ;23 bu f f e r . append ( ” ( ” ) ; //$NON−NLS−1$24 bu f f e r . append ( St r ing . valueOf ( index ) ) ;25 index++;

Page 126: A Feasibility Study of Loop Bound Analysis for Loops with ...

122 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

26 bu f f e r . append ( ’ ) ’ ) ;27 newname = bu f f e r . t oS t r i ng ( ) ;28 }

Listing A.96: ./org/objectweb/asm/ClassWriter.java

1 while ( i != null && ( i . type != key . type | | ! key . isEqualTo ( i ) ) ) {2 i = i . next ;3 }

Listing A.97: ./org/osgi/framework/ServicePermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.98: ./org/osgi/framework/PackagePermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.99: ./org/osgi/framework/BundlePermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.100: ./org/osgi/framework/CapabilityPermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.101: ./org/osgi/framework/AdminPermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.102: ./org/osgi/framework/AdaptPermission.java

1 while ( ( i != −1) && (( c = a [ i ] ) == ’ ’ | | c == ’\ r ’ | | c == ’\n ’ | | c ==’\ f ’ | | c == ’\ t ’ ) )

2 i−−;

Listing A.103: ./org/apache/jasper/compiler/Parser.java

1 private JspReader reader ;23 while ( Character . i s L e t t e r ( ch ) | | Character . i sD i g i t ( ch ) | | ch == ’ . ’ | |

ch == ’ ’ | | ch == ’− ’ | | ch == ’ : ’ ) {4 buf . append ( ch ) ;5 reader . nextChar ( ) ;6 ch = ( char ) reader . peekChar ( ) ;7 }

Page 127: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 123

Listing A.104: ./org/apache/jasper/compiler/Parser.java

1 private JspReader reader ;23 do {4 // XXX could move t h i s l o g i c to JspReader5 currentChar = reader . nextChar ( ) ;6 i f ( currentChar == ’ \\ ’ && ( s ing leQuoted | | doubleQuoted ) ) {7 // sk ip charac t e r f o l l ow ing ’\ ’ with in quotes8 reader . nextChar ( ) ;9 currentChar = reader . nextChar ( ) ;

10 }11 i f ( currentChar == −1)12 e r r . j spEr ro r ( s ta r t , ” j sp . e r r o r . unterminated ” , typeEL ) ;13 i f ( currentChar == ’ ” ’ )14 doubleQuoted = ! doubleQuoted ;15 i f ( currentChar == ’ \ ’ ’ )16 s ing leQuoted = ! s ing leQuoted ;17 } while ( currentChar != ’} ’ | | ( s ing leQuoted | | doubleQuoted ) ) ;

Listing A.105: ./org/apache/lucene/index/IndexWriter.java

1 while ( writeThread != null | | readCount > 0)2 doWait ( ) ;

Listing A.106: ./org/apache/lucene/index/IndexWriter.java

1 while ( readCount > upgradeCount | | writeThread != null ) {2 doWait ( ) ;3 }

Listing A.107: ./org/apache/lucene/index/IndexWriter.java

1 while ( pendingMerges . s i z e ( ) > 0 | | runningMerges . s i z e ( ) > 0) {2 doWait ( ) ;3 }

Listing A.108: ./org/apache/lucene/index/DocumentsWriter.java

1 while ( ! c l o s ed && (( s t a t e != null && ! s t a t e . i s I d l e ) | | pauseThreads != 0| | f lushPending | | abort ing ) ) {

2 try {3 wait ( ) ;4 } catch ( Inter ruptedExcept ion i e ) {5 // In 3 .0 we w i l l change t h i s to throw6 // Inter ruptedExcept ion in s t ead7 Thread . currentThread ( ) . i n t e r r up t ( ) ;8 throw new RuntimeException ( i e ) ;9 }

10 }

Listing A.109: ./org/apache/lucene/search/spans/NearSpansOrdered.java

1 private boolean toSameDoc ( ) throws IOException {2 Arrays . s o r t ( subSpansByDoc , spanDocComparator ) ;3 int f i r s t I n d e x = 0 ;4 int maxDoc = subSpansByDoc [ subSpansByDoc . l ength − 1 ] . doc ( ) ;5 while ( subSpansByDoc [ f i r s t I n d e x ] . doc ( ) != maxDoc) {6 i f ( ! subSpansByDoc [ f i r s t I n d e x ] . skipTo (maxDoc) ) {7 more = fa l se ;8 inSameDoc = fa l se ;9 return fa l se ;

10 }

Page 128: A Feasibility Study of Loop Bound Analysis for Loops with ...

124 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

11 maxDoc = subSpansByDoc [ f i r s t I n d e x ] . doc ( ) ;12 i f (++f i r s t I n d e x == subSpansByDoc . l ength ) {13 f i r s t I n d e x = 0 ;14 }15 }16 for ( int i = 0 ; i < subSpansByDoc . l ength ; i++) {17 a s s e r t ( subSpansByDoc [ i ] . doc ( ) == maxDoc)18 : ” NearSpansOrdered . toSameDoc ( ) spans ” + subSpansByDoc [ 0 ]19 + ”\n at doc ” + subSpansByDoc [ i ] . doc ( )20 + ” , but should be at ” + maxDoc ;21 }22 inSameDoc = true ;23 return true ;24 }25 private boolean stretchToOrder ( ) throws IOException {26 matchDoc = subSpans [ 0 ] . doc ( ) ;27 for ( int i = 1 ; inSameDoc && ( i < subSpans . l ength ) ; i++) {28 while ( ! docSpansOrdered ( subSpans [ i −1] , subSpans [ i ] ) ) {29 i f ( ! subSpans [ i ] . next ( ) ) {30 inSameDoc = fa l se ;31 more = fa l se ;32 break ;33 } else i f (matchDoc != subSpans [ i ] . doc ( ) ) {34 inSameDoc = fa l se ;35 break ;36 }37 }38 }39 return inSameDoc ;40 }41 private boolean shr inkToAfterShortestMatch ( ) throws IOException {42 matchStart = subSpans [ subSpans . l ength − 1 ] . s t a r t ( ) ;43 matchEnd = subSpans [ subSpans . l ength − 1 ] . end ( ) ;44 Set poss ibleMatchPayloads = new HashSet ( ) ;45 i f ( subSpans [ subSpans . l ength − 1 ] . i sPay loadAva i l ab l e ( ) ) {46 poss ib leMatchPayloads . addAll ( subSpans [ subSpans . l ength −

1 ] . getPayload ( ) ) ;47 }4849 Co l l e c t i on pos s ib l ePay load = null ;5051 int matchSlop = 0 ;52 int l a s t S t a r t = matchStart ;53 int lastEnd = matchEnd ;54 for ( int i = subSpans . l ength − 2 ; i >= 0 ; i−−) {55 Spans prevSpans = subSpans [ i ] ;56 i f ( c o l l e c tPay l oad s && prevSpans . i sPay loadAva i l ab l e ( ) ) {57 Co l l e c t i on payload = prevSpans . getPayload ( ) ;58 pos s ib l ePay load = new ArrayList ( payload . s i z e ( ) ) ;59 pos s ib l ePay load . addAll ( payload ) ;60 }6162 int prevStar t = prevSpans . s t a r t ( ) ;63 int prevEnd = prevSpans . end ( ) ;64 while ( true ) { // Advance prevSpans un t i l a f t e r (

l a s t S t a r t , lastEnd )65 i f ( ! prevSpans . next ( ) ) {66 inSameDoc = fa l se ;67 more = fa l se ;68 break ; // Check remaining subSpans f o r

f i n a l match .69 } else i f (matchDoc != prevSpans . doc ( ) ) {70 inSameDoc = fa l se ; // The l a s t subSpans

i s not advanced here .71 break ; // Check remaining subSpans f o r

l a s t match in t h i s document .72 } else {73 int ppStart = prevSpans . s t a r t ( ) ;74 int ppEnd = prevSpans . end ( ) ; // Cannot

avoid invoking . end ( )75 i f ( ! docSpansOrdered ( ppStart , ppEnd ,

l a s t S t a r t , lastEnd ) ) {76 break ; // Check remaining

subSpans .

Page 129: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 125

77 } else { // prevSpans s t i l l b e f o r e (l a s t S t a r t , lastEnd )

78 prevStar t = ppStart ;79 prevEnd = ppEnd ;80 i f ( c o l l e c tPay l oad s && prevSpans

. i sPay loadAva i l ab l e ( ) ) {81 Co l l e c t i on payload =

prevSpans .getPayload ( ) ;

82 pos s ib l ePay load = newArrayList ( payload .s i z e ( ) ) ;

83 pos s ib l ePay load . addAll (payload ) ;

84 }85 }86 }87 }8889 i f ( c o l l e c tPay l oad s && poss ib l ePay load != null ) {90 poss ib leMatchPayloads . addAll ( pos s ib l ePay load ) ;91 }9293 a s s e r t prevStar t <= matchStart ;94 i f ( matchStart > prevEnd ) { // Only non over lapp ing

spans add to s l op .95 matchSlop += (matchStart − prevEnd ) ;96 }9798 /∗ Do not break on (matchSlop > a l lowedSlop ) here to

make sure99 ∗ that subSpans [ 0 ] i s advanced a f t e r the match , i f any .

100 ∗/101 matchStart = prevStar t ;102 l a s t S t a r t = prevStar t ;103 lastEnd = prevEnd ;104 }105106 boolean match = matchSlop <= al lowedSlop ;107108 i f ( c o l l e c tPay l oad s && match && poss ib leMatchPayloads . s i z e ( ) > 0) {109 matchPayload . addAll ( poss ib leMatchPayloads ) ;110 }111112 return match ; // ordered and al lowed s l op113 }114115 while (more && ( inSameDoc | | toSameDoc ( ) ) ) {116 i f ( stretchToOrder ( ) && shrinkToAfterShortestMatch ( ) ) {117 return true ;118 }119 }

Listing A.110: ./org/apache/lucene/search/BooleanScorer.java

1 do {2 bucketTable . f i r s t = null ;34 while ( cur rent != null ) { // more queued56 // check proh ib i t ed & requ i r ed7 i f ( ( cur rent . b i t s & prohibitedMask ) == 0 &&8 ( cur rent . b i t s & requiredMask ) == requiredMask ) {9

10 i f ( cur rent . doc >= max){11 tmp = current ;12 cur rent = current . next ;13 tmp . next = bucketTable . f i r s t ;14 bucketTable . f i r s t = tmp ;15 continue ;16 }17

Page 130: A Feasibility Study of Loop Bound Analysis for Loops with ...

126 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

18 i f ( cur rent . coord >= minNrShouldMatch ) {19 bs . s co r e = current . s co r e ∗ coordFactors [

cur rent . coord ] ;20 bs . doc = current . doc ;21 c o l l e c t o r . c o l l e c t ( cur rent . doc ) ;22 }23 }2425 cur rent = current . next ; // pop the queue26 }2728 i f ( bucketTable . f i r s t != null ){29 cur rent = bucketTable . f i r s t ;30 bucketTable . f i r s t = cur rent . next ;31 return true ;32 }3334 // r e f i l l the queue35 more = fa l se ;36 end += BucketTable . SIZE ;37 for ( SubScorer sub = s c o r e r s ; sub != null ; sub = sub . next ) {38 int subScorerDocID = sub . s c o r e r . docID ( ) ;39 i f ( subScorerDocID != NO MORE DOCS) {40 more |= sub . s c o r e r . s co r e ( sub . c o l l e c t o r , end ,

subScorerDocID ) ;41 }42 }43 cur rent = bucketTable . f i r s t ;44 } while ( cur rent != null | | more ) ;

Listing A.111: ./org/apache/lucene/search/BooleanScorer.java

1 do {2 while ( bucketTable . f i r s t != null ) { // more queued3 cur rent = bucketTable . f i r s t ;4 bucketTable . f i r s t = cur rent . next ; // pop the

queue56 // check proh ib i t ed & requi red , and minNrShouldMatch7 i f ( ( cur rent . b i t s & prohibitedMask ) == 0 && ( cur rent .

b i t s & requiredMask ) == requiredMask && current .coord >= minNrShouldMatch ) {

8 return doc = current . doc ;9 }

10 }1112 // r e f i l l the queue13 more = fa l se ;14 end += BucketTable . SIZE ;15 for ( SubScorer sub = s c o r e r s ; sub != null ; sub = sub . next ) {16 Scorer s c o r e r = sub . s c o r e r ;17 sub . c o l l e c t o r . s e t S co r e r ( s c o r e r ) ;18 int doc = s co r e r . docID ( ) ;19 while ( doc < end ) {20 sub . c o l l e c t o r . c o l l e c t ( doc ) ;21 doc = s c o r e r . nextDoc ( ) ;22 }23 more |= ( doc != NO MORE DOCS) ;24 }25 } while ( bucketTable . f i r s t != null | | more ) ;

Listing A.112: ./libsrc/org/apache/tools/ant/util/LineOrientedOutput-Stream.java

1 while ( remaining > 0 && (b [ o f f s e t ] == LF | | b [ o f f s e t ] == CR) ) {2 wr i t e (b [ o f f s e t ] ) ;3 o f f s e t++;4 remaining−−;5 }

Page 131: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 127

Listing A.113: ./libsrc/org/apache/tools/ant/taskdefs/SQLExec.java

1 do {2 i f ( updateCount != −1) {3 updateCountTotal += updateCount ;4 }5 i f ( r e t ) {6 r e s u l t S e t = getStatement ( ) . ge tResu l tSe t ( ) ;7 printWarnings ( r e s u l t S e t . getWarnings ( ) , fa l se ) ;8 r e s u l t S e t . c learWarnings ( ) ;9 i f ( p r i n t ) {

10 p r i n tRe su l t s ( r e su l tS e t , out ) ;11 }12 }13 r e t = getStatement ( ) . getMoreResults ( ) ;14 updateCount = getStatement ( ) . getUpdateCount ( ) ;15 } while ( r e t | | updateCount != −1) ;

Listing A.114: ./libsrc/org/apache/tools/ant/taskdefs/PumpStreamHan-dler.java

1 while ( ( s == null | | ! s . i sF i n i s h ed ( ) ) && t . i sA l i v e ( ) ) {2 t . i n t e r r up t ( ) ;3 t . j o i n (JOIN TIMEOUT) ;4 }

Listing A.115: ./libsrc/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java

1 while ( haveReadAhead | | s t . hasMoreTokens ( ) ) {2 St r ing currentToken = haveReadAhead ? cachedVers ion : s t .

nextToken ( ) ;3 haveReadAhead = fa l se ;4 i f ( currentToken . equa l s ( ” C l i en t : ” ) ) {5 c l i e n t = true ;6 } else i f ( currentToken . equa l s ( ” Server : ” ) ) {7 s e r v e r = true ;8 } else i f ( currentToken . startsWith ( ” (CVS” )9 && currentToken . endsWith ( ” ) ” ) ) {

10 cvs = currentToken . l ength ( ) == 5 ? ”” : ” ” +currentToken ;

11 }12 i f ( ! c l i e n t && ! s e r v e r && cvs != null13 && cachedVers ion == null && st . hasMoreTokens ( ) ) {14 cachedVers ion = s t . nextToken ( ) ;15 haveReadAhead = true ;16 } else i f ( c l i e n t && cvs != null ) {17 i f ( s t . hasMoreTokens ( ) ) {18 c l i e n tVe r s i o n = s t . nextToken ( ) + cvs ;19 }20 c l i e n t = fa l se ;21 cvs = null ;22 } else i f ( s e r v e r && cvs != null ) {23 i f ( s t . hasMoreTokens ( ) ) {24 s e rve rVer s i on = s t . nextToken ( ) + cvs ;25 }26 s e r v e r = fa l se ;27 cvs = null ;28 } else i f ( currentToken . equa l s ( ” ( c l i e n t / s e r v e r ) ” )29 && cvs != null && cachedVers ion != null30 && ! c l i e n t && ! s e r v e r ) {31 c l i e n t = s e rv e r = true ;32 c l i e n tVe r s i o n = se rve rVer s i on = cachedVers ion + cvs ;33 cachedVers ion = cvs = null ;34 }35 }

Listing A.116: ./libsrc/org/apache/tools/ant/taskdefs/Concat.java

Page 132: A Feasibility Study of Loop Bound Analysis for Loops with ...

128 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

1 private I t e r a t o r readerSource s ;2 private Reader getReader ( ) throws IOException {3 i f ( reader == null && readerSources . hasNext ( ) ) {4 reader = fa c t o ry . getReader ( readerSource s . next ( ) ) ;5 Arrays . f i l l ( lastChars , ( char ) 0) ;6 }7 return reader ;8 }9

10 while ( getReader ( ) != null | | needAddSeparator ) {11 i f ( needAddSeparator ) {12 cbuf [ o f f ] = e o l S t r i n g . charAt ( l a s tPos++) ;13 i f ( l a s tPos >= eo l S t r i n g . l ength ( ) ) {14 la s tPos = 0 ;15 needAddSeparator = fa l se ;16 }17 len−−;18 o f f++;19 amountRead++;20 i f ( l en == 0) {21 return amountRead ;22 }23 continue ;24 }25 int nRead = getReader ( ) . read ( cbuf , o f f , l en ) ;26 i f (nRead == −1 | | nRead == 0) {27 nextReader ( ) ;28 i f ( i sF ixLas tL ine ( ) && isMiss ingEndOfLine ( ) ) {29 needAddSeparator = true ;30 l a s tPos = 0 ;31 }32 } else {33 i f ( i sF ixLas tL ine ( ) ) {34 for ( int i = nRead ;35 i > (nRead − l a s tChars . l ength ) ;36 −−i ) {37 i f ( i <= 0) {38 break ;39 }40 addLastChar ( cbuf [ o f f + i − 1 ] ) ;41 }42 }43 l en −= nRead ;44 o f f += nRead ;45 amountRead += nRead ;46 i f ( l en == 0) {47 return amountRead ;48 }49 }50 }

Listing A.117: ./libsrc/org/apache/tools/ant/filters/TailFilter.java

1 while ( l i n e == null | | l i n e . l ength ( ) == 0) {2 l i n e = l in eToken i z e r . getToken ( in ) ;3 l i n e = t a i l F i l t e r ( l i n e ) ;4 i f ( l i n e == null ) {5 return −1;6 }7 l inePos = 0 ;8 }

Listing A.118: ./libsrc/org/apache/tools/ant/filters/HeadFilter.java

1 while ( l i n e == null | | l i n e . l ength ( ) == 0) {2 l i n e = l in eToken i z e r . getToken ( in ) ;3 i f ( l i n e == null ) {4 return −1;5 }6 l i n e = headF i l t e r ( l i n e ) ;

Page 133: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 129

7 i f ( eo f ) {8 return −1;9 }

10 l inePos = 0 ;11 }

Listing A.119: ./libsrc/org/apache/tools/ant/filters/TokenFilter.java

1 while ( l i n e == null | | l i n e . l ength ( ) == 0) {2 l i n e = token i z e r . getToken ( in ) ;3 i f ( l i n e == null ) {4 return −1;5 }6 for ( Enumeration e = f i l t e r s . e lements ( ) ; e . hasMoreElements ( ) ; ) {7 F i l t e r f i l t e r = ( F i l t e r ) e . nextElement ( ) ;8 l i n e = f i l t e r . f i l t e r ( l i n e ) ;9 i f ( l i n e == null ) {

10 break ;11 }12 }13 l inePos = 0 ;14 i f ( l i n e != null ) {15 i f ( t ok en i z e r . getPostToken ( ) . l ength ( ) != 0) {16 i f ( delimOutput != null ) {17 l i n e = l i n e + delimOutput ;18 } else {19 l i n e = l i n e + token i z e r . getPostToken ( ) ;20 }21 }22 }23 }

Listing A.120: ./libsrc/org/apache/tools/ant/DemuxOutputStream.java

1 while ( remaining > 0 && (b [ o f f s e t ] == LF | | b [ o f f s e t ] == CR) ) {2 wr i t e (b [ o f f s e t ] ) ;3 o f f s e t++;4 remaining−−;5 }

Listing A.121: ./com/ibm/icu/text/CollationKey.java

1 while ( m key [ index ] < 0 | | m key [ index ] >= MERGE SEPERATOR ) {2 r e s u l t [ r index ++] = m key [ index ++];3 }

Listing A.122: ./com/ibm/icu/text/CollationParsedRuleBuilder.java

1 while ( ( ( prevCE & STRENGTH MASK [ s t r ength ] ) != (CE & STRENGTH MASK [s t r ength ] ) | | ( prevContCE & STRENGTH MASK [ s t r ength ] ) != ( contCE &STRENGTH MASK [ s t r ength ] ) )

2 && ( s t r ength != 0) ) {3 strength−−;4 }

Listing A.123: ./com/ibm/icu/text/CollationParsedRuleBuilder.java

1 while ( ( c e i << 1) < m ut i l I n tBu f f e r [ 0 ] | | c e i < m ut i l I n tBu f f e r [ 1 ]2 | | c e i < m ut i l I n tBu f f e r [ 2 ] ) {3 i f ( c e i > 0) {4 value = RuleBasedCol lator .CE CONTINUATION MARKER ;5 } else {6 value = 0 ;7 }

Page 134: A Feasibility Study of Loop Bound Analysis for Loops with ...

130 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

89 i f ( ( c e i << 1) < m ut i l I n tBu f f e r [ 0 ] ) {

10 value |= (( cepa r t s [ 0 ] >> (32 − ( ( c e i + 1) << 4) ) ) & 0xFFFF) << 16 ;

11 }12 i f ( c e i < m ut i l I n tBu f f e r [ 1 ] ) {13 value |= (( cepa r t s [ 1 ] >> (32 − ( ( c e i + 1) << 3) ) ) & 0xFF

) << 8 ;14 }1516 i f ( c e i < m ut i l I n tBu f f e r [ 2 ] ) {17 value |= (( cepa r t s [ 2 ] >> (32 − ( ( c e i + 1) << 3) ) ) & 0x3F

) ;18 }19 token .m CE [ c e i ] = value ;20 c e i++;21 }

Listing A.124: ./com/ibm/icu/text/CollationRuleParser.java

1 while ( m opt ionarg < optionend && (UCharacter . i sWhitespace ( r u l e s . charAt( m opt ionarg ) ) | | UCharacterProperty . isRuleWhiteSpace ( r u l e s . charAt( m opt ionarg ) ) ) )

2 { // eat whitespace3 m optionarg ++;4 }

Listing A.125: ./com/ibm/icu/util/BasicTimeZone.java

1 while ( ! bFinalStd | | ! bFinalDst ) {2 t z t = getNextTrans i t ion ( time , fa l se ) ;3 i f ( t z t == null ) {4 break ;5 }6 time = tz t . getTime ( ) ;78 TimeZoneRule toRule = t z t . getTo ( ) ;9 int ru l e Idx = 1 ;

10 for ( ; ru l e Idx < a l l . l ength ; ru l e Idx++) {11 i f ( a l l [ ru l e Idx ] . equa l s ( toRule ) ) {12 break ;13 }14 }15 i f ( ru l e Idx >= a l l . l ength ) {16 throw new I l l e g a l S t a t eEx c ep t i o n ( ”The ru l e was not found”

) ;17 }18 i f ( i sP ro c e s s ed . get ( ru l e Idx ) ) {19 continue ;20 }21 i f ( toRule instanceof TimeArrayTimeZoneRule ) {22 TimeArrayTimeZoneRule ta r = (TimeArrayTimeZoneRule )

toRule ;2324 // Get the prev ious raw o f f s e t and DST sav ings be f o r e

the very f i r s t s t a r t time25 long t = s t a r t ;26 while ( true ) {27 t z t = getNextTrans i t ion ( t , fa l se ) ;28 i f ( t z t == null ) {29 break ;30 }31 i f ( t z t . getTo ( ) . equa l s ( ta r ) ) {32 break ;33 }34 t = t z t . getTime ( ) ;35 }36 i f ( t z t != null ) {37 // Check i f the e n t i r e s t a r t t imes to be added38 Date f i r s t S t a r t = tar . g e tF i r s t S t a r t ( t z t . getFrom

( ) . getRawOffset ( ) ,

Page 135: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.1. WHILE-LOOPS 131

39 t z t . getFrom ( ) . getDSTSavings ( ) ) ;40 i f ( f i r s t S t a r t . getTime ( ) > s t a r t ) {41 // Just add the ru l e as i s42 f i l t e r e dRu l e s . add ( ta r ) ;43 } else {44 // Co l l e c t t r a n s i t i o n s a f t e r the s t a r t

time45 long [ ] t imes = tar . getStartTimes ( ) ;46 int timeType = tar . getTimeType ( ) ;47 int idx ;48 for ( idx = 0 ; idx < t imes . l ength ; idx++)

{49 t = times [ idx ] ;50 i f ( timeType == DateTimeRule .

STANDARD TIME) {51 t −= tz t . getFrom ( ) .

getRawOffset ( ) ;52 }53 i f ( timeType == DateTimeRule .

WALL TIME) {54 t −= tz t . getFrom ( ) .

getDSTSavings ( ) ;55 }56 i f ( t > s t a r t ) {57 break ;58 }59 }60 int a s i z e = times . l ength − idx ;61 i f ( a s i z e > 0) {62 long [ ] newtimes = new long [ a s i z e

] ;63 System . arraycopy ( times , idx ,

newtimes , 0 , a s i z e ) ;64 TimeArrayTimeZoneRule newtar =

new TimeArrayTimeZoneRule (65 ta r . getName ( ) ,

ta r .getRawOffset( ) , ta r .getDSTSavings( ) ,

66 newtimes , ta r .getTimeType( ) ) ;

67 f i l t e r e dRu l e s . add ( newtar ) ;68 }69 }70 }71 } else i f ( toRule instanceof AnnualTimeZoneRule ) {72 AnnualTimeZoneRule ar = (AnnualTimeZoneRule ) toRule ;73 Date f i r s t S t a r t = ar . g e tF i r s t S t a r t ( t z t . getFrom ( ) .

getRawOffset ( ) ,74 t z t . getFrom ( ) . getDSTSavings ( ) ) ;75 i f ( f i r s t S t a r t . getTime ( ) == tz t . getTime ( ) ) {76 // Just add the ru l e as i s77 f i l t e r e dRu l e s . add ( ar ) ;78 } else {79 // Ca lcu la te the t r a n s i t i o n year80 int [ ] d f i e l d s = new int [ 6 ] ;81 Grego . t imeToFie lds ( t z t . getTime ( ) , d f i e l d s ) ;82 // Recreate the ru l e83 AnnualTimeZoneRule newar = new

AnnualTimeZoneRule ( ar . getName ( ) ,84 ar . getRawOffset ( ) , ar .

getDSTSavings ( ) ,85 ar . getRule ( ) , d f i e l d s [ 0 ] , ar .

getEndYear ( ) ) ;86 f i l t e r e dRu l e s . add ( newar ) ;87 }88 // Check i f t h i s i s a f i n a l r u l e89 i f ( ar . getEndYear ( ) == AnnualTimeZoneRule .MAXYEAR) {90 // After both f i n a l standard and dst ru l e are

processed ,91 // e x i t t h i s whi le loop .

Page 136: A Feasibility Study of Loop Bound Analysis for Loops with ...

132 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

92 i f ( ar . getDSTSavings ( ) == 0) {93 bFinalStd = true ;94 } else {95 bFinalDst = true ;96 }97 }98 }99 i sP roc e s s ed . s e t ( ru l e Idx ) ;

100 }

A.2 For-loops

Listing A.126: ./org/eclipse/ui/internal/dialogs/TreeManager.java

1 for ( I t e r a t o r i = changedItem . parent . ch i l d r en . i t e r a t o r ( ) ; i . hasNext ( ) &&( ! checkedFound | | ! uncheckedFound ) ; ) {

2 TreeItem item = ( TreeItem ) i . next ( ) ;3 switch ( item . checkState ) {4 case CHECKSTATECHECKED: {5 checkedFound = true ;6 break ;7 } case CHECKSTATEGRAY: {8 checkedFound = uncheckedFound = true ;9 break ;

10 } case CHECKSTATEUNCHECKED: {11 uncheckedFound = true ;12 break ;13 }}14 }

Listing A.127: ./org/eclipse/ui/internal/navigator/NavigatorContentSer-viceDescriptionProvider.java

1 for ( int i = 0 ; i < prov ide r s . l ength && (message == null | | message .l ength ( ) == 0) ; i++) {

2 i f ( p rov ide r s [ i ] instanceof ICommonLabelProvider ) {3 message = ( ( ICommonLabelProvider ) p rov ide r s [ i ] )4 . g e tDe s c r i p t i on ( t a r g e t ) ;5 }6 }

Listing A.128: ./org/eclipse/jdt/internal/formatter/Scribe.java

1 for ( int idx=0, ptr=0; idx<=max | | ( t ext . htmlNodesPtr != −1 && ptr <=text . htmlNodesPtr ) ; idx++) {

23 // append text to bu f f e r r e a l i g n i n g with the l i n e l ength4 int end = ( idx > max) ? text . sourceEnd : ( int ) ( t ext . s epa ra to r s [

idx ] >>> 32) ;5 int nodeKind = 0 ; // text break6 i f ( t ext . htmlNodesPtr >= 0 && ptr <= text . htmlNodesPtr && end >

t ext . htmlNodes [ ptr ] . s ou r c eS ta r t ) {7 FormatJavadocNode node = text . htmlNodes [ ptr ] ;8 FormatJavadocText htmlTag = node . i sText ( ) ? (

FormatJavadocText ) node : null ;9 int newLines = htmlTag == null ? 0 : htmlTag . l i n e sB e f o r e

;10 i f ( l i n e sA f t e r > newLines ) {11 newLines = l i n e sA f t e r ;12 i f ( newLines > 1 && c learB lankL ines ) {13 i f ( idx < 2 | | ( t ext . htmlIndexes [ idx−2]

& JAVADOC TAGS ID MASK) !=JAVADOC CODE TAGS ID) {

14 newLines = 1 ;15 }16 }

Page 137: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.2. FOR-LOOPS 133

17 }18 i f ( t ex tS ta r t < previousEnd ) {19 addReplaceEdit ( t extStar t , previousEnd , bu f f e r .

t oS t r i ng ( ) ) ;20 }21 boolean immutable = node . isImmutable ( ) ;22 i f ( newLines == 0) {23 newLines = printJavadocBlockNodesNewLines ( block ,

node , previousEnd ) ;24 }25 int nodeStart = node . s ou r c eS ta r t ;26 i f ( newLines > 0 | | ( idx > 1 && nodeStart > ( previousEnd

+1) ) ) {27 printJavadocGapLines ( previousEnd+1, nodeStart −1,

newLines , c l earBlankLines , false , null ) ;28 }29 i f ( newLines > 0) textOnNewLine = true ;30 bu f f e r . setLength (0) ;31 i f ( node . i sText ( ) ) {32 i f ( immutable ) {33 // do not change immutable tags , j u s t

increment column34 i f ( textOnNewLine && this .

commentIndentation != null ) {35 addInser tEd i t ( node . sourceStar t ,

this . commentIndentation ) ;36 this . column += this .

commentIndentation . l ength ( );

37 }38 printJavadocImmutableText ( htmlTag , block

, textOnNewLine ) ;39 this . column += getTextLength ( block ,

htmlTag ) ;40 l i n e sA f t e r = 0 ;41 } else {42 l i n e sA f t e r = printJavadocHtmlTag ( htmlTag

, block , textOnNewLine ) ;43 }44 nodeKind = 1 ; // text45 } else {46 i f ( textOnNewLine && this . commentIndentation !=

null ) {47 addInser tEd i t ( node . sourceStar t , this .

commentIndentation ) ;48 this . column += this . commentIndentation .

l ength ( ) ;49 }50 pr intJavadocBlock ( ( FormatJavadocBlock ) node ) ;51 l i n e sA f t e r = 0 ;52 nodeKind = 2 ; // block53 }54 t ex tS ta r t = node . sourceEnd+1;55 ptr++;56 i f ( idx > max) {57 return l i n e sA f t e r ;58 }59 } else {60 i f ( idx > 0 && l i n e sA f t e r > 0) {61 printJavadocGapLines ( previousEnd+1, nextStart −1,

l i n e sA f t e r , c l earBlankLines , false , b u f f e r) ;

62 textOnNewLine = true ;63 }64 boolean needIndentat ion = textOnNewLine ;65 i f ( idx > 0) {66 i f ( ! needIndentat ion && text .

isTextAfterHtmlSeparatorTag ( idx−1) ) {67 needIndentat ion = true ;68 }69 }70 this . needSpace = idx > 1 && ( previousEnd+1) < nextStar t ;

// There ’ s no space between text and html tag ori n l i n e block => do not i n s e r t space a the beg inning

Page 138: A Feasibility Study of Loop Bound Analysis for Loops with ...

134 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

o f the text71 printJavadocTextLine ( bu f f e r , nextStart , end , block , idx

==0, needIndentat ion , idx==0/∗ opening html tag ?∗/| | t ext . htmlIndexes [ idx−1] != −1) ;

72 l i n e sA f t e r = 0 ;73 i f ( idx==0) {74 i f ( isHtmlSeparatorTag ) {75 l i n e sA f t e r = 1 ;76 }77 } else i f ( t ext . htmlIndexes [ idx−1] ==

JAVADOC SINGLE BREAK TAG ID) {78 l i n e sA f t e r = 1 ;79 }80 }8182 // Replace with cur rent bu f f e r i f the re are s e v e r a l empty l i n e s

between text l i n e s83 nextStar t = ( int ) t ext . s epa ra to r s [ idx ] ;84 int endLine = Ut i l . getLineNumber ( end , this . l ineEnds , s ta r tL ine

−1, this . maxLines ) ;85 s t a r tL in e = Ut i l . getLineNumber ( nextStart , this . l ineEnds , endLine

−1, this . maxLines ) ;86 int l inesGap = s ta r tL in e − endLine ;87 i f ( l inesGap > 0) {88 i f ( c l ea rB lankL ines ) {89 // keep p r ev i ou s l y computed l i n e s a f t e r90 } else {91 i f ( idx==0 | | l inesGap > 1 | | ( idx < max &&

nodeKind==1 && ( text . htmlIndexes [ idx−1] &JAVADOC TAGS ID MASK) !=JAVADOC IMMUTABLE TAGS ID) ) {

92 i f ( l i n e sA f t e r < l inesGap ) {93 l i n e sA f t e r = l inesGap ;94 }95 }96 }97 }98 textOnNewLine = l i n e sA f t e r > 0 ;99

100 // pr in t <pre> tag101 i f ( isCode ) {102 int codeEnd = ( int ) ( t ext . s epa ra to r s [max ] >>> 32) ;103 i f ( codeEnd > end ) {104 i f ( this . f o rmatter . p r e f e r e n c e s .

comment format source ) {105 i f ( t ex tS ta r t < end ) addReplaceEdit (

t extStar t , end , bu f f e r . t oS t r i ng ( ) ) ;106 // See whether the re ’ s a space be f o r e

the code107 i f ( l inesGap > 0) {108 int l i n e S t a r t = this . scanner .

g e tL ineSta r t ( s t a r tL in e ) ;109 i f ( nextStar t > l i n e S t a r t ) { //

i f code s t a r t s at the l i n e ,then no l ead ing space i s

needed110 this . scanner . resetTo (

l i n eS t a r t ,nextStart −1) ;

111 try {112 int token = this

. scanner .getNextToken( ) ;

113 i f ( token ==TerminalTokens.TokenNameWHITESPACE) {

114 // sk ipindenta t i on

115 token =this

Page 139: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.2. FOR-LOOPS 135

.scanner.getNextToken( ) ;

116 }117 i f ( token ==

TerminalTokens.TokenNameMULTIPLY) {

118 nextStar t=this.scanner.cu r r en tPo s i t i on;

119 }120 }121 catch (

Inva l id InputExcept ioni i e ) {

122 // sk ip123 }124 }125 }126 // Format gap l i n e s be f o r e code127 int newLines = l inesGap ;128 i f ( newLines == 0) newLines=1;129 this . needSpace = fa l se ;130 printJavadocGapLines ( end+1, nextStart −1,

newLines , fa l se /∗ c l e a r f i r s tblank l i n e s i n s i d e <pre> tag asdone by old formatter ∗/ , false ,null ) ;

131 // Format the code132 printCodeSnippet ( nextStart , codeEnd ,

l inesGap ) ;133 // Format the gap l i n e s a f t e r the code134 nextStar t = ( int ) t ext . s epa ra to r s [max ] ;135 printJavadocGapLines ( codeEnd+1,

nextStart −1, 1 , fa l se /∗ c l e a r blankl i n e s i n s i d e <pre> tag as done by

old formatter ∗/ , false , null ) ;136 return 2 ;137 }138 } else {139 nextStar t = ( int ) t ext . s epa ra to r s [max ] ;140 i f ( ( nextStart −1) > ( end+1) ) {141 int l i n e 1 = Ut i l . getLineNumber ( end+1,

this . l ineEnds , s ta r tL ine −1, this .maxLines ) ;

142 int l i n e 2 = Ut i l . getLineNumber ( nextStart−1, this . l ineEnds , l i n e1 −1, this .maxLines ) ;

143 int gapLines = l ine2−l i n e1 −1;144 printJavadocGapLines ( end+1, nextStart −1,

gapLines , fa l se /∗ never c l e a rblank l i n e s i n s i d e <pre> tag ∗/ ,false , null ) ;

145 i f ( gapLines > 0) textOnNewLine = true ;146 }147 }148 return 1 ;149 }150151 // s t o r e prev ious end152 previousEnd = end ;153 }

Page 140: A Feasibility Study of Loop Bound Analysis for Loops with ...

136 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

Listing A.129: ./org/eclipse/jface/viewers/AbstractTableViewer.java

1 for ( int column = 0 ; column < columnCount | | column == 0 ; column++) {2 ViewerColumn columnViewer = getViewerColumn ( column ) ;3 ViewerCel l cel lToUpdate = updateCel l ( viewerRowFromItem ,4 column , element ) ;56 // I f the con t r o l i s v i r tua l , we cannot use the cached c e l l

ob j e c t . See bug 188663.7 i f ( i sV i r t u a l ) {8 cel lToUpdate = new ViewerCel l ( cel lToUpdate . getViewerRow

( ) , cel lToUpdate . getColumnIndex ( ) , element ) ;9 }

1011 columnViewer . r e f r e s h ( cel lToUpdate ) ;1213 // c l e a r c e l l ( s ee bug 201280)14 updateCel l (null , 0 , null ) ;1516 // As i t i s p o s s i b l e f o r user code to run the event17 // loop check here .18 i f ( item . i sD i sposed ( ) ) {19 unmapElement ( element , item ) ;20 return ;21 }2223 }

Listing A.130: ./org/eclipse/jface/viewers/AbstractTableViewer.java

1 for ( int column = 0 ; column < columnCount | | column == 0 ; column++) {2 ViewerColumn columnViewer = getViewerColumn ( column ) ;3 ViewerCel l cel lToUpdate = updateCel l ( viewerRowFromItem ,4 column , element ) ;56 // I f the con t r o l i s v i r tua l , we cannot use the cached c e l l

ob j e c t . See bug 188663.7 i f ( i sV i r t u a l ) {8 cel lToUpdate = new ViewerCel l ( cel lToUpdate . getViewerRow

( ) , cel lToUpdate . getColumnIndex ( ) , element ) ;9 }

1011 columnViewer . r e f r e s h ( cel lToUpdate ) ;1213 // c l e a r c e l l ( s ee bug 201280)14 updateCel l (null , 0 , null ) ;1516 // As i t i s p o s s i b l e f o r user code to run the event17 // loop check here .18 i f ( item . i sD i sposed ( ) ) {19 unmapElement ( element , item ) ;20 return ;21 }2223 }

Listing A.131: ./org/eclipse/jface/viewers/TableTreeViewer.java

1 for ( int column = 0 ; column < columnCount | | column == 0 ; column++) {2 St r ing text = ”” ; //$NON−NLS−1$3 Image image = null ;4 i f ( tprov != null ) {5 text = tprov . getColumnText ( element , column ) ;6 image = tprov . getColumnImage ( element , column ) ;7 } else {8 i f ( column == 0) {9 ViewerLabel updateLabel = new ViewerLabel ( item .

getText ( ) ,10 item . getImage ( ) ) ;11 bu i ldLabe l ( updateLabel , element ) ;

Page 141: A Feasibility Study of Loop Bound Analysis for Loops with ...

A.2. FOR-LOOPS 137

1213 // As i t i s p o s s i b l e f o r user code to run the

event14 // loop check here .15 i f ( item . i sD i sposed ( ) ) {16 unmapElement ( element , item ) ;17 return ;18 }1920 text = updateLabel . getText ( ) ;21 image = updateLabel . getImage ( ) ;22 }23 }2425 // Avoid s e t t i n g text to nu l l26 i f ( t ext == null ) {27 text = ”” ; //$NON−NLS−1$28 }2930 t i . setText ( column , text ) ;31 // Apparently a problem to setImage to nu l l i f a l r eady nu l l32 i f ( t i . getImage ( column ) != image ) {33 t i . setImage ( column , image ) ;34 }3536 getColorAndFontCol lector ( ) . setFontsAndColors ( element ) ;37 getColorAndFontCol lector ( ) . applyFontsAndColors ( t i ) ;38 }

Listing A.132: ./org/eclipse/jface/viewers/ColumnViewer.java

1 for ( int i = 0 ; i < count | | i == 0 ; i++) {2 Widget owner = getColumnViewerOwner ( i ) ;3 i f ( owner != null && ! owner . i sD i sposed ( ) ) {4 ViewerColumn column = (ViewerColumn ) owner5 . getData (ViewerColumn .COLUMNVIEWERKEY)

;6 i f ( column != null ) {7 Edit ingSupport e = column . getEdit ingSupport ( ) ;8 // Ensure that only Edit ingSupports are wiped

that are9 // setup

10 // f o r Legacy reasons11 i f ( e != null && e . isLegacySupport ( ) ) {12 column . setEdi t ingSupport ( null ) ;13 }14 }15 }16 }

Listing A.133: ./org/eclipse/osgi/internal/resolver/StateHelperImpl.java

1 for ( int i = 0 ; i < toSort . l ength && ( hostIndex == −1 | | f rag Index ==−1) ; i++) {

2 i f ( toSort [ i ] == host )3 hostIndex = i ;4 else i f ( toSort [ i ] == fragment )5 f rag Index = i ;6 }

Listing A.134: ./org/apache/lucene/search/SloppyPhraseScorer.java

1 for ( int pos = s t a r t ; pos <= next | | ! t p sD i f f e r ; pos = pp . po s i t i o n ) {2 i f ( pos<=next && tp sD i f f e r )3 s t a r t = pos ; // advance pp to min

window4 i f ( ! pp . nextPos i t i on ( ) ) {5 done = true ; // ran out o f a term −− done

Page 142: A Feasibility Study of Loop Bound Analysis for Loops with ...

138 APPENDIX A. LOOPS USED IN THE DETAILED STUDY

6 break ;7 }8 PhrasePos i t i ons pp2 = null ;9 t p sD i f f e r = ! pp . r epea t s | | ( pp2 = te rmPos i t i on sD i f f e r (pp) )==null

;10 i f ( pp2!=null && pp2!=pp) {11 pp = f l i p (pp , pp2 ) ; // f l i p pp to pp212 }13 }