5 ms·
One question. Why IOKit was not written in ObjC?
by fithisux 11y ago
One question. Why IOKit was not written in ObjC?
- adamnemecek 11y agoObjC has a pretty beefy (and therefore somewhat slow) runtime which is an issue for kernel stuff.
- speeder 11y agoOr explaining this better: The objects of ObjC work very differently than C++ objects. In Obj-C for example, there are no "methods" like C++, in C++ when you put a method in a class, (although implementation details may vary) it works like a function pointer in a C struct, and calling that method is just executing whatever code that pointer points to. In Obj-C in contrast, to call a function of a class, you actually pass a message, that first must be interpreted, then the runtime that interpreted the message find the correct function definition to use and run. For most apps people don't care about this, but game developers for example frequently make iOS and Mac games that in time-critical parts use pure C or even Obj-C++ so that they can skip this messaging part (that can cause significant performance problems sometimes). Example: yesterday I was trying to figure why a open source game I like was slowing down, I ran a profiler, and the most called function, and the one with most execution time, was a simple "GetSomeRandomVar()" for spaceships (it is a spacefight battle game), I looked in the source, and saw that every frame, every spaceship call this at least once for every other spaceship, if the spaceship has an AI it calls it many, many times, I inlined it and the code became much faster. I am very sure that if it was a ObjC call (with messaging) it would be so slow that the original author probably would not even have uploaded that to github. (by the way, the game IS an OSX game, but the original author wisely decided to go with C++ instead of ObjC)
- adamnemecek 11y ago> in C++ when you put a method in a class, (although implementation details may vary) it works like a function pointer in a C struct That's true only for virtual methods. Also to add to what you said, no real way of doing stack allocated objects in ObjC is an issue as well.
- chc 11y agoI think putting it that way exaggerates the differences a bit. The message doesn't really have to be "interpreted" in any meaningful way AFAIK. A message consists of a selector (essentially a method name) and a receiver, then whatever other arguments the method will take. The runtime looks up the selector in the receiver's method table, much like with C++ virtual methods, and then jumps to the implementation it finds. There is a little more fanciness (some method caching, and support for nil receivers), but I don't feel like it's hugely dissimilar from virtual methods. For anyone interested, here's a good analysis of Objective-C's message dispatch machinery: http://blog.zhengdong.me/2013/07/18/a-look-under-the-hood-of-objc-msgsend http://blog.zhengdong.me/2013/07/18/a-look-under-the-hood-of...
- pcwalton 11y agoThe vtable is a flat structure with known layout in C++. In Objective-C, it's a hash table (with precomputed hashes and lots of other tricks—but it's still fundamentally a hash table). There's a big difference between the two.
- chc 11y agoThere's a big difference between the data structures, yes, but the basic logic for message sends is still pretty similar. They both boil down to a simple lookup in a data structure and a jump. Would you really characterize the difference between a vtable and a hash table as "you actually pass a message, that first must be interpreted" in the case of a hash table?
- fleitz 11y agoI think the biggest issue is that in a vtable you jump directly to the method by index, and with objc_msgsend it looks up a string in a hash table. Mostly the difference is ints vs. strings in my opinion. As well in C++ if you don't mark your method virtual you can bypass all the vtable crap. I love ObjC but method resolution is far more expensive than in C++, especially non-virtual methods.
- 11y ago
- chrisdevereux 11y agoAlso, since classes are mutable, calling a method in a multithreaded environment may result in lock contention, which I imagine being tricky in a driver. So using obj-c in the kernel might require giving up some of the language's dynamism. Not sure how this was handled in NeXT.
- tempodox 11y agoYes, but then ObjC is not designed for low-level the way C & C++ are. In fact, the design goals are practically the opposite of what C++ aims at.
- mrpippy 11y agoDriverKit was the NeXTSTEP 3 driver environment, and it was written in ObjC. In old mailing lists posts (https://www.geeklair.net/~dluke/PCIdevice_tutorial.txt https://www.geeklair.net/~dluke/PCIdevice_tutorial.txt), Godfrey van der Linden (one of the IOKit architects) made some comments about the IOKit language choice: As IOKit is a child of DriverKit which was implemented in ObjC we wanted to reduce the amount of work necessary to convert from one space to the other, as ObjC is single inherited this was easiest for most of our drivers. At first we were going to allow multiple inheritance as we ported to C++ but then we tripped over the whole can of worms called 'virtual' inheritance. We really, really didn't want to turn all of our developers into C++ experts, which you have to be to use virtual inheritance properly. Another side effect is that we are now reasonable language independent. At some stage in the future we may be able to move IOKit over to a good programming language. I suspect that if they had re-written IOKit in 2010, it would be in Objective-C. My guesses why it was done in C++ in 2000: - programmer familiarity/comfort level: remember that classic Mac development was mostly being done in C/C++ by the mid-90s, and the Mac developers still around by 2000 didn't need to be given more reasons to jump ship. Carbon was created so that Mac C/C++ applications could be brought to X, and having drivers written in C++ was another easing factor. This also includes Apple's internal development teams--I don't think all the longtime Apple teams were that bullish on NeXT technologies. Remember that the original OS X Finder was a C++ Carbon app built with CodeWarrior. - ObjC not considered inevitable: in 2000 it was not at all clear that ObjC would be thriving for another 15+ years. The C/C++ Carbon API was one direction for the future, the Cocoa-Java bridge was another, another was putting C++-style syntax on top of ObjC (which was never completed). C++ wasn't going anywhere, whereas it would be painful to have driver development handcuffed to ObjC if applications abandoned it. - performance: it probably would have been a non-issue, but C++ is a safer choice performance-wise. There might be other interesting tidbits on the darwin-development or darwin-drivers if you go back to 2000/2001.
- ams6110 11y agoIn 2000 or thereabouts there was a strong push towards Java.