Bravo, Apple

Finally, Apple is doing away with those arrogant upstarts who think then can write a few lines in a high level language and call it a program. Their new developer agreement requires:

3.3.1 – Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).

This has a couple of good points – firstly banning stupid languages (used by those people who are not smart enough to learn c++), and secondly getting rid of translation layers. Apple has clearly put a lot of thought into their APIs, so why would anyone want to put a layer on top of them – it’s just going to make things harder to use.

Languages

There has been a lot of talk recently about compiling “foreign” languages, such as haxe, as3, javascript, java, .net based languages, into binaries that will run extremely well on the iPhone. But like all foreigners (who are responsible for all the terrorism in the world) these languages should be cleansed from all iPhones to maintain the iPhones mono-lingual purity. Putting such insidious diversity into a beautifully designed device can be shown to confuse consumers, most of whom don’t even know their device and been compromised by these so call “high level” languages.

By raising the barrier of entry, and only permitting “real” programming languages (ie, “C” based ones), Apple ensures that the quality of apps will remain at its current lofty levels. “Natural Selection” will then weed out those people who are too lazy or too stupid to learn a proper language. In fact, I think Apple has not gone far enough here and should dabble in a bit of “Intelligent Design” by requiring that all developers who wish to submit apps hold at least a 4 year degree in computer science. Just imagine a world where any kid can work out of his garage and build an application with an original language, or bit of hardware, that snubs its nose at the establishment – anarchy would ensue. Therefore, it is important that the responsible companies out there vet such potentially disruptive ideas before they can cause too much damage.

It can’t be said that Apple don’t like new langauges, after all, they championed the greatest NeXT Step in programming ever, Objective-C, it’s just that all the other languages are utter crap. Some of then do away with the beautiful square bracket, some use commas to separate function arguments and nearly all the modern ones perform “Garbage Collection”. What a joke! Apple solved this problem years ago be simply not creating garbage in the first place. Again, it is only those too lazy to learn about how to use allocation pools and correct reference counting that need anything as dirty as Garbage Collection.

The new langages, such as haxe, are so terse that you do not even know when you are using a delegate. How can anyone possibly understand that code like:
addEventListener(KeyboardEvent.KEY_DOWN, function(event) { trace(event); });
Is supposed to do? I mean where is the delegate? Where is the class that implements the UITextFieldDelegate protocol? (And why must these languages continue to call things “Interfaces” when they are clearly “Protocols” ?)

I think Apple are right to ban code generators, such as the haxe c++ backend. While these produce code that could in theory be produced by hand, the code it robotic and lacks the “soul” of hand written code. To err is human, and without the quirks introduced bu a human coding c++ we may as well hand the future over to SkyNet and let the machines run everything.

Layers and Tools

Thankfully, Apple has also done its research into programming techniques as well as programming languages. The problem with programming these days is that where are too many layers and tools to learn, and they are taking us back to a simpler times where you are “close to the metal”. Apple rightfully shuns these extra layers, and focuses only on code. Once you understand Objective-C, Interface Builder, NIB, XIB, Frameworks, .app layouts, provisioning, xml, plist, controllers, delegates, owners and outlets, then you can create pure lovely code, without any of that layering crap getting in your way.

Programmers must beware of code that essentially “lies” by pretending that the beautiful, native API actually looks like one of the ill-conceived APIs from another language. For example, why would anyone want to view a native UIView image as the practically unsable as3 “equivalent” (I use the term loosly) of BitmapData? I don’t think there is a single successful application ever written that uses this BitmapData class.

Isolating your code from the native API will cause your code to lose its identity. If you can compile it for another (obviously inferior) device then your code will become tainted by the lower class device, even it it performs identically on the Apple device. How quickly people forget that the upper class should not mingle with the lower class.

I hope Apple’s ban extends to the gzip “translation layer”. Programmers should not be using this library because it has security implications, and they should simply use the streaming classes and do the decompression in their own code. If more programmers thought like Apple, then there would be a lot fewer security holes in software.

Don’t get me started on Game Making programs. Thank god these are banned – imagine letting a non-programmer create an App. What next, Artist creating games? Don’t make me laugh.

Conclusion

Apple has made a huge stride forwards by tightening the definition of what a real developer is, and I’m looking forward to what’s next. I think they have a little way to go – for example, what about all those people using foreign editors, rather than XCode? Surely if XCode is not good enough for a developer, then that developer is not good enough for Apple. The best way I can see for them enforcing this is for them to install a “watchdog” application the the developer’s machine, and send screenshots back to Apple periodically. That way, if the developer does not conform to the coding purity required by Apple, they could be identified and sent to a camp to help them concentrate on being better programmers. Win-win, what a great idea.

Switched to IMMIX for Internal Garbage Collection

