Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In the late 2000s I worked for a small NZ company, Innaworks, who developed a tool to automatically port J2ME mobile phone apps (mostly games) to BREW, Qualcomm's C++ environment for phones.

The number of handset bugs we had to work around was immense. One handset, the Samsung A790, would reboot if you drew text on an offscreen buffer. Another, the Samsung N330 which we nicknamed the "shaver phone" for obvious reasons[1], ignored a few least significant bits of the source x coordinate when you did a bitblt from an offscreen bitmap to the screen, IF the offscreen bitmap had fewer than 4 bits per pixel.

We ended up writing our own graphics code that wrote into the BREW backbuffer, set the damage rectangle, and asked BREW to blit that to the screen for us. This was much faster than the BREW runtime's graphics code, so games ported via our automated system often ran faster than "hand-ported" games.

The LG AX260 would crash with an error screen if you used threading -- I suspect an ISR would notice the stack pointer was in the heap and halt the phone. This was a BREW 3 phone, and BREW 3 actually had a threading API, so we thought maybe the solution was to use the real threading API instead of setjmp/longjmp. No, BREW 3 threads froze the phone too. We worked around the problem with some help from memcpy and some rather evil stack pointer manipulation. Our stacks were pretty small as all Java objects were allocated on the heap, so this wasn't as bad a performance issue as you'd think. I refactored the scheduler to avoid stack copies if it decided to keep running the current thread.

The worst bug I remember, though, was in the ARM RealView C++ compiler. It optimized out a null pointer check -- you could write to the logfile the pointer value, write to the logfile from the exception throwing code ... which never ran. I eventually got the compiler to generate an assembly listing for the function in question and discovered that no null pointer check code was there. One volatile keyword later and we were back in business.

Our customers loved the product because it just worked. We supported full Java semantics, all the way down to static initializer ordering. It was a simple choice to make -- the more robust our system was, the fewer support incidents for us and the happier the customers. We produced human-readable C++ code so you could run your app in a debugger if need be, and did some clever whole-program optimization. Our runtime was a real memory miser as a "400k" Java handset would have 400k of heap -- code and images tended to live outside that. We could compile a game for a 400k Java handset to run on a 400k BREW handset -- 400k for our runtime, the user's code, the heap, image data, audio data... I vividly remember the time I saved a whole kilobyte of RAM -- that was a major win.

I worked with the smartest people I ever have at that company. I've never been in an environment where everyone was just brimming over with technical adeptness. And we weren't just a company of young things, there were a few over 40s there too.

[1] http://www.cnet.com/au/products/samsung-sch-n330-verizon-wir...



Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: