We have dealt with the complete life cycle of a full-fledged retail SDK comprised from (among other things) C and C++ compilers developed from scratch: design, implementation, and support.

The said compilers were optimizing (multiple-pass) and re-targetable: they had back-ends for the Hitachi H8S and Motorola 68k family of CPUs, as well as Intel x86.

 

Own C/C++ compilers developed from scratch

These compilers were not modifications of GNU C/C++, or any other compiler, but completely new designs.

The need for these compilers arose from the necessity to create a functionally rich system for a very limited platform based on Hitachi H8S 32-bit processor. The amount of memory available to applications was a mere 128k! This drove the decision to build compiler(s) with bytecode back-end, allowing us to generate bytecode four (!) times as small as native code. Other system highlights: Optimizing, multiple-pass compilers

  • Re-targetable back-end, ultimately implemented for Intel x86, Motorola 68k (Palm), Hitachi H8S, along with the original bytecode generator
  • Unique ability to switch between generating bytecode and native code with #pragma's
  • Register (vs. stack) bytecode interpreter model, allowing for very fast bytecode execution
  • Bytecode interpreter as small as 400 bytes (yes, bytes, not kilobytes
  • Optimizing assembler (see below)

Even C compiler had "object extensions" making it simple, reliable, and efficient to implement features like in-game objects.

C++ compiler has had implementations of almost all modern features (including inheritance, strong type system, etc.), except exceptions and templates.

The package had its own C pre-processor, linker, and... optimizing assembler. The assembler would "profile" every module and:

  • Collect statistics on the most frequently used bytecode instructions, providing information necessary to prioritize which bytecodes should be the most optimized
  • Collect statistics on most frequent bytecode pairs not separated by a label and therefore providing hints as to what new bytecode instructions – functional equivalents of bytecode pairs – to introduce
  • Replace bytecode pairs having single-bytecode equivalents with those equivalents, thus performing both size and execution speed optimization

Extendable scripting languages tailored for specific applications

With modern software, power and flexibility is often synonymous to scripting. Just think about Microsoft's VBA, Autodesk MAX script, and ActionScript of Adobe Flash.

We can help you unleash that power for your applications.

Furthermore, we can also tailor our generic script engine to your applications' specific needs, meaning:

  • Introduction of application-specific data types (e.g. implement a particular type of image, or a sound, as base data type)
  • Introduction of application-specific methods, procedures, or even operators
  • Introduction of application-specific interfaces within interpreter's sandbox

Industrial-strength resource management

The term "industrial-strength" applied to "resource management" in this particular case means that:

  • Resource management is efficient. For instance, by default, assignment of a variable of type 'image' to another variable of same type would not lead to data copying; instead, just the reference count will be incremented
  • Resource management is rubust: destruction (e.g. going out of scope) of the last variable/reference to a resource would deallocate that resource ("garbage collection")
  • Resource management is flexible: almost any type can be converted to almost any other type whenever necessary
  • Resource management is extendable: for every script data type there is a C/C++ equivalent; script language can be extended with native procedures accepting and returning such data types

Java machines (KVM) and tools

Our experience is not limited to the development of C/C++ compilers and interpreters.

We have had experience with custom Java machines development (KVMs), and are familiar with Sun's certification process.

Also, we have experience with tools facilitating Java to C/C++ porting (e.g. semi-automated code translation).

We have developed other related tools, like Java class decompilers and Java preprocessors. The latter comes in handy on projects requiring extra flexibility (conditional preprocessing) or efficiency (compile-time expression folding, etc.)

 

Optimization techniques

Knowing exactly how compilers and interpreters work helps us understand how to write optimum code, both in size and speed. However, sometimes it's necessary to bring in the heavy artillery:

In this case, the "heavy artillery" is, of course, Intel's VTune — the profiler that can help squeeze every last cycle out of one's application.

A brief account of how VTune helped us optimize POVPro application and make it 5% to 50% faster than its "official" predecessor (POV-Ray, the photorealistic ray tracer), can be read here.

Portability

Whatever we build, we build it with portability in mind. A good example is our SDKs: they run on Windows and Linux, and their C/C++ compilers have back-ends for Intel, Motorola, and Hitachi CPUs.

To achieve such level of portability, we:

  • Explicitly subdivide the code into platform-agnostic and platform-dependent parts
  • Do not use compiler-specific features, and stick to ISO standards
  • Implement I/O in endianness-agnostic way (e.g. read words byte by byte, so that is works on both LE and BE systems)
  • Try not to use even standard language features not found in other languages; for instance, we try to only use C++ templates to implement generic containers and such — this way, we make sure C++ code is quite portable to even Java
  • ... and so on, and so forth

     

 

 


Mobile/Emerging Platforms
 :  Web Solutions  :  CGI  :  Systems Programming  :  Development Tools & Scripting  :  Process Control  :  Company Info  :  Contact us  :  Home

Website copyright © 2009 Cyberhull - Web design Mantravisual