4 ms·
> This, actually, is one of my favorite points. Letting the JVM grab a giant allocation at startup is fine if all you're going to do with your machine is run JV
by flatline3 14y ago
> This, actually, is one of my favorite points. Letting the JVM grab a giant allocation at startup is fine if all you're going to do with your machine is run JVM programs (i.e. a server), but it sucks when you've got multiple apps all trying to play nice together. The OS has a memory management system for a reason. I'd much prefer my runtime use the existing system, than re-invent the wheel (as it were).
The OS memory management system is as general-purpose as possible. At the kernel/process interaction level, the APIs are thin abstractions on the underlying VM page mapping system. Below that, at the malloc level, malloc is designed to be as general purpose allocator as possible, without introducing complexity unsupportable in C, such as migrating allocations across generations.
The JVM's lack of ability to rededicate pages to the OS is a failing of Sun's particular implementation, and is not strictly inherent in the design of generational collectors.
Your argument dismantles Sun's architectural choice when used on mobile hardware, but does not address the relative merits of alternative allocation/collection schemes.
> In regards to the class registration system: "It seems that perfection is reached not when there is nothing left to add, but when there is nothing left to take away"
That response has little substance. It's not perfect, or even great, it's merely functional. I would be enthralled if Mach-O two-level namespacing worked with ObjC classes, but it can not.
> The type encodings are simple C strings!
They're C strings, not particularly simple. Try decoding (with lackluster documentation) a complex structure return value. Modern runtimes use much more cleanly structured, cross-referenced data here.
> If by that you mean that the central message dispatch routine is hand-optimized assembly for each platform the runtime is available on... I'll have some more of that, please!
No, that's not what I mean. You'd find just as much complex hand-optimized assembly code in other runtimes, likely more.
I'm referring to design choices such as the use of unnecessarily complex data structures with minimal if not outright missing API to access them, poorly abstracted implementation details (such as exposing C string type signatures as the highest-level representation of a type encoding), minimal/missing/poorly-defined metadata.
An example is the failure to encode type data in blockrefs in the first public release of blocks for ObjC, which made it impossible to implement imp_implementationWithBlock(), due to the need to differentiation between stret vs non-stret return types and select the appropriate trampoline. This required changes to both the compiler and the runtime, and meant that prior to those changes' introduction by Apple, it would have been impossible for an external entity to implement similar functionality.
This sort of hackish minimalism is the polar opposite of the careful considered and long-term focused design that Microsoft (and even Sun) applied to the core of their platform. Compare the completeness (and longevity) of the JVM Virtual Machine specification to the ObjC runtime. Over roughly the same amount of time, Apple has had to introduce complete ABI-breaking fundamental changes of to their runtime to implement extremely basic language enhancements. In contract, the JVM specification has not, to my recollection, been broken once over the course of 20 years. Additions have always been forward-compatible.
An example of the above would be the addition of non-fragile base classes through the use of minimal ivar access indirection. This required a wholesale breakage of the entire language, and thus could only be introduced on 64-bit Mac OS X and on iOS.
Apple's language and runtime design is hackish at best.
- comex 14y agoI don't buy the comparison. It's a lot easier to avoid breaking things when you're not compiling to native code, but compiling to native code is one of Objective-C's biggest advantages.
- flatline3 14y agoIn contrast, I don't buy that dichotomy. The Objective-C runtime is runtime-heavy, generates a slew of runtime-interpretable data, and yet is compiled "natively" insofar as the body of functions-nee-methods is native. Instance variable access from native code is done through indirection with metadata maintained on their type and offset, dispatch is done through indirection from native code using class metadata, instantiation is done through indirection using the global registration of class metadata. The problem has consistently been in the non-forward-looking design of that structured data, not in the fact that they generate method bodies as native machine code.
- comex 14y agoSince I've been tired the last few days, here's a late reply: Direct pointer offsetting of fragile base classes and statically generated copy/destroy code for blocks in lieu of type information would be fairly unthinkable in a managed language, whose bytecode probably wouldn't be low level enough to even express those designs; it would still have been a good idea to think ahead and use indirection for ivars and include full type information in blocks, but managed language designers never really had the chance to make such mistakes in the first place. For other Objective-C changes, like garbage collection, the changes to code generation would have been unreasonable to make "in advance", but it's hard to imagine an analogous change in a managed language that would require an ABI break. Though Objective-C could have done better, it's a bit unfair to compare it to something like the JVM.