Skip to main content
17 events
when toggle format what by license comment
May 23, 2017 at 12:40 history edited CommunityBot
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Apr 12, 2017 at 7:31 history edited CommunityBot
replaced http://programmers.stackexchange.com/ with https://softwareengineering.stackexchange.com/
Nov 12, 2015 at 7:26 comment added Luaan You can always attach a debugger after the application starts, giving you the real instructions executing - I'm not actually using AOT, this is all based on JITter output. It's a bit harder to read than IL, of course. However, I don't doubt that Mono is still far behind the "real" CLR implementation - I know that it has many issues with memory management, it wouldn't be a surprise if it's assembly generation was also more limited. It does mean you have to write silly code once in a while if you're targeting Mono :)
Nov 11, 2015 at 18:44 comment added user40980 @Luaan as I run on a mac, the only visibility I have into IL is mono, which is a virtual machine much like the JVM. I don't get AOT compilation and optimizations - I can only see to the level of what gets passed to the JIT if it is done at all (and given the development environment for the mac for .net, that isn't a trivial thing). What I do see is that the IL layer allocates space for each distinct variable used within the entire scope of the method, and that is what is executed on my machine.
Nov 11, 2015 at 15:32 comment added Luaan Don't stop at the IL level. When looking at the actual x86 assembly produced from that code, the locals don't exist anymore - just the simple "pass-by-ecx" code. IL is just a high-level intermediate language, it rarely looks anything like the resulting x86 code. In fact, locals are only rooted until they are no longer used - if the two locals existed, one would be reused regardless of scoping. Even replacing the constants with a Console.ReadLine avoids the stack entirely. IL is just a description of the program, not a bullet-list. IL uses the stack for everything, the x86 result doesn't.
Nov 11, 2015 at 3:42 comment added user40980 @5gon12eder I dug into it a bit more. While C and C++ register allocation is well done with AOT compilation, languages that go to a byte code appear to allocate space for all of the variables used within the scope of the method, even if the variables themselves have mutually exclusive sub-scopes.
Nov 11, 2015 at 3:41 comment added user40980 @ratchetfreak I've adjusted the code and shown both the .net IL and the decompiled method header for the JVM. They are both allocating space for all the inner scopes at the top of the method declaration, even if you aren't using them at the same time.
Nov 11, 2015 at 3:39 history edited user40980 CC BY-SA 3.0
added 2187 characters in body
Nov 10, 2015 at 21:31 comment added user40980 @5gon12eder If you are allocating a dozen {} blocks within the scope of one method with a few variables in each, this could get expensive on the stack. Granted, there are other problems if you have a method with that much complexity in it. This just adds to the problems.
Nov 10, 2015 at 21:26 comment added 5gon12eder While I don't think that anything said in the answer or the comments is wrong, I wouldn't let these concerns guide my programming style (at least not at the expense of readability) unless I had evidence that there is a measurable effect in a particular case I care about. Register allocation is a very well studied field and your compiler is likely to do a much better job than you.
Nov 10, 2015 at 20:47 comment added user40980 @Deduplicator In Java, inlining is done by the JIT, not javac. So... it gets tricky again. I am curious though to dig into this and find out what is really going on with the breaking down the bytecode for a class that has this behavior and poking at the JIT internals to turn on debugging to see if I can tease out the "this is what is happening." Though again, this "work" thing during the day can be quite distracting.
Nov 10, 2015 at 20:44 comment added Deduplicator Well, if there's inlining going on, it's quite likely all variables for the function and all inlined functions are allocated in one go for efficiency.
Nov 10, 2015 at 15:05 comment added user40980 @JAB that depends on the compiler. In gcc with similar code, both are allocated qux and baz are assigned just a register, and its the same register in each case. With .net IL and Java bytecode, it is likely to allocate the space and then allow JIT to do the escape analysis on it which is much harder to dig into.
Nov 10, 2015 at 15:02 comment added user40980 @ratchetfreak that was explored a bit in chat around that time and a bit awkward to extract. My example is really pushing the envelope of it (though I'll dig into the Java byte code and .net IL when I can more easily work on that without the distractions of this 'work' thing).
Nov 10, 2015 at 15:02 comment added JAB "This allocates the space for three integers at the initialization of the function foo" Couldn't a compiler that accounts for variable liveness, observing that qux and baz are never in scope at the same time, just reuse the space? Variable names are just tools to assist the programmer, the compiler doesn't need to preserve them (and in most compiled languages, it doesn't unless you embed symbols for debugging).
Nov 10, 2015 at 14:59 comment added ratchet freak That analysis only considers different types in different blocks but doesn't test your variant.
Nov 10, 2015 at 14:50 history answered user40980 CC BY-SA 3.0