It is currently Thu Mar 28, 2024 8:19 pm

Mulle kybernetiK Optimization

Forum for Optimizations around Cocoa and Mac OS X

Article 3.2: IMP Cacheing Deluxe

Discussion about the <a href="http://www.mulle-kybernetik.com/artikel/Optimization">Optimizing Objective-C Article Series</a>
User avatar
 
Posts: 42
Joined: Fri Aug 06, 2004 9:20 am
Location: Bochum
Website: http://www.mulle-kybernetik.com/weblog

Article 3.2: IMP Cacheing Deluxe

Post by Nat! » Wed Sep 01, 2004 12:20 am

Discusssion thread for this specific optimization article.
Last edited by Nat! on Wed Sep 15, 2004 12:53 am, edited 1 time in total.

User avatar
 
Posts: 2
Joined: Fri Aug 06, 2004 1:07 am
Website: http://www.mulle-kybernetik.com/~znek/

lame

Post by znek » Fri Sep 03, 2004 2:50 pm

The requested URL /artikel/Optimization/opti-imp-autorelease.source.tgz was not found on this server.

User avatar
 
Posts: 42
Joined: Fri Aug 06, 2004 9:20 am
Location: Bochum
Website: http://www.mulle-kybernetik.com/weblog

Re: lame

Post by Nat! » Sun Sep 05, 2004 6:50 pm

znek wrote:The requested URL /artikel/Optimization/opti-imp-autorelease.source.tgz was not found on this server.


:oops: Fixed. Thanks for the hint.

 
Posts: 5
Joined: Tue Sep 07, 2004 4:50 am

Post by whitenoise » Tue Sep 07, 2004 4:58 am

You write in regard to the standard dyld stub: "I think this could be done a whole lot better".

I agree, but can it be done without breaking binary compatibility? The guy who designed DYLD wasn't an expert on position-independent code, and this stub has already been improved at least once prior to the current version you dissect in the article. But, it's embedded in the file format.

User avatar
 
Posts: 42
Joined: Fri Aug 06, 2004 9:20 am
Location: Bochum
Website: http://www.mulle-kybernetik.com/weblog

Post by Nat! » Tue Sep 07, 2004 9:59 pm

whitenoise wrote:I agree, but can it be done without breaking binary compatibility?


I think it should be possible to define a bit in the flags of the mach-o header, to alert that this is a new kind of object file. Or one could also use a different filetype. This would be only upward compatible, but the different filetype could preclude launches on not-supported platforms.

User avatar
 
Posts: 42
Joined: Fri Aug 06, 2004 9:20 am
Location: Bochum
Website: http://www.mulle-kybernetik.com/weblog

Post by Nat! » Thu Sep 09, 2004 6:06 pm

Well, I don't think I will really write a whole article on the subject. The topic is too narrow and I would actually have to do some serious coding, for which I am too lazy. 8)

This stub code would be much faster, if it were to contain just this:

Code: Select all

       lis     r12,0x1234
       ori     r12,r12,0x5678
       mtspr   ctr,r12
       bctr


It would be twice as fast and it is half the size.

If the dynamic linker can generate a table with addresses it could also just generate or patch that code. Incidentally that code just takes 16 bytes, which means proper alignment (see below) for free without waste.

Because of prebinding the linked addresses wouldn't usually change, so this could be set already at link time and it usually wouldn't be necessary to change the stub code at all. Therefore there shouldn't be any penalty compared to the current state of affairs.

Now shared libraries can be relocated and therefore addresses can change. To accomodate that it would be required that the stubcodes reside on their own page(s), then map a fresh page at that address and write in the required new stubs. Finally clear the instruction cache and maybe fiddle with page protection and I think it should work.

User avatar
 
Posts: 42
Joined: Fri Aug 06, 2004 9:20 am
Location: Bochum
Website: http://www.mulle-kybernetik.com/weblog

A danger with forwarded messages

Post by Nat! » Wed Sep 13, 2006 2:18 pm

There is a problem that just bit me now, in a NSArray mapping method. I have an array mixed with objects that implement a certain method (lets say it's @selector( name)) directly and some, that implement them indirectly via forwarding (@selector( forwardInvocation:) -> forwarding it to another object).

If a class does not implement a method, then class_lookupMethod will return _objc_msgForward. This will in turn do the forwarding steps.

Unfortunately it is either the case that _objc_msgForward is written in a way, that it expects objc_msgSend to be called beforehand (setting the r11 register properly) or the gcc compiler 4.0 does not emit proper function pointer call code, because it does not set the r11 register then. I am undecided, but leaning towards the first conclusion.

To fix this in either case, you should change the code to something like this

Code: Select all

 // our IMP cacheing thing
      thisIsa = _isa( p);
      index   = ((unsigned long) thisIsa >> 4) & 15;
     
      if( lastIsa[ index] != thisIsa)
      {
         extern id  _objc_msgForward( id, SEL, ...);

         imp = class_lookupMethod( thisIsa, sel);

         /* the problem is, that we don't preserve r11, but objc_msgForward
          * explicitly expects r11 to be set by objc_msgSend
          */
         if( imp == _objc_msgForward)
            imp = objc_msgSend;
         
         /* otherwise continue as planned */
         lastSelIMP[ index] = imp;
         lastIsa[ index]    = thisIsa;
      }
     
      (*lastSelIMP[ index])( p, sel, argument);
   }


Performance with forwarding ain't so great anyway, so the loss in that case should be acceptable.


Return to “Article Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest