CS164: Midterm Exam 2

Similar documents
CS164: Final Exam. Fall 2003

CS164: Midterm I. Fall 2003

CS164: Programming Assignment 5 Decaf Semantic Analysis and Code Generation

CS143 Final Fall 2009

CSE351 Winter 2016, Final Examination March 16, 2016

Midterm II CS164, Spring 2006

More Dataflow Analysis

Semantic Analysis and Type Checking

CSE351 Spring 2018, Final Exam June 6, 2018

Midterm I - Solution CS164, Spring 2014

CS 10, Fall 2015, Professor Prasad Jayanti

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CMSC330 Spring 2015 Midterm #1 9:30am/11:00am/12:30pm

Midterm Exam. CS169 Fall November 17, 2009 LOGIN: NAME: SID: Problem Max Points Points TOTAL 100

INSTRUCTIONS TO CANDIDATES

The first program: Little Crab

Global Optimization. Lecture Outline. Global flow analysis. Global constant propagation. Liveness analysis. Local Optimization. Global Optimization

1 Inheritance (8 minutes, 9 points)

Computer Architecture I Midterm I

CIS 341 Final Examination 4 May 2017

Midterm I (Solutions) CS164, Spring 2002

CMSC330 Spring 2015 Midterm #1 9:30am/11:00am/12:30pm

First Midterm Exam CS164, Fall 2007 Oct 2, 2007

CS107 Handout 37 Spring 2007 May 25, 2007 Introduction to Inheritance

MARKING KEY The University of British Columbia MARKING KEY Computer Science 260 Midterm #2 Examination 12:30 noon, Thursday, March 15, 2012

CIS 110 Introduction To Computer Programming. February 29, 2012 Midterm

Compiler Design Prof. Y. N. Srikant Department of Computer Science and Automation Indian Institute of Science, Bangalore

CSE344 Midterm Exam Winter 2017

CS Exam 1 Review Suggestions

COMP 401 Midterm. Tuesday, Oct 18, pm-3:15pm. Instructions

CS 455 Midterm Exam 1 Spring 2015 [Bono] Thursday, Feb. 19, 2015

CSE 401 Final Exam. March 14, 2017 Happy π Day! (3/14) This exam is closed book, closed notes, closed electronics, closed neighbors, open mind,...

Final Exam CS164, Fall 2007 Dec 18, 2007

CS143 Final Spring 2016

CS 455 Midterm Exam 1 Fall 2013 [Bono] Wednesday, Oct. 2, 2013

CS 455 Midterm Exam 1 Fall 2016 [Bono] Thursday, Sept. 29, 2016

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CSCI-1200 Data Structures Fall 2012 Lecture 5 Pointers, Arrays, Pointer Arithmetic

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

CS558 Programming Languages Winter 2013 Lecture 8

ECS 140A Midterm 2 November 19, Name (Last, First):, Sign your name:

CS 3L (Clancy) Solutions and grading standards for exam 1

Qualifying Exam Languages

Type Checking in COOL (II) Lecture 10

Software Design and Analysis for Engineers

CS 2110 AEW SIGN UP FOR 1 CREDIT S/U COURSE!!!

CSE331 Autumn 2011 Midterm Examination October 28, 2011

CS 320 Midterm Exam Solution

CS 151 Midterm. Instructions: Student ID. (Last Name) (First Name) Signature

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

Applied Information and Communication Technology

CS 320 Midterm Exam. Fall 2018

CSCI-1200 Data Structures Spring 2017 Lecture 5 Pointers, Arrays, Pointer Arithmetic

CSE 401 Final Exam. December 16, 2010

Introduction to C++ Introduction to C++ Dr Alex Martin 2013 Slide 1

CS164 First Midterm Exam Fall 2014

8 Understanding Subtyping

XC Total Max Score Grader

CS 455 Final Exam Fall 2016 [Bono] December 13, 2016

(Refer Slide Time 6:48)

(the bubble footer is automatically inserted into this space)

Object-Oriented Design Lecture 14 CSU 370 Fall 2007 (Pucella) Friday, Nov 2, 2007

Making Inheritance Work: C++ Issues

Making Inheritance Work: C++ Issues

CS 61B, Midterm #3 and solutions, Spring 1996

REFERENCES, POINTERS AND STRUCTS

Pointers. 1 Background. 1.1 Variables and Memory. 1.2 Motivating Pointers Massachusetts Institute of Technology

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

CSE 143 Lecture 12 Inheritance

CMSC 330 Exam #2 Fall 2008

CIS 130 Exam #2 Review Suggestions

CS 2110 AEW. Machine Language. Outline. Assembly Language. High-Level Language 1/26/2012

CSCI 355 LAB #2 Spring 2004

Project 5 Due 11:59:59pm Tuesday, April 25, 2017

