Java Program Analysis: Activation Records and Optimization, Exams of Programming Languages

Information on java program analysis, focusing on activation records and optimization. It covers topics such as the creation of activation records, optimization without recursion, and global dataflow analysis. Students can use this document as study notes, summaries, or slides for courses related to java programming, compiler design, or software engineering.

Typology: Exams

2012/2013

Uploaded on 04/02/2013

shailaja_987c
shailaja_987c 🇮🇳

4.3

(34)

217 documents

1 / 12

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS164: Midterm II
Fall 2003
Please read all instructions (including these) carefully.
Write your name, login, andcircle the time of your section.
Read each question carefully and think about what’s being asked. Ask the proctor if you
don’t understand anything about any of the questions. If you make any non-trivial as-
sumptions, state them clearly.
Some questions span multiple pages. Be sure to answer every part of each question.
You will have 1 hour and 20 minutes to work on the exam. The exam is closed book, but you
may refer to your two pages of handwritten notes.
Solutions will be graded on correctnessand clarity, so make sure your answers are neat and
coherent. Remember that if we can’t read it, it’s wrong!
Each question has a relatively simple and straightforward solution. We will deduct points
if your solution is far more complicated than necessary. Partial answers will be graded for
partial credit.
Write all of your answers in the space provided on the exam, and clearly mark your answers.
Use the backs of the exam pages for scratch work. Do not use any extra scratch paper. Do
not unstaple the exam.
Turn off your cell phone.
Good luck!
NAME and LOGIN:
Your SSN or Student ID:
Circle the time of your section: 9:00 10:00 11:00 2:00 3:00
Q1 (30 points) Q2 (35 points) Q3 (20 points) Q4 (15 points) Total(100 points)
1
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Java Program Analysis: Activation Records and Optimization and more Exams Programming Languages in PDF only on Docsity!

CS164: Midterm II

Fall 2003

  • Please read all instructions (including these) carefully.
  • Write your name, login, and circle the time of your section.
  • Read each question carefully and think about what’s being asked. Ask the proctor if you don’t understand anything about any of the questions. If you make any non-trivial as- sumptions, state them clearly.
  • Some questions span multiple pages. Be sure to answer every part of each question.
  • You will have 1 hour and 20 minutes to work on the exam. The exam is closed book, but you may refer to your two pages of handwritten notes.
  • Solutions will be graded on correctness and clarity , so make sure your answers are neat and coherent. Remember that if we can’t read it, it’s wrong!
  • Each question has a relatively simple and straightforward solution. We will deduct points if your solution is far more complicated than necessary. Partial answers will be graded for partial credit.
  • Write all of your answers in the space provided on the exam, and clearly mark your answers. Use the backs of the exam pages for scratch work. Do not use any extra scratch paper. Do not unstaple the exam.
  • Turn off your cell phone.
  • Good luck!

NAME and LOGIN:

Your SSN or Student ID:

Circle the time of your section: 9:00 10:00 11:00 2:00 3:

Q1 (30 points) Q2 (35 points) Q3 (20 points) Q4 (15 points) Total (100 points)

1 Activation Records (30 points)

Consider the Java program on the following page:

  • (3 points) What is the output of the program?
  • (8 points) Draw the procedure-call stack at the point when the execution reaches the call to println (i.e., before the arguments to println are pushed on the stack). Draw on the following page. - Show, in detail, the content of each activation record (you don’t need to show where the args argument of main() points to). Assume that arguments are pushed on the stack in reverse order (i.e., the first argument is pushed last). - Show the boundaries of each activation record. - For one activation record, show (i) which part of the activation record is created by the caller, (ii) which by the callee; and (iii) which could be created by either, depending on the calling convention. - Indicate where sp and fp registers point to when the execution stops at the call to println (assume that sp points to the top of the stack, as in x86). - Show where all control links point to (the control link is a pointer to the previous acti- vation record). - Show where all return addresses point to (make them point to the Java source code).
  • (5 points) The fp register has been introduced into processors to simplify code generation of accesses to the activation record. Question: In theory, the sp register could be used for this purpose. Why is it easier to use the fp register than the sp register? Answer this question by stating what information you would have to maintain during code generation to use sp for accessing the activation record.

Optimizing the activation records. Assume that we restrict SkimDecaf and require that the pro- grammer cannot write programs with recursion (i.e., procedures cannot call themselves, directly or indirectly through other procedures). (Recall also that SkimDecaf supports only static methods.) While some interesting programs (e.g., recursive graph traversals) cannot be written in such a restricted language, the language allows generating a more efficient code. Here’s why:

  • (6 points) One optimization is based on the observation that, without recursion, at any point of execution, each method can be active at most once. Hence, at any given moment, there is at most one active activation record for each procedure. This observation simplifies the implementation of activation records: because there is at most one copy of local variables and actual arguments for each procedure, they need not be stored on the stack; instead, they can be stored in static (global) memory at a fixed location. The benefit of this optimization is that there is less pushing and popping from the stack. Question: Which of the following are not needed when each procedure uses only one ac- tivation record that is located in a fixed memory location? Why are they still/no longer needed? - control link (i.e., the saved frame pointer) - return address.
  • (8 points) In order to perform the above optimization, the compiler must verify that the programmer indeed did not use recursion (direct or indirect). Give a (simple) algorithm that your SkimDecaf compiler could use to detect the presence of recursion in the program. Your approach should perform a simple traversal of the AST representation of the program. Feel free to extend the AST as necessary; if you do, state clearly what links and/or nodes you added to the AST.

