61
RMod 1 Mariano Martinez Peck [email protected] http://marianopeck.wordpress.com/ Monday, August 22, 2011

Efficient Proxies in Smalltalk

Embed Size (px)

DESCRIPTION

Presentation of the research paper entitled "Efficient Proxies in Smalltalk" in ESUG International Workshop on Smalltalk Technologies (IWST 2011), Edinburgh, Scotland.

Citation preview

Page 1: Efficient Proxies in Smalltalk

RMod

1

Mariano Martinez [email protected]

http://marianopeck.wordpress.com/

Monday, August 22, 2011

Page 2: Efficient Proxies in Smalltalk

What is a proxy?

2

A proxy object is a surrogate or placeholder that controls access to

another target object.

Monday, August 22, 2011

Page 3: Efficient Proxies in Smalltalk

Glossary

Target: object to proxify.

Client: user of the proxy.

Interceptor: object that intercepts message sending.

Handler: object that performs a desired action as a consequence of an interception.

3

Monday, August 22, 2011

Page 4: Efficient Proxies in Smalltalk

Forwarder and Logging example

4

Monday, August 22, 2011

Page 5: Efficient Proxies in Smalltalk

With or without Object replacement?

In proxies with object replacement (#become:), the target object is replaced by a proxy.

Proxies without object replacement are a kind of factory.

5

Monday, August 22, 2011

Page 6: Efficient Proxies in Smalltalk

With or without Object replacement?

In proxies with object replacement (#become:), the target object is replaced by a proxy.

Proxies without object replacement are a kind of factory.

5

Monday, August 22, 2011

Page 7: Efficient Proxies in Smalltalk

Traditional proxy implementations

6

Usage of a minimal object together with an implementation of a custom #doesNotUnderstand

doesNotUnderstand:executeBeforeHandlingexecuteAfterHandling

targetProxy

identityHashpointersTonextObject...

ProtoObject

Monday, August 22, 2011

Page 8: Efficient Proxies in Smalltalk

7

We are going to play a little game...

Monday, August 22, 2011

Page 9: Efficient Proxies in Smalltalk

8

Are both prints in Transcript the same or not?

Monday, August 22, 2011

Page 10: Efficient Proxies in Smalltalk

8

Are both prints in Transcript the same or not?

Conclusion: methods understood are NOT intercepted.Is that bad?

Monday, August 22, 2011

Page 11: Efficient Proxies in Smalltalk

8

Are both prints in Transcript the same or not?

Conclusion: methods understood are NOT intercepted.Is that bad?

Different execution paths Errors difficult to findMonday, August 22, 2011

Page 12: Efficient Proxies in Smalltalk

9

Do we want the regular #doesNotUnderstand or to intercept the message?

Monday, August 22, 2011

Page 13: Efficient Proxies in Smalltalk

10

Do we want the regular #doesNotUnderstand or to intercept the message?

Monday, August 22, 2011

Page 14: Efficient Proxies in Smalltalk

11

I wanted the normal #doesNotUnderstand!!!

Monday, August 22, 2011

Page 15: Efficient Proxies in Smalltalk

12

I wanted the normal #doesNotUnderstand!!!

Monday, August 22, 2011

Page 16: Efficient Proxies in Smalltalk

Problems #doesNotUnderstand: cannot be trapped like a regular message.

Mix of handling procedure and proxy interception.

Only methods that are not understood are intercepted.

No separation between proxies and handlers

13

This approach is not stratified

Monday, August 22, 2011

Page 17: Efficient Proxies in Smalltalk

14

Subclassing from nil does not solve the problem.

Monday, August 22, 2011

Page 18: Efficient Proxies in Smalltalk

15

VM CRASH

This solution is not uniform

Monday, August 22, 2011

Page 19: Efficient Proxies in Smalltalk

16

A Uniform, Light-weight and Stratified Proxy Model and Implementation.

Monday, August 22, 2011

Page 20: Efficient Proxies in Smalltalk

Used hooks

Object replacement (#become:)

Change an object’s class (#adoptInstance:)

Objects as methods (#run:with:in:)

Classes with no method dictionary (#cannotInterpret:)

17

Monday, August 22, 2011

Page 21: Efficient Proxies in Smalltalk

Object replacement

18

AB

CD

AB

CD

c become: d

Monday, August 22, 2011

Page 22: Efficient Proxies in Smalltalk

Objects as methods

19

The VM sends #run: aSelector with: anArray in: aReceiver

Monday, August 22, 2011

Page 23: Efficient Proxies in Smalltalk

Objects as methods

19

The VM sends #run: aSelector with: anArray in: aReceiver

So.....We can implement in Proxy:

Monday, August 22, 2011

Page 24: Efficient Proxies in Smalltalk

CLasses with no method dictionary

20

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

Monday, August 22, 2011

Page 25: Efficient Proxies in Smalltalk

Ghost model

21

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

handleInterception: anInterceptionProxyHandler

handleInterception: anInterceptionSimpleForwarderHandler

messageproxyproxyState

Interception

Monday, August 22, 2011

Page 26: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

Monday, August 22, 2011

Page 27: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

Proxy class >>

Monday, August 22, 2011

Page 28: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

aProxy

‘Mariano’aHandler

instanceOf

Proxy class >>

Monday, August 22, 2011

Page 29: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

aProxy

‘Mariano’aHandler

instanceOf

Proxy class >>

ProxyTrap class >>

Monday, August 22, 2011

Page 30: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

aProxy

‘Mariano’aHandler

instanceOf

Proxy class >>

ProxyTrap class >>

Monday, August 22, 2011

Page 31: Efficient Proxies in Smalltalk

How it works?

22

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

aProxy

‘Mariano’aHandler

instanceOf

Proxy class >>

Monday, August 22, 2011

Page 32: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Monday, August 22, 2011

Page 33: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Monday, August 22, 2011

Page 34: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Monday, August 22, 2011

Page 35: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Monday, August 22, 2011

Page 36: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Monday, August 22, 2011

Page 37: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Proxy >>

Monday, August 22, 2011

Page 38: Efficient Proxies in Smalltalk

aProxy

aProxy username

1: #username send

methodDict := nilProxyTrap

cannotInterpret: aMessageProxy

Object

2: #aProxy lookup

3: Since the method dictionary was nil, the VM sends #cannotInterpret to

the receiver but starting the lookup in the superclass

4: #cannotInterpret: lookup

Referencesinstance ofmessage sendlookupsubclass

How it works?

23

Proxy >>

SimpleForwarderHandler >>

Monday, August 22, 2011

Page 39: Efficient Proxies in Smalltalk

24

Traditional Ghost

#doesNotUnderstand: cannot be trapped like a regular message.

#cannotInterpret: is trapped like a regular message.

Mix of handling procedure and proxy interception.

No mix of handling procedure and proxy interception.

Only methods that are not understood are intercepted.

“All” methods are intercepted.

No separation between proxies and handlers.

Clear separation between proxies and handlers.

Monday, August 22, 2011

Page 40: Efficient Proxies in Smalltalk

25

is stratified

Monday, August 22, 2011

Page 41: Efficient Proxies in Smalltalk

Methods not intercepted

26

1) Optimizations done by the Compiler

2) Special shortcut bytecodes between Compiler and VM

2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending

on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.

2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.

Monday, August 22, 2011

Page 42: Efficient Proxies in Smalltalk

Methods not intercepted

26

1) Optimizations done by the Compiler

2) Special shortcut bytecodes between Compiler and VM

2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending

on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.

2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.

Monday, August 22, 2011

Page 43: Efficient Proxies in Smalltalk

Methods not intercepted

26

1) Optimizations done by the Compiler

2) Special shortcut bytecodes between Compiler and VM

