R
Roedy Green
Jumps come is 8, 16 and 23 bit signed offsets.
should read
Jumps come is 8, 16 and 23 bit signed offsets.
Roedy Green said:There is also the lload_0 ... lload_3 instructions that are special
shortcuts for pushing the long value of the first four local variable
32-bit slots onto the stack. Local variables I believe are either
parameters or locals.
But I thought it was determined that the stack consists of objects, so
it's pushing references to the first 4 objects? Then it would have
to convert say an int to Integer to make this work?
When a method returns, it pops its locals off the stack and restores
the instruction pointer to what it used to be in the caller.
I forget who pops the parameters, the caller or the callee. I vaguely
recall the callee.
Remember BALR 12,13? And the STM 11,15 which typically proceeded?
Yes, it's normally up to the callee to reset the stack to the
state upon calling, although it can set it up by a fullword in
order to store the return value...
Was that fun or what?!
(most youngsters will find themselves asking WHAT?)
I have seen in various places reference to a 'stack'
But what is a stack? Is it a machine specific
implementation of something, is it a machine hardware
feature/capability? One remark in a book on Java
Performance Tuning*, says that there are special
instructions that make it more efficient to use
the first 4 variables on the stack.
Sudsy said:Roedy Green wrote:
Remember BALR 12,13? And the STM 11,15 which typically proceeded?
Liz said:Hi Liz,
A stack is a very basic data structure that is implemented in Java
with the type Stack. In Java (and in most other languages that
implement a stack type data structure), you use the method
push(Object) to "add" an item to the stack and the method pop() to get
items off of it. If you've ever been to a school cafeteria or an
all-you-can-eat buffet, a stack is like the thing you get your plate
out of before going down the line, or buffet. It is called a
last-in-first-out structure in that the last thing you "push()"ed onto
it will be the first thing that "pop()"s off. It can be very useful
at times but the main gist of it can be seen below:
int forwardArray[] = {1, 2, 3};
Stack reversingStack = new Stack(); //stacks are created empty
for (int i=0; i < forwardArray.length; i++) {
reversingStack.push(new Integer(forwardArray));
}
int reverseArray = new int[forwardArray.length];
for (int i=0; i < reverseArray.length; i++) {
reverseArray = reversingStack.pop().getIntValue();
}
reverseArray will now be: {3, 2, 1}
This code is not guaranteed to compile as I haven't tested it. It's
here to give you a feel for how a stack works. For more information,
check out the Java API at http://java.sun.com
Hope this helps!
-Patrick
OP => "... there are special instructions that make it more
efficient to use the first 4 variables on the stack."
So what are these instructions and what is so special
about the first 4 variables on the stack?
Finally, someone is making some sense. It takes me back a few years.Sudsy said:Roedy Green wrote:
Remember BALR 12,13? And the STM 11,15 which typically proceeded?
Yes, it's normally up to the callee to reset the stack to the
state upon calling, although it can set it up by a fullword in
order to store the return value...
Was that fun or what?!
(most youngsters will find themselves asking WHAT?)
Roedy Green said:He is referring to the IBM 360, a machine without hardware stack
instructions. The calling convention was pretty frightening.
IIRC, the called routine did a call to getmain, to allocate some RAM
on the heap for a save area and for local variables. Then it would
save all the registers in that area. BALR 12,13 would jump to the
address in register 13 and store the return addresess in register 12.
That was the end of hardware support for subroutine calls.
It is not quite as crazy as it sounds. In the BBL forth compiler I
used two different call mechanisms one for branch to branch and one
for branch to leaf. The branch to leaf, instead of pushing the return
address to the stack, I left it in a register. On the old 8086 this
carved quite a few cycles off the call/ret. (A leaf is a method that
does no calls of its own.) In the grand scheme of things the most
common calls are branch to leaf.
I have seen in various places reference to a 'stack'
But what is a stack?
there are special
instructions that make it more efficient to use
the first 4 variables on the stack.
Other people have given good and interesting responses, but the
following point seems to be getting lost from time to time (though
at least one person has I think pointed it out): There is a
difference between "a stack" and "the stack".
Roedy Green said:The JVM can get at the top four elements of the stack more efficiently
that those deeper. These are typically intermediate results in a
calculation. Java does not use Top of stack relative addressing to
get at the local variables. It uses frame relative addressing. This
makes manually understanding JVM code easier, but I think created
needless overhead.
Roedy Green said:No, the stack at the JVM level contains primitives and references to
objects, not the objects themselves. The objects live on the heap.
The stack is a hodgepodge of different types, in an ever changing
order, verified sane by the byte code verifier before execution
starts.
Each time a method starts, it nails down sufficient space for its
local variables on the tail end of the stack, then does uses the space
past that for computation working storage. When it calls a method it
pushes the params to the top of the stack and then calls the method,
which will leave the return address on the stack so it can get back
when it is done.
When a method returns, it pops its locals off the stack and restores
the instruction pointer to what it used to be in the caller.
I forget who pops the parameters, the caller or the callee. I vaguely
recall the callee.
In real life, things can be more complex. You can have separate
stacks for return addresses, parameters, floating point etc. So long
as the scheme effectively simulates the JVM, it is kosher. The JVM
spec gives plenty of latitude. All that counts is the net effect, not
precisely how it is pulled off.
But that is making assumptions about what the JIT or hotspot compiler will
do. It can do whatever it wants. It might not even put the local variables
on the stack. It could use registers for a local variable and or for
intermediate results. It might use top of stack relative addressing if it
wanted to. That's one of the things that is so great about vitual machines.
It can optimize to the specific architecture that it is running on.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.