22
Problem: Efficient dynamic type checking for Java ƒ single class inheritance ƒ multiple interface inheritance ƒ array subtyping Solutions ƒ Leverage (JIT) compile-time information ƒ 3 data structures to handle common cases ƒ inline code sequences for common cases Dynamic Type Checking [JVM'01]

Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Embed Size (px)

Citation preview

Page 1: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Problem: Efficient dynamic type checking for Javaƒ single class inheritanceƒ multiple interface inheritanceƒ array subtyping

Solutionsƒ Leverage (JIT) compile-time informationƒ 3 data structures to handle common casesƒ inline code sequences for common cases

Dynamic Type Checking

[JVM'01]

Page 2: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Taxonomy of Java Types

Proper classes always extend one superclassProper classes may implement many interfacesThere are no interface valuesnull is a typeless value (for reference variables)

variable type

primitive reference

boolean

byte

short

char

int

long

float

double

proper class

java.lang.Object

interface

array of

primitive

proper class

java.lang.Object

interface

array of

primitive

proper class

java.lang.Object

interface

array of

primitive

proper class

java.lang.Object

interface

array of

primitive

proper object

java.lang.Object

interface

array of

Page 3: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Type Checking in Java

Most operations are statically typed

Some operations entail dynamic typecheckingƒ Explicit type tests (instanceof)

b instanceof A;

ƒ Down casts (checkcast)(A) b;

ƒ Interface method invocation (invokeinterface)I i = b; // I an interface typei.foo();

ƒ Exception delivery (athrow)try { . . .} catch (A a) { . . . }

ƒ Object array stores (aastore)DeclaredType [] X = ......X[3] = b;

Page 4: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

(Simplified) Jalapeño Object Model

All objects have a two word header1Type Information Block (TIB) pointer2Status word (locking, hashcode, gc, etc.)

All types (primitives, arrays, classes) have uniqueƒ VM_Type objectsƒ integer idsƒ TIBs (arrays, classes only)

TIBs are reachable from JTOC (global TOC for statics)

Page 5: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Type Information Block

Truck

V

M

T

Implements tritsElement's TIB (null)

TIB forTruck

Superclass Id display

VM_Typefor

Truck

TIB for a type is an array of ObjectsThe Virtual Method Table for the typeThree dynamic type checking data structuresThe VM_Type object for the type

Page 6: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Example Hierarchy

interface Cargo

class java.lang.Object

class DurableGood extends java.lang.Object

class Vehicle extends DurableGood

class Car extends Vehicle

class Truck extends Vehicle implements Cargo

The depth of a class is the number of its superclassesObject has depth 0DurableGood has depth 1Vehicle has depth 2Truck has depth 3

Page 7: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Testing for a Proper Class

A is known to be a proper classcheckcast and instanceof bytecodesMost significant case (along with aastore)

Superclass Identifier Display (SID) [Cohen '91]A class's display contains its type id and the type ids of its

ancestorsThe display is ordered (indexed) by their depth

Dynamic type check:Compare depth SID entry of object to type id of Aif A_depth >= minimum (6) then array bounds check required

Page 8: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Object

Durable Good

Superclass Identifier Display

Each type has a depth and a type idSID for a type is an array of shorts

Maps superclass depth to superclass type idPadded to a minimum depth with invalid ids

TruckTIB forTruck

V

M

T

1

17

88

90

0

0

SIDfor

Truck

3

90

VM_Typefor

Truck

depth

type id

Dynamic type check:l r1, TIBoffset(b)l r1, SIDoffset(r1)l r1, A_depth<<1(r1)cmpi r1, A_idbne NoMatch

Dynamic type check:l r1, TIBoffset(b)l r1, SIDoffset(r1)l r2, lengthOffset(r1)cmpi r2, A_depthbge NoMatchl r1, A_depth<<1(r1)cmpi r1, A_idbne NoMatch

Truck

Vehicle

Page 9: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Testing for an Interface

Does an object implement interface I?invokeinterface, checkcast, instanceofThree possible answers:

0 - No, 1 - Yes, 2 - Maybe (don't know yet)Monotonic: Maybe becomes Yes or No

Implements Trits Vector (Trit == 3-values)Per class cache indexed by interface id

Shared ITV's1Initial ITV - all Maybe (most classes never ask) 2If a class doesn't explicitly implement an interface then it could share its superclass's ITV

Page 10: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Implements Trits Vector

ITV for a type is a array of bytes (could use two bits with rotate/mask)No the type doesn't implement the interfaceYes the type implements the interfaceMaybe no determination has yet been made

Truck

V

M

T

TIB forTruck

VM_Typefor

Truck

ITVfor

Truck

Dynamic type check:l r1, TIBoffset(b)l r1, ITVoffset(r1)array-bounds-checkl r1, I_interfaceId(r1)cmpi r1, 1bne ResolveOrNoMatch

Cargo

Page 11: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Testing for an ArrayIs b a subtype of array type A?Dimension of a type (or value)

Number of (possible) subscripts of arrays 0 for classes and interfaces-1 for primitives

1Short-circuit type equality test: A == B ?Definitive, if A's base type is primitive or final

2If A's dimension greater than b's, no match!3If A's dimension equal to b's

Match, if, and only if,b's base type is subtype of A's base type(Special case: if A's base type is Object then match, unless b's base type is primitive)

4If A's dimension less than b'sMatch, if, and only if, A's base type is Object

Page 12: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Catching ThrowablesExplicit throws

try { . . . throw b; . . . } catch (A a) { . . . }

Implicit throws: RuntimeExceptions

null pointer, out-of-bounds, divide-by-zero, etc.JVM walks the stack looking for catch (A) to match throw (b)

Both A and B extend Throwable

Both are proper classesProper class test

b's SID[A_depth] == A_typeId Works even if A is not (yet) loaded

A_depth is 0, but A_typeId is not the type id of ObjectThe test fails (as it should since B has been loaded)

Page 13: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Object Array Stores

Array subtyping is problematicVehicle [ ] X = makeVehicleArray();Truck b = makeTruck();X[0] = b;

At compile time, Truck must be a VehicleBut, what if X is an array of Cars?

At runtime, aastore throws an ArrayStoreException

Short-circuit: array type = declared array type ?If X is Vehicle[], the compile-time test was sufficient!Declared type may be recoverable from bytecodes

Page 14: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Object Array Stores II

Vehicle [ ] X = makeVehicleArray();Truck b = makeTruck();X[0] = b;

A is runtime element type of XNot known at compile timeAcquire from Element Type TIB (ETT) slot

1Type equality short-circuitCompare TIB of b and ETT from X

2Proper-class short-circuit (1-D array of proper classes)Get the VM_Type for A from X's ETTGet A's type id and depth from its VM_TypeA_typeId == b's SID[A_depth] ?

Page 15: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Element Type TIB

ETT is the TIB for the elements of an array null for non arrays

Number of subscripts is dimension of type0 for proper objects, -1 for primitives

Truck[]

VMT

TIBfor

Truck[] 1

VM_Typefor

Truck[]

TIBfor

Truck

V

M

T

dimension

Page 16: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Basic Optimizations of Dynamic Type Checking

Constant (null) propagation (JIT compile time)(A) null always succeeds(null instanceof A) == false

Type propagation idioms (JIT compile time)Aggressive inlining uncovers opportunitiesReaching definition

B b = new A(); ...(A) b similarly for instanceof and invokeinterface

Redundant checkcast eliminationif (b instanceof A) { . . . (A) b . . . }

Page 17: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Basic Optimizations of Dynamic Type Checking

Short-circuit tests (runtime)

b is null

A == B (type equality test)

Definitive, if A is

A final proper class

An array* of primitive

An array* of a final proper class

Page 18: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Experimental EvaluationImplemented three dynamic type checking schemes in Jalapeño

1Prior Jalapeño: out-of-line type equality, cache last success2Inline TE/Cache: inlined type equality and type cache check

to approximate technique described in [Ishizaki et al.'00]inline TE/Cache check for instanceof and checkcast

3New Jalapeño

All three include same basic optimizations4final classes & null handled inline5null and type propagation6compile time folding of instanceof & checkcast

Experimental setup7AIX/PowerPC, 1 processor 604e with 768MB8Jalapeño adaptive system9copying, nongenerational garbage collector

Page 19: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Performance Impact of Dynamic Type Checking

Page 20: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Space ConsiderationsData Structures (per Type costs)

1Superclass ID Display: expected 7 (or 4) words (when depth < 6)2Implements Trits Vector:

ƒ Class does not implement any interfaces, 1 wordƒ Otherwise 4 words + Max(min ITV, largest interface ID implemented

trits)3Element Type TIB: 1 word

No data structures for aastore declared type short-circuit

Code costs highly variable

4Which sequences are inlined?5Where the sequences are inlined (be selective based on profiling)?6Some sequences are both definitive and smaller than calls to runtime

c Type equality test in restricted casesd Proper subclass using SIDe A few array cases

Page 21: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

ConclusionsSuperclass Id Display (SID)

Resolves proper class tests (normal case)Usually, in four instructionsPadded to avoid array bounds checks

Implements Trits Vector (ITV)

Resolves interface implementation tests3-valued to accommodate dynamic class loading

Element Type TIB (ETT)

Resolves some common object-array-store testsShort-circuit for object-array-store test (aastore)

Does runtime array type = declared array type?Declared type may be recoverable from bytecodesResolves large fraction of object-array-store tests

Exploit compile-time knowledge to customize dynamic type checking

Page 22: Problem: Efficient dynamic type checking for Java ƒsingle class inheritance ƒmultiple interface inheritance ƒarray subtyping Solutions ƒLeverage (JIT)

Related WorkSingle inheritance dynamic type checking

Superclass display's in Oberon [Cohen '91]Padded to 8 elements [Pfister, et. al. '91]

Imposed a maximum inheritance depth on OberonMultiple inheritance dynamic type checking

boolean TypeCheck [*, *] arrayTypeCheck[B_id, A_id] iff B is a subtype of ASpace inefficient

Subset type tests

A set of small integers is associated with each type

B is a subtype of A iff B_set A_setSet coloring algorithm [Krall, et. al. '97]

Produces space-efficient TypeCheck array

Dynamic class loading may require recomputation

Jalapeño implementation by Litvinov, no longer supported

Caching schemesCache most recent success [Ishizaki et. al.'00]