| View previous topic :: View next topic |
| Author |
Message |
Nat!

Joined: 06 Aug 2004 Posts: 42 Location: Bochum
|
Posted: Wed Sep 01, 2004 12:20 am Post subject: Article 3.2: IMP Cacheing Deluxe |
|
|
Discusssion thread for this specific optimization article.
Last edited by Nat! on Wed Sep 15, 2004 12:53 am; edited 1 time in total |
|
| Back to top |
|
 |
znek

Joined: 06 Aug 2004 Posts: 2
|
Posted: Fri Sep 03, 2004 2:50 pm Post subject: lame |
|
|
| The requested URL /artikel/Optimization/opti-imp-autorelease.source.tgz was not found on this server. |
|
| Back to top |
|
 |
Nat!

Joined: 06 Aug 2004 Posts: 42 Location: Bochum
|
Posted: Sun Sep 05, 2004 6:50 pm Post subject: Re: lame |
|
|
| znek wrote: | | The requested URL /artikel/Optimization/opti-imp-autorelease.source.tgz was not found on this server. |
Fixed. Thanks for the hint. |
|
| Back to top |
|
 |
whitenoise
Joined: 07 Sep 2004 Posts: 5
|
Posted: Tue Sep 07, 2004 4:58 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
Nat!

Joined: 06 Aug 2004 Posts: 42 Location: Bochum
|
Posted: Tue Sep 07, 2004 9:59 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
Nat!

Joined: 06 Aug 2004 Posts: 42 Location: Bochum
|
Posted: Thu Sep 09, 2004 6:06 pm Post subject: |
|
|
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.
This stub code would be much faster, if it were to contain just this:
| Code: | 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. |
|
| Back to top |
|
 |
Nat!

Joined: 06 Aug 2004 Posts: 42 Location: Bochum
|
Posted: Wed Sep 13, 2006 2:18 pm Post subject: A danger with forwarded messages |
|
|
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: | // 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. |
|
| Back to top |
|
 |
|