1 java subtype tests in real-time krzysztof palacz, jan vitek university of purdue presented by:...

24
1 Java Subtype Tests in Real- Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

Post on 21-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

1

Java Subtype Tests in Real-Time

Krzysztof Palacz, Jan VitekUniversity of PurduePresented by: Itay Maman

Page 2: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

2

Outline

Subtyping tests Previous work R&B Overview Ranges (SI test) Buckets (MI test) Results Conclusions & Future Research

Page 3: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

3

Given a hierarchy (T,≺) T is a set of types ≺ is a partial order over T (reflexive, transitive and anti-

symmetric) called subtype relation The query c ≺ p is a subtype test In the above test, C is the Client type, while P is the Provider

type Java:

Class inheritance test (“extends”) is an SI subtype test Interface inheritance test (“implements”) is an MI subtype

test

Subtyping tests

Does a type extend a given class?Does a type implement a given interface?

Page 4: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

4

Subtyping tests - Requirements

Queries must run in constant time Space overhead must not significantly increase

system footprint Size of emitted code Memory needed for the data structure

Support for dynamic loading of classes Ideally, should be able to load a class without blocking

concurrent subtype queries, invoked by other threads

Page 5: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

5

Naïve solution

subtypeOf(type_info cl, type_info pr) { if(cl == pr || cl.cache == pr) return true; if(pr.isInterface return implements(cl, pr); else return extends(cl, pr);}

implements(type_info cl, type_info pr) { for(int i = 0; i < pr.interfaces.length; ++i) if(cl == pr.interfaces[i]) { cl.cache = pr; return true; } return false; }

extends(type_info cl, type_info pr) { for(type_info t = cl.parent; t != null; t = t.parent) if(t == pr) { cl.cache = pr; return true; } return false; }

Page 6: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

6

Previous Work

SI (single inheritance) hierarchies Bit matrix – Space inefficient Relative numbering [Schubert ’83] Cohen's algorithm [Cohen ’91]

MI (multiple inheritance) hierarchies Packed Encoding (PE) - generalization of Cohen's algorithm

[Krall, Vitek and Horspool ’97] Bit-vectors [Krall, Vitek and Horspool ’97a] PQ Encoding – Adapts Relative numbering to MI [Zibin, Gil ’01]

Incremental technique in production JVMs (HotSpot, Jalapeno)

SI: Cohen’s algorithm with arrays of a fixed size (inlined) MI: Linear search over a list of displays

Page 7: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

7

Ranges (SI test): The basics

Based on Scubert’s technique1) Ranges of children are subranges of their

parents’2) Ranges of siblings are disjoint

Range assignment: Via a pre-order walk c ≺ p p.low ≤ c.low < p.high[0,8]

A

B

D

C

E F

[4,7]

[6,0][5,0]

[1,3]

[2,0]

Page 8: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

8

Only the low bound is observed for the client A leaf type can reuse its parent’s low bound

Ranges (SI test): Refinements

Reminder: c ≺ p p.low ≤ c.low < p.high

insert(type_info t) {

t.high = 0;

t.low = (t.parent == null) ? 1 : t.parent.low;

}

The high bound can be calculated on-demand.When a type is loaded it is initialized with 0

Conclusion:

Page 9: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

9

Ranges (SI test): extends()

extends() implements an SI test If the provider’s high bound is not present,

its value is computed by invoking promote()

extends(type_info cl, type_info pr) { if(pr.low <= cl.low && cl.low < pr.high)

return true;

if(pr.high != 0)

return false;

promote(pr);

return (pr.low <= cl.low && cl.low < pr.high);

}

Page 10: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

10

Steps for computing range assignments: Step 1. Place all type_info items in an

array using a pre-order walk Leaf types are stored once Non-leaves are stored twice: once before all their

subtypes, and once after

Ranges (SI test): promote(), 1/3

ABDBCEFCA

012345678

type_info:

A

B

D

C

E F

Page 11: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

11

order:

Step 2. Perform a left-to-right iteration over the array. Compute order[i] for each index

Start with 1 Increase whenever a non-leaf type is encountered

Ranges (SI test): promote(), 2/3

A

B

D

C

E F

ABDBCEFCA

012345678

122344456

type_info:

Page 12: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

12

[1,6]

Perform a right-to-left iteration over the array (end to beginning)

Right position of a non-leaf type: assign order[i] to its high bound

Left position of a non-leaf type: assign order[i] to its low bound

Leaf type: assign order[i] to its low boundorder:

Ranges (SI test): promote(), 3/3

ABDBCEFCA

012345678

122344456

type_info:

A

B

D

C

E FA.h = 6

C.h = 5

F.l = 4

E.l = 4B.h = 3

C.l = 4D.l = 2

B.l = 2

A.l = 1

[4,0] [4,0][2,0]

[4,5][2,3]

Page 13: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

13

Given the following properties of the promote() algorithm… A type’s high bound is updated before its subtypes are

processed A type’s high bound is updated before its low bound Sibling types are processed on a descending order of their low

bounds

… It is guaranteed that the invariants of Scubert’s technique