I did a little bit of profiling on the iPhone and found a bit too much time was spent doing garbage collection.
The hxcpp runtime has 2 modes – “Boehm GC with explicit statics” and “internal”. The former is from a standard and robust code base, with the latter uses built in code with explicit marking. I added the second mode because Boehm GC was just too slow on the iPhone – not sure why because it is pretty good on the other platforms (maybe I missed a configuration option).

The internal GC has some restrictions that make it mainly suitable for games. These are: the collection must be triggered explicitly, since no stack searching is done, which is most easily done once per frame. And it is not thread safe, which can be worked around. Within these confines, many different schemes can be tried.
My first attempt could probably be termed “Naive Mark and Sweep”, and used free lists. On Windows/Mac this underperfromed Boehm GC, but on the iPhone, worked better.

The current scheme is now “Simplified IMMIX“. It is simplified because it is single threaded, and I have not implemented overflow allocation, defragmentation (although there are hooks in there for moving) or any generational stuff.
I think overflow allocation should be easy enough, and defrag should not be too hard in some form or other. The insertion of write barriers for generational control may also be straight-forward using the “operator =”. I may also change the code generation to separate stack variables (local, function args) from member variables since in the current scheme, stack variables never form roots, and therefore would not need to use write-barriers.

Anyhow, on the “Physaxe” test, which creates lots of small list objects per frame, the Naive GC got about 51fps, Boehm GC got about 65fps and IMMIX got about 69fps – so a bit of a win there. For this test, I triggered all collections exactly once per frame. The difference between Naive and IMMIX is significant, and this perfromance gain also translates to the iPhone, which is good news.

Since the internal scheme is precise, I feel it should be able to outperform Boehm GC by a bit more, and maybe the extra could come from a generational system. The code is actually not that complex (1 cpp file, 1 header file) so any budding GC researchers may want to see what they can do.

Currently, the internal GC is default only for the iPhone, but you can try it on other platforms by changing the #define in hxGCInternal.h. The reason for this is the restrictions mentioned above – the easiet way to conform to these restrictions is to enable the “Collect Every Frame” in neash.Lib. To remove these restrictions, I will need to find some way of stopping the world (safe points?) and some way of capturing the stack (code mods to allow objects to push themselves on a shadow stack?), both of which are very doable, although I’m not sure on the effect on performance.

Haxe on the iPhone – For Real!

iphone3 To progress this project a bit further, I needed a real device – so I convinced the little woman that an iPod touch would be a good thing to have around. She seems to have taken to it, so now I’m thinking I may need one each :).

After much phaffing about, I’ve finally managed to get stuff running on the actual device. I had to comment out quite a bit of NME, since I only used the base SDL, not all the extras. Boehm GC was also a bit tricky because I didn’t really know what I was doing, but I brought in some bits from the mono project and then disabled USE_MUNMAP because it caused it to crash. In the end, it seems to work – no crash, but then I may not have been running it long enough. I will have to try some memory thrashing later.

One thing I found with Xcode is that if you ever change the project name/AppID settings then you really need to clean the project, exit Xcode and get back in. But the hardest part was working out where to go the get the developer certificate! I guess I’m a bit thick, or missed the meno, but it took me ages to get to the web form to create a certificate.

So the big question is perfromance. In this demo, initally, it runs at about 2.5 frames a second (I don’t have a fps counter yet), but slows a bit later when things spread out. But this is using the high-quality, anti-aliasing software renderer. Next job is to hook up the OpenGLES renderer, then I’ll really know where I stand.
But overall, pretty positive result I think.

HXCPP 0.2 – Huge performance increase.

I have switched hxcpp over from using ref-counting to using Boehm garbage collection. I have also added some additional perfromance improvements, such as integer-index field names to make interaction with neko more efficient.

The overall result is that for the Physaxe demo, the frame rate went from 24 fps to 82 fps (in opengl mode). The swf file runs at about 35 fps, and neko at about 8 fps. This is about what I was hoping for from the first round, but I got there in the end.

You can download the updated files here.

Boehm GC, virtual inheritance and finalizers.

I’m trying to get a speedup for the cpp backend for haxe by using garbage collection. Initial results are very promising – potentially about twice as fast. Howerver I spent a good few hours getting the the bottom of a little problem. Boehm garbage collection is a very impressive piece of work – it has all sorts of magic that does magical things, such as deal with virtual inheritance. This was a bit of a surprise because you do not always get “real” pointers, when you store an object pointer, you get one with an offset. However it seemed to work. Until I added finalizers to the external draw objectes used by the renderer. Apparently, you can only add finalizers to the “real” pointers (ie, those returned from “GC\_MALLOC” et al), rather than a pointer to the same object related by virtual inheritance. The symptom was that the object gets finalized in the first “gc_collect”, even though it was still “used” as far as I was concerned. I guess this is not too surpising, and the fix was pretty easy, but the fact that everything else worked so well lulled be into not suspecting this initially.