Redings for Next Two Lectures Text CPSC 213 Switch Sttements, Understnding Pointers - 2nd ed: 3.6.7, 3.10-1st ed: 3.6.6, 3.11 Introduction to Computer Systems Unit 1f Dynmic Control Flow Polymorphism nd Switch Sttements 1 Bck to Procedure Clls 2 Sttic Method Invoctions nd Procedure Clls Polymorphism trget method/procedure ddress is known stticlly in Jv sttic methods re clss methods - invoked by nming the clss, not n object public clss A { sttic () { public clss Foo { sttic foo () { A. (); in C specify procedure nme () { foo () { (); 3 4
Polymorphism Polymorphic Disptch Method ddress is determined dynmiclly Invoking method on n object in Jv vrible tht stores the object hs sttic type compiler cn not hrdcode trget ddress in procedure cll object reference is dynmic nd so is its type insted, compiler genertes code to lookup procedure ddress t runtime - object s type must implement the type of the referring vrible ddress is stored in memory in the object s clss jump tble - but object s type my override methods of this bse type Clss Jump tble Polymorphic Disptch every clss is represented by clss object trget method ddress depends on the type of the referenced object the clss object stores the clss s jump tble one cll site cn invoke different methods t different times clss A { () { () { the jump tble stores the ddress of every method implemented by the clss objects store pointer to their clss object sttic foo (A ) { Which gets clled?. ();. (); clss B extends A { () { wiff () { Sttic nd dynmic of method invoction ddress of jump tble is determined dynmiclly sttic br () { foo (new A()); foo (new B()); method s offset into jump tble is determined stticlly 5 Exmple of Jv Disptch Clss A A. () { A. () { 6 Dynmic Jumps in C clss A { () { () { Function pointer clss B extends A { () { wiff () { vrible tht stores pointer to procedure declred - <return-type> (*<vrible-nme>)(<forml-rgument-list>); Clss B wiff n A B. () { B.wiff () { used to mke dynmic cll sttic foo (A ) {. ();. (); - <vrible-nme> (<ctul-rgument-list>); Exmple sttic br () { foo (new A()); foo (new B()); () { foo () { (*Func) (); B foo () r[0] r[1] pc pc m[r[5]] # r0 m[r[0]] # r1 m[r[1]+0*4] # m[r[1]+1*4] # = =.clss. (). () Runtime Stck 7 Func = ; clls Func (); 8
Simplified Polymorphism in C (SA-dynmic-cll.c) nd B... Declrtion of B s jump tble nd code Use struct to store jump tble struct B { (*)(); (*)(); (*wiff)(); ; drwing on previous exmple of A... Declrtion of A s jump tble nd code struct A { (*) (); (*) (); ; B_ () { printf ("B_\n"); B_wiff () { printf ("B_wiff\n"); A_ () { printf ("A_\n"); A_ () { printf ("A_\n"); Crete n instnce of B s jump tble struct B* new_b () { struct B* b = (struct B*) mlloc (sizeof (struct B)); b-> = B_; b-> = A_; b->wiff = B_wiff; return b; Crete n instnce of A s jump tble struct A* new_a () { struct A* = (struct A*) mlloc (sizeof (struct A)); -> = A_; -> = A_; return ; 9 10 Disptch Digrm for C (dt lyout) invoking nd on n A nd B... foo (struct A* ) { -> (); -> (); struct A A. () { br () { foo (new_a ()); foo ((struct A*) new_b ()); A. () { Struct B wiff struct A { (*) (); (*) (); ; struct A* new_a () { struct A* = (struct A*) mlloc (sizeof (struct A)); -> = A_; -> = A_; return ; 11 A_ () { A_ () { B_ () { B_wiff () { B. () { B.wiff () { struct B { (*)(); (*)(); (*wiff)(); ; struct B* new_b () { struct B* b = (struct B*) mlloc (sizeof (struct B)); b-> = B_; b-> = A_; b->wiff = B_wiff; return b; 12
Disptch Digrm for C (the disptch) struct A A. () { A. () { Struct B ISA for Polymorphic Disptch foo (struct A* ) { -> (); -> (); A_ () { A_ () { B_ () { B_wiff () { How do we compile B. () { wiff r[0] m[r[5]] # r0 = pc m[r[1]+0*4] # -> () pc m[r[1]+1*4] # -> () -> ()? foo (struct A* ) { -> (); -> (); br () { foo (new_a ()); foo ((struct A*) new_b ()); B.wiff () { foo () r[0] m[r[5]] # r0 = pc m[r[1]+0*4] # -> () pc m[r[1]+1*4] # -> () Pseudo code pc m[r[1]+0*4] Current jumps supported by ISA Nme Semntics Assembly Mchine jump bsolute pc j b--- indirect jump pc r[t] + (o==pp*2) j o(rt) ctpp We will benefit from new instruction in the ISA tht jumps to n ddress tht is stored in memory Runtime Stck 13 14 Double-indirect jump instruction (b+o) jump to ddress stored in memory using bse+offset ddressing Nme Semntics Assembly Mchine jump bsolute pc j b--- indirect jump pc r[t] + (o==pp*2) j o(rt) ctpp j *o(rt) dtpp dbl-ind jump b+o pc m[r[t] + (o==pp*2)] Switch Sttements 15 16
Switch Sttement Humn vs Compiler int i; int j; foo () { cse 1: j=11; brek; cse 2: j=12; brek; br () { if (i==0) j=10; else if (i==1) j = 11; else if (i==2) j = 12; else if (i==3) j = 13; else Semntics the sme s simplified nested if sttements where condition of ech if tests the sme vrible unless you leve the brek the end of the cse block So, why bother putting this in the lnguge? is it for humns, fcilitte writing nd reding of code? is it for compilers, permitting more efficient implementtion? Implementing switch sttements we lredy know how to implement if sttements; is there nything more to consider? Benefits for humns the syntx models common idiom: choosing one computtion from set But, switch sttements hve interesting restrictions cse lbels must be sttic, crdinl vlues - crdinl vlue is number tht specifies position reltive to the beginning of n ordered set - for exmple, integers re crdinl vlues, but strings re not cse lbels must be compred for equlity to single dynmic expression - some lnguges permit the expression to be n inequlity Do these restrictions benefit humns? hve you ever wnted to do something like this? switch (treenme) { cse "lrch": cse "cedr": cse "hemlock": switch (i,j) { cse i>0: cse i==0 & j>: cse i<0 & j==: defult: Why Compilers like Switch Sttements 17 Hppy Compilers men Hppy People 18 Notice wht we hve switch condition evlutes to number ech cse rm hs distinct number And so, the implementtion hs simplified form build tble with the ddress of every cse rm, indexed by cse vlue switch by indexing into this tble nd jum to mtching cse rm For exmple cse 1: j=11; brek; cse 2: j=12; brek; lbel jumptble[4] = { L0, L1, L2, L3 ; if (i >3) goto DEFAULT; goto jumptble[i]; L0: j = 10; L1: j = 11; L2: j = 12; L3: j = 13; DEFAULT: CONT: cse 1: j=11; brek; cse 2: j=12; brek; Computtion cn be much more efficient compre the running time to if-bsed lterntive But, could it ll go horribly wrong? lbel jumptble[4] = { L0, L1, L2, L3 ; if (i >3) goto DEFAULT; goto jumptble[i]; L0: j = 10; L1: j = 11; L2: j = 12; L3: j = 13; DEFAULT: CONT: construct switch sttement where this implementtion technique is relly bd ide Guidelines for writing efficient switch sttements if (i==0) j=10; else if (i==1) j = 11; else if (i==2) j = 12; else if (i==3) j = 13; else 19 20
The bsic implementtion strtegy Refining the implementtion strtegy Generl form of switch sttement switch (<cond>) { cse <lbel_i>: <code_i> repeted 0 or more times defult: <code_defult> optionl Nive strtegy goto ddress of code_defult if cond > mx_lbel_vlue goto jumptble[lbel_i] stticlly: jumptble[lbel_i] = ddress of code_i forll lbel_i Nive implementtion strtegy goto ddress of code_defult if cond > mx_lbel_vlue goto jumptble[lbel_i] stticlly: jumptble[lbel_i] = ddress of code_i forll lbel_i But there re two dditionl considertions cse lbels re not lwys contiguous the lowest cse lbel is not lwys 0 Non-contiguous cse lbels wht is the problem wht is the solution Cse lbels not strting t 0 wht is the problem wht is the solution cse 1000: j=10; brek; cse 1001: j=11; brek; cse 1002: j=12; brek; cse 1003: j=13; brek; Implementing Switch Sttements 21 Snippet B: In templte form 22 Choose strtegy use jump-tble unless cse lbels re sprse or there re very few of them use nested-if-sttements otherwise Jump-tble strtegy stticlly - build jump tble for ll lbel vlues between lowest nd highest generte code to - goto defult if condition is less thn minimum cse lbel or greter thn mximum - normlize condition to lowest cse lbel - use jumptble to go directly to code selected cse rm goto ddress of code_defult if cond < min_lbel_vlue goto ddress of code_defult if cond > mx_lbel_vlue goto jumptble[cond-min_lbel_vlue] stticlly: jumptble[i-min_lbel_vlue] = ddress of code_i forll i: min_lbel_vlue <= i <= mx_lbel_vlue cse 20: j=10; brek; cse 21: j=11; brek; cse 22: j=12; brek; cse 23: j=13; brek; lbel jumptble[4] = { L20, L21, L22, L23 ; if (i < 20) goto DEFAULT; if (i > 23) goto DEFAULT; goto jumptble[i-20]; L20: j = 10; L21: j = 11; L22: j = 12; L23: j = 13; DEFAULT: CONT: 23 24
Snippet B: In Assembly Code Sttic nd Dynmic Control Flow foo: ld $i, r0 # r0 = &i ld 0x0(r0), r0 # r0 = i ld $0xffffffed, r1 # r1 = -19 dd r0, r1 # r0 = i-19 bgt r1, l0 # goto l0 if i>19 br defult # goto defult if i<20 l0: ld $0xffffffe9, r1 # r1 = -23 dd r0, r1 # r1 = i-23 bgt r1, defult # goto defult if i>23 ld $0xffffffec, r1 # r1 = -20 dd r1, r0 # r0 = i-20 ld $jmptble, r1 # r1 = &jmptble j *(r1, r0, 4) # goto jmptble[i-20] Jump instructions specify trget ddress nd jump-tken condition trget ddress cn be sttic or dynmic jump-trget condition cn be sttic (unconditionl) or dynmic (conditionl) Sttic jumps jump trget ddress is sttic cse20: ld $0x, r1 # r1 = 10 br done # goto done... defult: ld $0xe, r1 # r1 = 14 br done # goto done done: ld $j, r0 # r0 = &j st r1, 0x0(r0) # j = r1 br cont # goto cont compiler hrd-codes this ddress into instruction Nme Semntics Assembly Mchine brnch pc (==pc+oo*2) br 8-oo brnch if equl pc (==pc+oo*2) if r[c]==0 beg 9coo brnch if greter pc (==pc+oo*2) if r[c]>0 bgt coo jump pc j b--- jmptble:.long 0x00000140 # & (cse 20).long 0x00000148 # & (cse 21).long 0x00000150 # & (cse 22).long 0x00000158 # & (cse 23) Simultor... Dynmic jumps jump trget ddress is dynmic Dynmic Jumps 25 Summry 26 Indirect Jump Jump trget ddress stored in register We lredy introduced this instruction, but used it for sttic procedure clls Nme Semntics Assembly Mchine indirect jump pc r[t] + (o==pp*2) j o(rt) ctpp Sttic vs Dynmic flow control sttic if jump trget is known by compiler dynmic for polymorphic disptch, function pointers, nd switch sttements Polymorphic Disptch in Jv invoking method on n object in jv method ddress depends on object s type, which is not know stticlly Double indirect jumps Jump trget ddress stored in memory Bse-plus-displcement nd indexed modes for memory cecss object hs pointer to clss object; clss object contins method jump tble procedure cll is double-indirect jump i.e., trget ddress in memory Function Pointers in C vrible tht stores the ddress of procedure Nme Semntics Assembly Mchine dbl-ind jump b+o pc m[r[t] + (o==pp*2)] j *o(rt) dtpp dbl-ind jump indexed pc m[r[t] + r[i]*4] j *(rt,ri,4) eti- used to implement dynmic procedure cll, similr to polymorphic disptch Switch Sttements syntx restricted so tht they cn be implemented with jump tble jump-tble implementtion running time is independent of the number of cse lbels but, only works if cse lbel vlues re resonbly dense 27 28