are kept at any given point during its operation:1) Ranges of children are subranges of their parents’2) Ranges of siblings are disjoint

Ranges (SI test): Thread-safety

Promote() is thread-safeConclusion:

Page 14: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

14

Low, constant memory demands (32 bits per class)

Query time Is constant in vast majority of the tests In RT systems, promote() can be used eagerly (invoked

on class load), to ensure constant query time

Code is thread-safe => can handle dynamically loaded classes. No need to “stop the world”

Performance improvement of: ** ??? **

Ranges (SI test): Summary

Page 15: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

15

Buckets (MI test): The basics

Based on the Packed-Encoding algorithm (PE)

Each interface is assigned to a bucket, and receives a unique id (iid) within that bucket

Two interfaces in a bucket do not have a common subtype

c ≺ p c.display[p.bucket] == p.iidtype_info { …

byte[] display; }

interface_info {

byte iid;

byte bucket; }

Page 16: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

16

Buckets (MI test): assignment 1/3

Computing bucket assignments: Case 1. Loading an interface.

If all buckets are full or no bucket exists, create a new bucket

Choose the bucket with the fewest interfaces among ‘M’ most recently created buckets. (Typically, M = 5)

Create a new iid value for the interface, which is unique within the bucket.

A bucket cannot reuse ‘old’ (i.e: previously used) iid-s

Page 17: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

17

Buckets (MI test): assignment 2/3

Case 2. Loading a class. If the interfaces implemented by the class are of

different buckets, initialize the array of displays:cl.display[i.bucket] = i.iid;

// for each implemented interface i Otherwise, the class is a subtype of (at least)

two interfaces of the same bucket. These interfaces must be reassigned to other buckets

(Details on the next slide)

Page 18: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

18

Case 2 contd. Loading a class/Reassignment1) For each bucket b, with k interfaces implemented by a class C:

a) Create k-1 new bucketsb) k-1 interfaces are assigned to the new bucketsc) Remaining interfaces from b are evenly spread among b and the new

buckets

An interface’s iid is not changed when the interface is reassigned A bucket cannot reuse an iid of an interfaces that was reassigned

2) Iterate over all loaded classes and update their display[] array: Existing entries remain unchanged New entries are added for the new buckets Consequently, in a given class’s display[] an iid of the same interface

may appear more than once.

3) Iterate over all reassigned interfaces, update their bucket value

Buckets (MI test): assignment 3/3

Page 19: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

19

Buckets (MI test): Thread-safety

Given the following properties of the Buckets algorithm…

An interface never changes its iid A bucket cannot reuse an ‘old’ iid Updated display[] arrays contain the old entries as well as

the new ones An interface’s bucket value is changed only after display[]

s are updated

… It is guaranteed that an implements() query will always yield the correct result

Page 20: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

20

The END

Page 21: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

21

Definitions

≺d is the transitive reduction of ≺ ≺ is the transitive closure of ≺d

Formally, a ≺d b iff a ≺ b and there is no c such that

a ≺ c ≺ b, a≠c≠b. Also,

ancestors(a)≡{b∈T| a ≺ b}, descendants(a)≡{b∈T| b ≺ a} parents(a)≡{b∈T| a ≺d b}, children(a)≡{b∈T| b ≺d a} roots≡{a∈T| parents(a)=∅}, leaves≡{a∈T| children(a)=∅} level(a)≡1+max{level(b)| b∈parents(a)}

Single inheritance (SI) vs. multiple inheritance (MI) In SI, for each a∈T, |parents(a)|≤1

Page 22: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

22

Cohen's algorithm

Partition the hierarchy into levels a ≺ b lb ≤ la and ra[lb] = idb

lb is level(b), idb is a unique identifier within the level

4 53

1

21

1 2 3

1

134

3113

3112

3111

3

1321

22112

1idr[1 ]

lr[l]

...

135

3

A

B C D

E F G H I

Page 23: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

23

Range compression

Apply postorder on some spanning forest a ≺ b lb[i] ≤ ida ≤ rb[i] , for some i

9

3 6 8

5 721

4[1 ,6 ] [1 ,3 ],[5 ,9 ]

[1 ,3 ] [2 ,2 ],[5 ,6 ] [5 ,5 ],[7 ,8 ]

[1 ,1 ] [2 ,2 ] [5 ,5 ] [7 ,7 ]

id

[l1 ,r1 ],[l2 ,r2 ],...

A B

C D E

F G H I

{2,5,6}{1,2,3}

Page 24: 1 Java Subtype Tests in Real-Time Krzysztof Palacz, Jan Vitek University of Purdue Presented by: Itay Maman

24

Ranges (SI test): promote()

Computes range assignments: Place all types in an array using a pre-order walk

Leaf types are stored once Non-leaves are stored twice: once before all their subtypes, and

once after Perform a left-to-right iteration over the array.

Compute order[i] for each index Start with 1 Increase whenever a non-leaf type is encountered

Perform a right-to-left iteration over the array (end to beginning)

Leaf type: assign (order[i], 0) to (low, high) Right position of a non-leaf type: assign order[i] to its high

bound Left position of a non-leaf type: assign order[i] to its low bound