2 Global Dataflow Analysis. (35 points)

Uninitialized Variables. A programming language may want to guarantee that each local vari- able is initialized (typically to zero or null) by the compiler when it is declared. To provide this guarantee, a compiler for such a language must generate statements that initialize the variables.

Because initialization statements are costly, some languages (e.g., C) do not initialize variables. In- stead, they assume that assigning a value to a variable before its first use is the responsibility of the programmer. To help the programmer find missing initializations, compilers for such languages analyze the program and tell the programmer when an expression uses a potentially uninitialized variable.

How do compilers determine if a statement, say z := x + y, uses an uninitialized variable? They use the following rule: x is potentially uninitialized in that statement if there is a path, in the CFG, from the beginning of the method to the statement such that the path does not contain an assignment into x. Same rule applies to y.

For example, in the statement z = x + y below, x is potentially uninitialized but y is initialized.

static void f (int a) { int x, y, z; y = 1; if (a > 0) { x = 1; } z = x + y; }

Computing the solution of the dataflow analysis. Many algorithms for performing dataflow analysis exist. The simple algorithm that we covered in class is iterative : It first initializes the solu- tion of the analysis and then iteratively applies rules until the solution does not change.

Here are iteration rules for computing whether a variable x is uninitialized. As in the lecture, the solution is denoted as I(p, x, in/out). The solution I(...) is true if x is always initialized when the program reaches entry/exit of statement p. The solution is false if x may be un initialized when the program reaches entry/exit of statement p.

So, again: true means always initialized and false means maybe un initialized.

The following rules roughly correspond to the Rules 1–4 of liveness analysis (there are important differences, though).

  1. I(p, x, in) := ∧ {I(s, x, out) | s is a predecessor of p in the CFG} This rules describes how information is propagated across CFG edges (and hence also how it is merged when CFG edges meet). The following rules describe how CFG nodes are handled.
  2. I(start, x, in) := false , where start is the first statement of the method. This rule says that all variables are assumed to be uninitialized on the entry point of the method.
  3. I(p, x, out) := true if x is assigned in node p. This rule says that x is initialized on the exit of its assignment.
  4. I(p, x, out) := I(p, x, in) if p does not assign x. This rule says that statements that do not assign x do not affect the solution; they merely propagate the information on whether x is initialized.
  • (3 points) Do these rules describe a forward or a backward analysis? Explain why.
  • (4 points) Explain why Rule 1 uses the logical and rather than the logical or ).
  • (6 points) The rules above describe the entire algorithm; the only missing part is how the I(...) values should be initialized before the rules are applied. (The initial solution can be set either to true or to false .) In order to determine which of the two is the correct initialization, analyze variable x in the program below twice, once initializing I(...) to true , once initializing to false. It is sufficient if you show the final solutions for x. You do not need to (but may) show the results of individual rule applications.

x = 0; y = 1; while ( f(x) ) { y = y + 1; } z = x + y;

Draw two separate CFGs for the program, one for each analysis.

  • (3 points) What is the correct way to initialize the solutions?
  • (4 points) (a) Explain why incorrect initialization produced an imprecise result. (b) Is this imprecise result of the kind you’d prefer (see the question at the bottom of page 6).

3 Typechecking. (20 points)

You are given three pairs of similar typing rules (two pairs appear on this page, and one pair appears on the following page), and in each pair one rule is correct and the other incorrect. For each pair:

  • (6 points) Identify which rule is correct and which is incorrect.
  • (6 points) Say whether the incorrect rule affects soundness (allows unsafe programs to pass) or completeness (does not type check programs that are clearly type safe; that is, restricts the programmer), or both.
  • (8 points) Give an example program that exposes the problem with the incorrect rule.

Assume that there is subtyping for the final pair of rules, and that there is no subtyping for the first two pairs.

O  e 1 : int O  e 2 : int O  e 1 + e 2 : int

O  e 1 : int O  e 1 + e 2 : int

O  e 0 : int O[T 0 /x]  e 1 : T 1 O  T 0 x = e 0 ; e 1 : T 1

O  e 0 : T 0 O[T 0 /x]  e 1 : T 1 O  T 0 x = e 0 ; e 1 : T 1

O, M  e 0 : T 0 O, M  e 1 : T 1

... O, M  en : Tn M (T 0 , f ) = (T 1 ′, T 2 ′,... , T (^) n′, Tr ) Ti = T (^) i′ (for 1 ≤ i ≤ n) O, M  e 0 .f (e 1 ,... , en) : Tr

O, M  e 0 : T 0 O, M  e 1 : T 1

... O, M  en : Tn M (T 0 , f ) = (T 1 ′, T 2 ′,... , T (^) n′, Tr ) Ti ≤ T (^) i′ (for 1 ≤ i ≤ n) O, M  e 0 .f (e 1 ,... , en) : Tr