2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending

on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.

2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.

Monday, August 22, 2011

Page 44: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

logIn:validate:

usernameage

User

Monday, August 22, 2011

Page 45: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

logIn:validate:

usernameage

User

Monday, August 22, 2011

Page 46: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

logIn:validate:

usernameage

User

Monday, August 22, 2011

Page 47: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

logIn:validate:

usernameage

User

Monday, August 22, 2011

Page 48: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

aUseraClassProxy

methodDict = nilsuperclass = ClassProxy

logIn:validate:

usernameage

User

instance of

Monday, August 22, 2011

Page 49: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

aUseraClassProxy

methodDict = nilsuperclass = ClassProxy

logIn:validate:

usernameage

User

instance of

User nameMonday, August 22, 2011

Page 50: Efficient Proxies in Smalltalk

Proxy for classes

27

cannotInterpret:proxyFor:

handlertarget

Proxy

initializenilMethodDict

ProxyTrap

Object

cannotInterpret:proxyFor:

superclass methodDictformathandlertarget

ClassProxy

initializenilMethodDict

ClassProxyTrap

aUseraClassProxy

methodDict = nilsuperclass = ClassProxy

logIn:validate:

usernameage

User

instance of

aUser username

User nameMonday, August 22, 2011

Page 51: Efficient Proxies in Smalltalk

Proxy for methods

28

Monday, August 22, 2011

Page 52: Efficient Proxies in Smalltalk

Proxy for methods

28

Regular message

Monday, August 22, 2011

Page 53: Efficient Proxies in Smalltalk

Proxy for methods

28

Regular messageMethod execution

Monday, August 22, 2011

Page 54: Efficient Proxies in Smalltalk

Proxy for methods

28

Just handling #run:with:in correctly is enough to also intercept method execution.

Regular messageMethod execution

Monday, August 22, 2011

Page 55: Efficient Proxies in Smalltalk

is

29

Uniform

Monday, August 22, 2011

Page 56: Efficient Proxies in Smalltalk

is

29

moreUniform

Monday, August 22, 2011

Page 57: Efficient Proxies in Smalltalk

More features

Low memory footprint.

Compact classes.

Store the minimal needed state.

Easy debugging.

Custom list of messages.

30

Monday, August 22, 2011

Page 58: Efficient Proxies in Smalltalk

Conclusion

31

With a little bit of special support from the VM (#cannotInterpret hook), we can have an image-side proxy solution

much better than the classic #doesNotUnderstand:

Monday, August 22, 2011

Page 59: Efficient Proxies in Smalltalk

Future work

Experiment with immediate proxies (memory address tag) in VM side.

Think how to correctly intercept non-executed methods.

32

Monday, August 22, 2011

Page 61: Efficient Proxies in Smalltalk

Mariano Martinez [email protected]

http://marianopeck.wordpress.com/

RMod

A Uniform, Light-weight and Stratified Proxy Model and Implementation

Monday, August 22, 2011