Open
Bug 516046
Opened 15 years ago
Updated 2 years ago
Gratuitous use of ObjC exceptions
Categories
(Firefox :: General, defect)
Tracking
()
NEW
People
(Reporter: joelr, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: [ts])
Consider CFStringRefToUTF8 [1]. This function uses Carbon APIs but no Cocoa. Still the whole function is bracketed in NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT and NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT, i.e.
@try {
...
} @catch(NSException *_exn) {
nsObjCExceptionLog(_exn);
} \
return NS_ERROR_FAILURE;
It looks harmless but take a look at the assembler dump below. 2/3 or 3/4 of this function (more?) are taken by the exception setup and cleanup. ObjC exceptions are zero-cost on x86-64 but very expensive on x86-32 [2]. I think we should analyze our code for gratuitous use of ObjC exceptions and, perhaps, eliminate their use altogether where possible.
For example, the .mm extension is for C++ files that call into ObjC. I skimmed through half of nsLocalFileOSX.mm but I didn't see any calls into ObjC, just calls to Carbon which is a C/C++ API. Why are we using ObjC exception here?
[1] http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsLocalFileOSX.mm#2225
[2] http://developer.apple.com/mac/library/releasenotes/Cocoa/RN-ObjectiveC/index.html
Breakpoint 1, CFStringReftoUTF8 (aInStrRef=0x2614fc0, aOutStr=@0xbfffec58) at ../../../mozilla-central/xpcom/io/nsLocalFileOSX.mm:2187
2187 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
(gdb) disas
Dump of assembler code for function CFStringRefToUTF8:
0x00bf8ff0 <CFStringRefToUTF8+0>: push %ebp
0x00bf8ff1 <CFStringRefToUTF8+1>: mov %esp,%ebp
0x00bf8ff3 <CFStringRefToUTF8+3>: push %esi
0x00bf8ff4 <CFStringRefToUTF8+4>: push %ebx
0x00bf8ff5 <CFStringRefToUTF8+5>: sub $0xb0,%esp
0x00bf8ffb <CFStringRefToUTF8+11>: call 0xbf9000 <CFStringRefToUTF8+16>
0x00bf9000 <CFStringRefToUTF8+16>: pop %ebx
0x00bf9001 <CFStringRefToUTF8+17>: mov %eax,-0x6c(%ebp)
0x00bf9004 <CFStringRefToUTF8+20>: mov %edx,-0x70(%ebp)
0x00bf9007 <CFStringRefToUTF8+23>: lea -0x64(%ebp),%esia
0x00bf900a <CFStringRefToUTF8+26>: mov %esi,(%esp)
0x00bf900d <CFStringRefToUTF8+29>: call 0xd1b0f4 <dyld_stub_objc_exception_try_enter>
0x00bf9012 <CFStringRefToUTF8+34>: mov %esi,(%esp)
0x00bf9015 <CFStringRefToUTF8+37>: call 0xd1aecc <dyld_stub__setjmp>
0x00bf901a <CFStringRefToUTF8+42>: test %eax,%eax
0x00bf901c <CFStringRefToUTF8+44>: je 0xbf9080 <CFStringRefToUTF8+144>
0x00bf901e <CFStringRefToUTF8+46>: lea -0x64(%ebp),%esi
0x00bf9021 <CFStringRefToUTF8+49>: mov %esi,(%esp)
0x00bf9024 <CFStringRefToUTF8+52>: call 0xd1b0e2 <dyld_stub_objc_exception_extract>
0x00bf9029 <CFStringRefToUTF8+57>: mov %eax,-0x74(%ebp)
0x00bf902c <CFStringRefToUTF8+60>: mov %esi,(%esp)
0x00bf902f <CFStringRefToUTF8+63>: call 0xd1b0f4 <dyld_stub_objc_exception_try_enter>
0x00bf9034 <CFStringRefToUTF8+68>: mov %esi,(%esp)
0x00bf9037 <CFStringRefToUTF8+71>: call 0xd1aecc <dyld_stub__setjmp>
0x00bf903c <CFStringRefToUTF8+76>: test %eax,%eax
0x00bf903e <CFStringRefToUTF8+78>: je 0xbf9110 <CFStringRefToUTF8+288>
0x00bf9044 <CFStringRefToUTF8+84>: lea -0x64(%ebp),%eax
0x00bf9047 <CFStringRefToUTF8+87>: mov %eax,(%esp)
0x00bf904a <CFStringRefToUTF8+90>: call 0xd1b0e2 <dyld_stub_objc_exception_extract>
0x00bf904f <CFStringRefToUTF8+95>: mov %eax,-0x74(%ebp)
0x00bf9052 <CFStringRefToUTF8+98>: mov -0x74(%ebp),%edx
0x00bf9055 <CFStringRefToUTF8+101>: test %edx,%edx
0x00bf9057 <CFStringRefToUTF8+103>: jne 0xbf920a <CFStringRefToUTF8+538>
0x00bf905d <CFStringRefToUTF8+109>: lea -0x64(%ebp),%eax
0x00bf9060 <CFStringRefToUTF8+112>: mov %eax,(%esp)
0x00bf9063 <CFStringRefToUTF8+115>: call 0xd1b0fa <dyld_stub_objc_exception_try_exit>
0x00bf9068 <CFStringRefToUTF8+120>: mov $0x80004005,%ebx
0x00bf906d <CFStringRefToUTF8+125>: mov %ebx,%eax
0x00bf906f <CFStringRefToUTF8+127>: add $0xb0,%esp
0x00bf9075 <CFStringRefToUTF8+133>: pop %ebx
0x00bf9076 <CFStringRefToUTF8+134>: pop %esi
0x00bf9077 <CFStringRefToUTF8+135>: leave
0x00bf9078 <CFStringRefToUTF8+136>: ret
0x00bf9079 <CFStringRefToUTF8+137>: nopl 0x0(%eax)
0x00bf9080 <CFStringRefToUTF8+144>: mov -0x6c(%ebp),%eax
0x00bf9083 <CFStringRefToUTF8+147>: mov %eax,(%esp)
0x00bf9086 <CFStringRefToUTF8+150>: call 0xd19336 <dyld_stub_CFStringGetLength>
0x00bf908b <CFStringRefToUTF8+155>: mov %eax,%esi
0x00bf908d <CFStringRefToUTF8+157>: mov %eax,-0x84(%ebp)
0x00bf9093 <CFStringRefToUTF8+163>: movl $0x0,-0x88(%ebp)
0x00bf909d <CFStringRefToUTF8+173>: mov -0x6c(%ebp),%ecx
0x00bf90a0 <CFStringRefToUTF8+176>: lea -0xc(%ebp),%eax
0x00bf90a3 <CFStringRefToUTF8+179>: mov %eax,0x20(%esp)
0x00bf90a7 <CFStringRefToUTF8+183>: movl $0x0,0x1c(%esp)
0x00bf90af <CFStringRefToUTF8+191>: movl $0x0,0x18(%esp)
0x00bf90b7 <CFStringRefToUTF8+199>: movl $0x0,0x14(%esp)
0x00bf90bf <CFStringRefToUTF8+207>: movl $0x0,0x10(%esp)
0x00bf90c7 <CFStringRefToUTF8+215>: movl $0x8000100,0xc(%esp)
0x00bf90cf <CFStringRefToUTF8+223>: mov -0x88(%ebp),%eax
0x00bf90d5 <CFStringRefToUTF8+229>: mov -0x84(%ebp),%edx
0x00bf90db <CFStringRefToUTF8+235>: mov %eax,0x4(%esp)
0x00bf90df <CFStringRefToUTF8+239>: mov %edx,0x8(%esp)
0x00bf90e3 <CFStringRefToUTF8+243>: mov %ecx,(%esp)
0x00bf90e6 <CFStringRefToUTF8+246>: call 0xd19318 <dyld_stub_CFStringGetBytes>
0x00bf90eb <CFStringRefToUTF8+251>: mov $0x80004005,%ebx
0x00bf90f0 <CFStringRefToUTF8+256>: cmp %eax,%esi
0x00bf90f2 <CFStringRefToUTF8+258>: je 0xbf9180 <CFStringRefToUTF8+400>
0x00bf90f8 <CFStringRefToUTF8+264>: lea -0x64(%ebp),%eax
0x00bf90fb <CFStringRefToUTF8+267>: mov %eax,(%esp)
0x00bf90fe <CFStringRefToUTF8+270>: call 0xd1b0fa <dyld_stub_objc_exception_try_exit>
0x00bf9103 <CFStringRefToUTF8+275>: mov %ebx,%eax
0x00bf9105 <CFStringRefToUTF8+277>: add $0xb0,%esp
0x00bf910b <CFStringRefToUTF8+283>: pop %ebx
0x00bf910c <CFStringRefToUTF8+284>: pop %esi
0x00bf910d <CFStringRefToUTF8+285>: leave
0x00bf910e <CFStringRefToUTF8+286>: ret
0x00bf910f <CFStringRefToUTF8+287>: nop
0x00bf9110 <CFStringRefToUTF8+288>: mov -0x74(%ebp),%eax
0x00bf9113 <CFStringRefToUTF8+291>: mov %eax,0x4(%esp)
0x00bf9117 <CFStringRefToUTF8+295>: mov 0x38b944(%ebx),%eax
0x00bf911d <CFStringRefToUTF8+301>: mov %eax,(%esp)
0x00bf9120 <CFStringRefToUTF8+304>: call 0xd1b0e8 <dyld_stub_objc_exception_match>
0x00bf9125 <CFStringRefToUTF8+309>: test %eax,%eax
0x00bf9127 <CFStringRefToUTF8+311>: je 0xbf9170 <CFStringRefToUTF8+384>
0x00bf9129 <nsObjCExceptionLog+0>: mov 0x38b008(%ebx),%eax
0x00bf912f <nsObjCExceptionLog+6>: mov %eax,0x4(%esp)
0x00bf9133 <nsObjCExceptionLog+10>: mov -0x74(%ebp),%edx
0x00bf9136 <nsObjCExceptionLog+13>: mov %edx,(%esp)
0x00bf9139 <nsObjCExceptionLog+16>: call 0xd1b100 <dyld_stub_objc_msgSend>
0x00bf913e <nsObjCExceptionLog+21>: mov %eax,%esi
0x00bf9140 <nsObjCExceptionLog+23>: mov 0x38b00c(%ebx),%eax
0x00bf9146 <nsObjCExceptionLog+29>: mov %eax,0x4(%esp)
0x00bf914a <nsObjCExceptionLog+33>: mov -0x74(%ebp),%ecx
0x00bf914d <nsObjCExceptionLog+36>: mov %ecx,(%esp)
0x00bf9150 <nsObjCExceptionLog+39>: call 0xd1b100 <dyld_stub_objc_msgSend>
0x00bf9155 <nsObjCExceptionLog+44>: mov %esi,0x8(%esp)
0x00bf9159 <nsObjCExceptionLog+48>: mov %eax,0x4(%esp)
0x00bf915d <nsObjCExceptionLog+52>: lea 0x36ad48(%ebx),%eax
0x00bf9163 <nsObjCExceptionLog+58>: mov %eax,(%esp)
0x00bf9166 <nsObjCExceptionLog+61>: call 0xd1a0ce <dyld_stub_NSLog>
0x00bf916b <nsObjCExceptionLog+66>: jmp 0xbf905d <CFStringRefToUTF8+109>
0x00bf9170 <CFStringRefToUTF8+384>: lea -0x64(%ebp),%eax
0x00bf9173 <CFStringRefToUTF8+387>: mov %eax,(%esp)
0x00bf9176 <CFStringRefToUTF8+390>: call 0xd1b0fa <dyld_stub_objc_exception_try_exit>
0x00bf917b <CFStringRefToUTF8+395>: jmp 0xbf9052 <CFStringRefToUTF8+98>
0x00bf9180 <CFStringRefToUTF8+400>: mov -0x70(%ebp),%eax
0x00bf9183 <CFStringRefToUTF8+403>: mov -0xc(%ebp),%edx
0x00bf9186 <CFStringRefToUTF8+406>: call 0xc34010 <_ZN19nsACString_internal9SetLengthEj>
0x00bf918b <CFStringRefToUTF8+411>: mov -0x70(%ebp),%eax
0x00bf918e <CFStringRefToUTF8+414>: mov 0x4(%eax),%eax
0x00bf9191 <CFStringRefToUTF8+417>: mov $0x8007000e,%ebx
0x00bf9196 <CFStringRefToUTF8+422>: cmp -0xc(%ebp),%eax
0x00bf9199 <CFStringRefToUTF8+425>: jne 0xbf90f8 <CFStringRefToUTF8+264>
0x00bf919f <CFStringRefToUTF8+431>: mov -0x70(%ebp),%ebx
0x00bf91a2 <_ZN19nsACString_internal12BeginWritingEv+0>: mov $0xffffffff,%edx
0x00bf91a7 <_ZN19nsACString_internal12BeginWritingEv+5>: mov %ebx,%eax
0x00bf91a9 <_ZN19nsACString_internal12BeginWritingEv+7>: call 0xc35490 <_ZN19nsACString_internal13EnsureMutableEj>
0x00bf91ae <_ZN19nsACString_internal12BeginWritingEv+12>: xor %ecx,%ecx
0x00bf91b0 <_ZN19nsACString_internal12BeginWritingEv+14>: test %eax,%eax
0x00bf91b2 <_ZN19nsACString_internal12BeginWritingEv+16>: je 0xbf91b6 <CFStringRefToUTF8+454>
0x00bf91b4 <_ZN19nsACString_internal12BeginWritingEv+18>: mov (%ebx),%ecx
0x00bf91b6 <CFStringRefToUTF8+454>: mov %esi,-0x7c(%ebp)
0x00bf91b9 <CFStringRefToUTF8+457>: movl $0x0,-0x80(%ebp)
0x00bf91c0 <CFStringRefToUTF8+464>: mov -0x6c(%ebp),%eax
0x00bf91c3 <CFStringRefToUTF8+467>: lea -0xc(%ebp),%edx
0x00bf91c6 <CFStringRefToUTF8+470>: mov %edx,0x20(%esp)
0x00bf91ca <CFStringRefToUTF8+474>: mov -0xc(%ebp),%edx
0x00bf91cd <CFStringRefToUTF8+477>: mov %edx,0x1c(%esp)
0x00bf91d1 <CFStringRefToUTF8+481>: mov %ecx,0x18(%esp)
0x00bf91d5 <CFStringRefToUTF8+485>: movl $0x0,0x14(%esp)
0x00bf91dd <CFStringRefToUTF8+493>: movl $0x0,0x10(%esp)
0x00bf91e5 <CFStringRefToUTF8+501>: movl $0x8000100,0xc(%esp)
0x00bf91ed <CFStringRefToUTF8+509>: mov -0x80(%ebp),%edx
0x00bf91f0 <CFStringRefToUTF8+512>: mov -0x7c(%ebp),%ecx
0x00bf91f3 <CFStringRefToUTF8+515>: mov %edx,0x4(%esp)
0x00bf91f7 <CFStringRefToUTF8+519>: mov %ecx,0x8(%esp)
0x00bf91fb <CFStringRefToUTF8+523>: mov %eax,(%esp)
0x00bf91fe <CFStringRefToUTF8+526>: call 0xd19318 <dyld_stub_CFStringGetBytes>
0x00bf9203 <CFStringRefToUTF8+531>: xor %ebx,%ebx
0x00bf9205 <CFStringRefToUTF8+533>: jmp 0xbf90f8 <CFStringRefToUTF8+264>
0x00bf920a <CFStringRefToUTF8+538>: mov -0x74(%ebp),%ecx
0x00bf920d <CFStringRefToUTF8+541>: mov %ecx,(%esp)
0x00bf9210 <CFStringRefToUTF8+544>: call 0xd1b0ee <dyld_stub_objc_exception_throw>
End of assembler dump.
Reporter | ||
Updated•15 years ago
|
Whiteboard: [ts]
See bug 417560. As for why those handlers are covering Carbon calls, our understanding is that Carbon calls can raise Obj-C exceptions.
Reporter | ||
Comment 2•15 years ago
|
||
Josh,
1) How can Carbon calls raise ObjC exceptions, these are two completely different worlds. Carbon has absolutely nothing to do with the ObjC runtime (and thus exceptions) as far as I know.
2) I looked at bugs 417560 and 163260 but I maintain that we should not be this ham-handed. CFStringRefToUTF8 and other functions from nsLocalFileOSX are all over the place in the startup path. I want to streamline this path and I really don't want to see a disassembly like the above!
3) Carbon is 32-bit only and there's no 64-bit Carbon at all. None, zilch, none whatsoever. Will you be replacing these Carbon calls as part of the 64-bit port?
(In reply to comment #2)
> 1) How can Carbon calls raise ObjC exceptions, these are two completely
> different worlds. Carbon has absolutely nothing to do with the ObjC runtime
> (and thus exceptions) as far as I know.
At an implementation level they are not different worlds. Many Obj-C objects are backed by Carbon implementations, and in some cases the situation is reversed. According to the research we did, Carbon APIs can call into Obj-C code and frameworks and thus raise Obj-C exceptions.
> 2) I looked at bugs 417560 and 163260 but I maintain that we should not be this
> ham-handed. CFStringRefToUTF8 and other functions from nsLocalFileOSX are all
> over the place in the startup path. I want to streamline this path and I really
> don't want to see a disassembly like the above!
See my answer to question #1 :) I don't like it either, but we have not come up with a better plan.
> 3) Carbon is 32-bit only and there's no 64-bit Carbon at all. None, zilch, none
> whatsoever. Will you be replacing these Carbon calls as part of the 64-bit
> port?
This isn't really true, "Carbon" is a somewhat wishy washy term these days. Most of Carbon disappeared, not all of it. For example, there is FSRef functionality in 64-bit, though some FSRef-based APIs are not available. In any case, most of our Carbon usage will go away in 64-bit. We've removed huge amounts of it already.
Reporter | ||
Comment 4•15 years ago
|
||
FSRef lives in the CoreServices framework, particularly in CarbonCore.
nm
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/CarbonCore
| grep objc
U _objc_collectingEnabled
U _objc_registerThreadWithCollector
U _objc_unregisterThreadWithCollector
I do not see how this can throw ObjC exceptions.
I'm still waiting for the "official" word.
Reporter | ||
Comment 5•15 years ago
|
||
I meant that I'm waiting for the semi-official word from Apple folks on whether Carbon can raise ObjC exceptions and how to best handle them on x86-32.
Reporter | ||
Comment 6•15 years ago
|
||
Via Eric Schlegel at Apple:
Generally, exceptions should be caught at the level of the callback, rather than around the lower-level functions that you're calling in CoreFoundation.
As to whether the CF function you're calling could actually throw an exception, I can't say for sure, although it would be surprising. I don't think CoreFoundation throws exceptions in general. However, the source is public; you could download it and determine the answer yourself.
-eric
Reporter | ||
Comment 7•15 years ago
|
||
The CoreFoundation sources are available for perusal here:
http://www.opensource.apple.com/source/CF/CF-476.19/
We can easily check to see what throws exceptions and what doesn't. The Core Foundation bits we use (CFRunLoop, etc.) do not throw ObjC exceptions.
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•