Lab 4 - Linked Lists

CSE030 Fall 2012 Final Exam Friday, December 14, PM

CS 1301 Exam 1 Fall 2010

Prelim 2. CS 2110, November 20, 2014, 7:30 PM Extra Total Question True/False Short Answer

Midterm Exam (REGULAR SECTION)

Week 7. Statically-typed OO languages: C++ Closer look at subtyping

Computer Science Foundation Exam

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #44. Multidimensional Array and pointers

University of California, Berkeley College of Engineering

University of Utah School of Computing

CSCI 3155: Principles of Programming Languages Exercise sheet #12 26 June 2007

CS61BL Summer 2013 Midterm 2

INHERITANCE. Spring 2019

Midterm Exam 2 CS 455, Spring 2011

Logistics. Final Exam on Friday at 3pm in CHEM 102

CSE P 501 Exam 8/5/04

2. You are required to enter a password of up to 100 characters. The characters must be lower ASCII, printing characters.

Discrete Mathematics and Probability Theory Fall 2015 Rao Midterm 1

Programming Project 4: COOL Code Generation

CS 455 Final Exam Spring 2018 [Bono] May 8, 2018

CIS 110 Introduction to Computer Programming. February 29, 2012 Midterm

Goals of Program Optimization (1 of 2)

Comp 11 Lectures. Mike Shah. June 26, Tufts University. Mike Shah (Tufts University) Comp 11 Lectures June 26, / 57

CS32 Midterm Exam E01, F15, Phill Conrad, UC Santa Barbara Wednesday, 10/28/2015, 11am 12:15pm

CSCI0330 Intro Computer Systems Doeppner. Lab 02 - Tools Lab. Due: Sunday, September 23, 2018 at 6:00 PM. 1 Introduction 0.

ENCM 369 Winter 2017 Lab 3 for the Week of January 30

Transcription:

CS164: Midterm Exam 2 Fall 2004 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 assumptions, state them clearly. You will have 1 hours and 20 minutes to work on the exam. The exam is closed book, but you may refer to your one page 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. Turn off your cell phone. Good luck! NAME and LOGIN: Your SSN or Student ID: Circle the time of your section: 10:00 11:00 2:00 4:00 Q1 (50 points) Q2 (50 points) Total (100 points) 1

