Archive for June 18, 2011

Saturday, June 18, 2011

History of Collaborative Editing

Martin Pittenauer (via John Gruber):

Martin [Ott] did research into if that was actually possible and found - beside other research - Xerox Parc’s Jupiter paper. I remember that we were all amazed by the simplicity and elegance of the approach. From that we started work in early 2003, finishing 1.0 of Hydra (now called SubEthaEdit) just 8 weeks later, eventually winning the ADA later that year.

Kindle Periodical Improvements

Two longstanding Kindle problems have been that, unlike with books, magazines could only be downloaded onto one device. Secondly, you could keep old issues as long as you want, but if you upgraded your Kindle (or needed to replace it for some other reason) you could not transfer the kept issues. Andrys Basten reports that Amazon has made some improvements recently. It is now possible to download current issues onto multiple devices—i.e. Kindles or Android devices, since the iOS and Mac clients don’t support periodicals. Additionally, old periodical issues that were purchased individually (not via subscriptions) can be re-downloaded at will. Ideally, magazines and newspapers would work just like books—you’d be able to get any issue that you’d purchased, complete with your notes and highlights, at any time—but this is at least some progress.


Greg Parker:

The compiler knows which selectors are optimized by the runtime. It compiles the call site differently, calling objc_msgSend_fixup via a function pointer. At runtime, objc_msgSend_fixup replaces the function pointer with one of the objc_msgSend_vtable functions, if the called selector is one of the optimized selectors.

Update (2014-06-25): objc-runtime-new.m (via Colin Wheeler):

* vtable dispatch
* Every class gets a vtable pointer. The vtable is an array of IMPs.
* The selectors represented in the vtable are the same for all classes
*   (i.e. no class has a bigger or smaller vtable).
* Each vtable index has an associated trampoline which dispatches to 
*   the IMP at that index for the receiver class's vtable (after 
*   checking for NULL). Dispatch fixup uses these trampolines instead 
*   of objc_msgSend.
* Fragility: The vtable size and list of selectors is chosen at launch 
*   time. No compiler-generated code depends on any particular vtable 
*   configuration, or even the use of vtable dispatch at all.
* Memory size: If a class's vtable is identical to its superclass's 
*   (i.e. the class overrides none of the vtable selectors), then 
*   the class points directly to its superclass's vtable. This means 
*   selectors to be included in the vtable should be chosen so they are 
*   (1) frequently called, but (2) not too frequently overridden. In 
*   particular, -dealloc is a bad choice.
* Forwarding: If a class doesn't implement some vtable selector, that 
*   selector's IMP is set to objc_msgSend in that class's vtable.
* +initialize: Each class keeps the default vtable (which always 
*   redirects to objc_msgSend) until its +initialize is completed.
*   Otherwise, the first message to a class could be a vtable dispatch, 
*   and the vtable trampoline doesn't include +initialize checking.
* Changes: Categories, addMethod, and setImplementation all force vtable 
*   reconstruction for the class and all of its subclasses, if the 
*   vtable selectors are affected.


At the program startup, the message reference trampolines are pointers to the objc_msgSend_fixup function. For each message_ref, when its trampoline pointer is invoked for the first time, objc_msgSend_fixup gets called receiving the obj to which the message’s got to be sent and the message_ref structure from which it was called. So, what objc_msgSend_fixup must do is get the selector for the message to be called. Since, this has to be done only once for each message reference, objc_msgSend_fixup must also replace the trampoline field of the ref by a pointer to another function that doesn’t fix the message’s selector. This function is called objc_msgSend_fixedup (the selector has been fixed up). Now that the message selector has been set and this doesn’t have to be done again, objc_msgSend_fixup just calls objc_msgSend_fixedup and this just calls objc_msgSend. After that, if a message ref’s trampoline is called again, its selector is already fixed, and objc_msgSend_fixedup is the one that gets called.