1 Dataflow analysis This question asks you to develop a simple dataflow analysis that can be used to optimize Decaf programs be removing from them unnecessary null checks. Background. Because dereferencing a null pointer crashes the program, in Decaf, a run-time check ensures that a null pointer is never dereferenced. This check takes place just before the pointer is dereferenced using the. operator. For example, the statement p.f(); might be translated by the compiler to if (p == null) print_error_and_exit(); p.f(); The null checks can be costly, but luckily we can optimize some of them away. Specifically, a check can be safely removed if the compiler can guarantee that the pointer being dereferenced will not be null for any program input. The problem. In this problem, you will develop a dataflow analysis to identify such redundant checks, so that they can be eliminated by the compiler. In particular, for every pointer dereference, you want to know whether the variable being dereferenced may be null; if it may not, then you can eliminate the null check. Simplifications. In order to simplify the analysis, you can make the following assumptions: Assume that the method that you arr going to analyze has only three local variables named x, y, z. These variables are initialized to null. All three variables are of type B, where B is a class defined as follows class B { void foo(); B moo(); The return value of moo can be either a null pointer or a valid pointer. Within a basic block, the only valid statements are an assignment into a local variable and a method call (like z.foo();). The right hand side of an assignment can be any of the following: A method call (like z.moo()), new B(), Another variable, null. 2

The questions. 1. (4 points) Give a program with 3 statements or less where the null-check is unnecessary, and explain why it is unnecessary. (Make sure your example uses only the language constructs listed on the previous page.) Answer: a.foo(); a.foo(); The null-check is unnecessary on the second call to foo. B b = new B(); b.foo(); The null check is unnecssary because we know that b is not null. 2. (4 points) Dataflow analysis can be classified as either forward or backward. Is your analysis going to be forward or backward? Explain why. Answer: Forward. We want to base our decision on eliminating the null-check or not by looking at the instructions executed prior to this point. 3. (5 points) As mentioned earlier, your goal is to find, for all pointer dereference expressions, whether the pointer may be null. Give the values that the analysis will use to represent the fact that the pointer is (is not) null. Give the meaning of these values. (Hint: recall that in Liveness analysis we used two such values for each variable: x is live and x is not live. Recall how we defined their meaning.) Answer: null: the variable may be null not null: the variable must not be null 4. (3 points) What is the ordering of these two values (for now, assume that you are analyzing each variable independently). Answer: notnull < null 5. (4 points) Assume now that you want to do the analysis for all three variables simultaneously. With this in mind, define the lattice you will use for the dataflow analysis (i.e. show the values that you are going to be assigning to program points, and the ordering you are going to impose on them). This question was annulled, but the lattice would consist of triples, (vx, vy, vz) where each term vx,vy and vz would be either null or notnull, depending on whether variables x,y or z are null or not null. The order would be defined as follows: (vx, vy, vz) (vx, vy, vz ) iff (vx vx and vy vy and vz vz ). 3

6. (12 points) If you are using a forward analysis, specify for each of the following statements how the value at program point B is computed given the value at the program point A (i.e. how do you decide what variables may be null at B given what you know about the variables at A). If you are using a backward analysis, specify how you are going to compute the value at program point A from the value at program point B. Your analysis should not be overly conservative. You can assume you are analyzing each variable separately. (A) (A) (A) (A) x = null; x = new B(); x = y; x = y.moo(); (B) (B) (B) (B) (hint: If y were null, you would never reach point (B)) Ans: Ans: Ans: Ans: x is null at (B) x is notnull at (B) x at (B) is whatever x is null at B y and z are the same as y and z remain the same y was at (A). y is notnull at B at (A) y and z remain the z remains the same. same. 7. (4 points) How are you going to handle join points (or split points if you are doing a backward analysis)? In particular, if you have two different values coming into a join point from two different edges, how are you going to define the value for the join point? Take the least upper bound (Which in this case is the same as the maximum) of all branches for each variable. i.e. if any branch is null, the value of the join point is null. 8. (4 points) What value are you going to initialize all program points too? What about the entry point (or the exit point if you are running a backward analysis)? You must initialize all internal program points to notnull. Otherwise the analysis will be overly conservative. The entry point has to be initialized to null, since you were told all variables start out null. 4

9. (10 points) Run your data-flow analysis on the graph given below, and fill out the two tables provided. 1 2 x = new B(); y = x; 9 7 4 5 3 y.foo(); //(A) z = y; y = x.moo(); //(B) 8 x = z.moo(); //(C) 6 10 x.foo(); 11 12 //(D) Program point Analysis value 1 x,y,z=null,null,null 2 notnull,null,null 3 null,null,null 4 null,notnull,null 5 null,notnull,notnull 6 notnull,null,notnull 7 notnull,null,notnull 8 notnull,null,notnull 9 null,null,notnull 10 null,null,notnull 11 null,null,notnull 12 notnull,null,notnull Pointer Dereference (A) (B) (C) (D) safe to remove the check? (Yes/No) NO NO YES NO 5

2 Run-time Organization for Interfaces This question asks you to extend Decaf with Java-style interfaces. Your main goal is to design dispatch tables needed to support interface calls, which are analogous to virtual calls. Background. If you are not familiar with Java interfaces, don t despair. We will introduce the running example with sufficient background so that you can solve this problem. First, you need to know that the goal of Java interfaces is to provide a limited form of multiple inheritance. This is how multiple inheritance works in Java: each Java class extends exactly one class and implements zero or more interfaces. (The only exception is the special class Object.) Now, what is an interface? For the purpose of this question (we simplify Java somewhat), a Java interface is simply a class whose members are all abstract methods. Also, what does it mean to implement an interface? A class C is said to implement an interface I when C implements (that is, defines bodies of) all methods of I. Example. The simple example below defines two interfaces (IK and IM) and three classes that implement (some) of the two interfaces. Notice that class C doesn t itself define method m, yet it is considered to implement the interface IM. Make sure you understand why this is so. public interface IK { abstract public void k(); public interface IM { abstract public void m(); public class A implements IK, IM { public void k() { System.out.println("A:k"); public void m() { System.out.println("A:m"); public class B implements IK { public void k() { System.out.println("B:k"); public void m() { System.out.println("B:m"); public class C extends B implements IM { public void k() { System.out.println("C:k"); 6

Interface references. To make use of interfaces, Java introduces interface reference variables, which are like object reference variables, except that an interface variable of type I is allowed to point to objects of any type T such that the class T implements the interface I. For example, the interface reference variable t of type IM (introduced above) is allowed to point to an object of type A or C but not of type B, even though B happens to contain a method m(): IM t; t = new A(); // LEGAL t = new B(); // ILLEGAL (even though B contains method m) t = new C(); // LEGAL t.m(); t.k(); // LEGAL // ILLEGAL (even though t is guaranteed to point // to an object with method k) Compiling interfaces. Compiling Java interfaces boils down to supporting a new kind of method call t.m(), named interface method call. To the programmer, this call behaves like the virtual method call used to invoke instance methods, except that the object on which you invoke the method m comes from an interface reference variable t, as opposed to from an object reference variable. Example (continued). The code below makes both kinds of calls. B b; // b can point to any object of type B or subclass of B IK ik; // ik can point to any object that implements interface IK if (x==1) { b = new B(); ik = new A(); else { b = new C(); ik = new C(); b.k(); // virtual call ik.k(); // interface call When x==1, the program outputs B:k A:k Turn over. 7

The questions. 1. (3 points) What output does the example print when x!=1? C:k C:k 2. (3 points) In the table below, indicate for each class which interfaces it implements. Note that a class is considered to implement an interface if its superclass implements the interface. It may help if you draw the class hierarchy in which you show with edges which class implements which interfaces. class A B C implemented interfaces IK, IM IK IK, IM 3. (3 point) In the table below, indicate which methods can be invoked on a reference variable of a particular static type. For example, list method m in column A if the following code is legal: A a;...; a.m(); static type A B C IK IM methods that can be invoked k, m k, m k, m k m 4. (3 point) What types of objects can b and ik point to at run time? call statement b.k() virtual call ik.k() interface call dynamic types of the object B, C A, C 5. (4 point) Looking at the immediately preceding table, what is the property that the types of the virtual call have that the types of the interface call don t? C is a subclass of B. (A is not a subclass of C. C is not a subclass of A.) 8

6. (6 points) The figures below show the (traditional) dispatch tables for two executions of the example (left: x = 1; right: x 1). These dispatch tables are used in virtual calls. From these two figures, it appears that virtual dispatch tables can be used to correctly implement interface calls. However, this impression is incorrect. To show why virtual dispatch tables are insufficient, modify our running example (given on pages 6 and 7) so that the dispatch tables don t work in interface calls. Write your modification in the blank space below. To reflect your modification to the example, modify also the dispatch tables shown below. Answer. Code modification: add a method called j() as the first method in class B. As a result of the code modification, the dispatch table pointed to by the object of type C now contains three pointers (to methods B:j, C:k, and B:m, in this order). We are assuming here that the compiler places methods in the dispatch table in the order they are given in the class. 7. (4 points) Explain (concisely) the reason why interface method calls cannot rely on the traditional dispatch tables to decide which method to invoke. Answer: The reason is that methods that can be invoked in a particular interface call may belong to classes unrelated by inheritance, and thus these methods are not in general placed by the compiler at the same ofset in dispatch tables of their classes. This mismatch of offsets prevents the use of the efficient dynamic dispatch, which relies on the called method being placed at the same offset in all dispatch tables that may be used by the call. For example, in the call ik.k(), we may invoke methods A:k and B:k. These methods are unrelated by inheritance (i.e., the first doesn t override the other or vice versa), and hence may be placed by the compiler at different offsets. 9

Questions on this page will take you some time. 8. (14 points) Design run-time support for interface calls. Note that the new run-time support need not look like a dispatch table at all. What you need to draw: Using the running example above, show the data structures that your compiler would generate to perform the dispatch at an interface call. Note: To earn full credit, the space requirements of your run-time data structures must not be a function of the number of interfaces in the entire program, only a function of how many interfaces a class implements. Simplifications. (1) Assume interfaces cannot extend each other (as they can in Java). (2) Assume the program is completely available prior to the execution, as in Decaf (in contrast, in Java, classes are loaded and compiled during the execution). 9. (5 points) If your solution stores pointers (to methods or tables) in an array, give your rules for determining the index in the array where the pointer will be stored. (An example of a rule: in the case of traditional virtual dispatch tables, the rule is that the pointer to a method f is (a) placed at the same offset in the dispatch tables of all classes related by inheritance; and (b) the methods of a subclass are placed immediately below the offset of the superclass.) 10. (5 points) Show the code that your compiler would generate at an interface call. Use a pseudo-code, not an assembler. Your code should assume the run-time data structures you designed above. Answer: First, we give a solution that s space-inefficient but good enough for a significant partial credit. The idea is to implement an interface dispatch table (IDT). The IDT is nothing more than a 3-dimensional array D[c, i, m] that is looked up at the time of the call. There is one copy of D for the entire program. The three indexes into the array are (i) c: object s dynamic type, i.e., the class id obtained from the object header; (ii) i: the interface id, determined at compile time from the static type of the variable (e.g., in ik.k(), the interface is K, which is the static type of ik); and (iii) m: a unique method id. The code generated by the compiler for the call ik.foo() may look as follows: c = ik.dynamictype; target = D[c,K,foo]; call [target]; % load type from object s header % lookup the IDT, K and foo are compile-time constants To meet the space restrictions requirements, we need to represent the IDT more compactly than a 3-D array. One simple solution that would give you full credit is to make the IDT a 1-D array, called D and store in the D [c] a hash map that maps each (i, m) pair to D[c, i, m]. The generated code may look as follows: c = ik.dynamictype; % load type from object s header map = D [c]; target = map.get(k,foo); call [target]; 10