How does the JVM know how many values to pop into a new frame when invoking a method via invokevirtual? - jvm

When a method is called via invokevirtual, the calling method pops off the values to pass to the called method along with the objectref and places them in the new stack frame.
How does it know which stack entry is the objectref? My guess is that it does so by looking at the type of the called method and parses this to determine how many values to pop off, but this seems extremely inefficient. Is there some other mechanism that I'm overlooking?

When you use the class file format as starting point, the method descriptor is the only way to determine, which values from the operand stack have to become the first local variables of the new stack frame.
As an exception to the rule, the invokeinterface instruction has an embedded count which can be used to determine the number of (type 1) elements to consume. As the documentation states:
The count operand of the invokeinterface instruction records a measure of the number of argument values, where an argument value of type long or type double contributes two units to the count value and an argument of any other type contributes one unit. This information can also be derived from the descriptor of the selected method. The redundancy is historical.
This historical redundancy doesn’t change the fact that the JVM has to cope with method descriptors as the source of this information, e.g. for invokevirtual, invokestatic, invokespecial, or invokedynamic. Further, a conforming JVM is required to verify this information, to throw an error if the invokeinterface’s count differs from the count derived from the method descriptor.
Generally, the verifier is responsible for detecting when method invocations are inconsistent to the stack frame’s state and therefore, has to process the method descriptors and model their effect on the operand stack. This implies that, unless you’re using a JVM that verifies each instruction right before its actual execution, it has to handle these descriptors even without executing an actual invocation. The obvious solution is to convert the method descriptors into an easier-to-process internal representation in a first step.
In short, these method descriptors are inefficient but with a reasonable JVM implementation you’re paying the costs only once, not for every invocation.

There's no one "right" way to do this, but the simplest strategy is to leave the values on the stack, and the called method refers to them via negative offsets. For example, if the called method has 3 params, they're referenced from the base stack offset minus 3, 2, and 1. Each is copied to a local variable and then referenced in the usual manner. The stack offset can be updated to reflect that the params have been consumed. Of course, each local param can also be initially assigned by a bunch of pops, one for each param.
Other tricks can be performed to speed things up. There's no reason that local variables need to be stored differently than the stack. They can be stored on the stack itself. The passed in params occupy their original locations on the stack, and then additional space is allocated for the remaining local variables by just updating the stack offset. A base stack offset is remembered, and all local variables are referenced via the base offset.
Essentially, a local variable is just like a stack slot, except it can be accessed at any time, regardless of what's currently been pushed on top.

Related

How Can I Aware Register Spilling via Objdump File?

How can I be aware of register spilling by looking at an objdump file?
My thought is that it can be done by tracking the stack pointer: moving sp beyond function prologue and epilogue, indicates register spilling.
I want to know which lines of codes are doing register spilling. Also, where are the registers restored pointed to global variable, also stack?
Register spilling doesn't require moving the stack pointer, a local variable may be spilled to the stack and constantly used directly from there while still in the current frame, and the compiler would just use the stack frame with its offset instead of a register.
Your best bet is just looking for memory addresses being read and/or written to constantly. This may even happen where there are available registers around because of compiler deficiencies, or inability to prove that no other thread/code unit are accessing some local variable by addr (for example if the variable address is copied somewhere out of scope). In such cases maintaining that variable in memory is necessary.

what is the stack of a task and what is it used for ? - uC/OS-II

So I am reading from MicroC/OS-II book, but in the section for task stacks I couldn't find exactly what the stack is and most importantly - what is it used for. I know it is not something long and difficult, but I kinda' have to understand it. The book only says how to set the stack size and some other things like this.
So, can somebody explain me in short and simple words what is the task stack and what is it used for, in uC/OS-II ?
In general in the context of a procedural programming language, the stack is where a function/procedure/sub-routine's local variables and return address are stored (in a "stack frame") - the greater the call depth, the more stack frames are stored - one for each function that has not yet returned. That part is true regardless of whether you are using an RTOS such as MicroC/OS-II or not.
In a single threaded environment, only one stack is required, and this is normally provided for you as part of the C runtime environment set-up for example. In a multi-threaded environment, you need a stack for each separate thread of execution, and it is typically up to you to allocate stack space for each thread, or at least to specify its length.
I don't know MicroC/OS-II, but the stack of a task is nearly always the same:
During the execution of a task, it stores data that are required in the current context. This means when a subroutine (method, etc.) is called, a "stack frame" is stored on top of the stack. This stack frame stores local variables of the called subroutine, the return address used when the subroutine is finished, and some other info. When the subroutine returns, the stack frame is deleted. If the subroutine calls another one (or itself recursively), another stack frame is stored on top of the current one.
In contrast to a stack where stored data are deleted in reverse order as the have been stored, a heap stores data a long as their memory is not freed, which can be done in an arbitrary order.
Many processors have a stack pointer, and most of those have instructions that specifically use that stack pointer. The stack pointer is a register that holds an address, not unlike the program counter. The stack is simply memory pointed to by the stack pointer, at a higher level you or the operating system or someone divides the available memory space up for different uses, a little for data a little for program a little for heap (mallocs and frees) and some for the stack. The stack pointer and associated instructions allow code to temporarily allocate some memory. A global variable for example is at least for the life of your program stuck at one memory location. A local variable though only needs a memory location while the function is being executed, when the function returns you dont need that local variable memory (statically defined locals are allocated like globals but only available during that function, so not temporary). You could do a malloc and free in the function to allocate this local memory, or you could simply use the stack. And many/most compilers simply use the stack. In addition to local variables you might need to store the return address, if function a() calls function b() to get from b back to where you were in a you need to return to the next instruction after the call to b(). if B calls c then within the context of b() you need to save the return to a() and now within c() you need to know how to return to b(). And so on. This is architecture and calling convention dependent, some architectures always use the stack for returns, some lean toward using a specific register. When nesting calls though all architectures are going to need to eventually use the stack for the return address, so the stack is used here as well. If function a() calls itself 10 times and has one local integer and the return address lets say it needs 8 bytes of stack per call, so first call moves the stack pointer 8 bytes allocating 8 bytes, the second call another 8 and so on. when you start to hit returns, the the stack pointer moves back 8 bytes, another return another 8 bytes back on the stack pointer.
Now translate that from a single application to multiple applications with the illusion if executing simultaneously (an operating system) for each application/task/procedure/thread/whatever you probably want each of them to have their own stack. This is often quite easy as you just need to save the stack pointer from the prior task and set the stack pointer to the last value from the next task when it was switched out. You can of course get much more complicated and have protection mechanisms so each application can only live within its memory space including stack and heap. and mmus can make it even more complicated by having physical memory chopped up into many pieces and the mmu makes it look like separate pieces are linear within the applications virtual address space. etc.
as nurd_droid pointed out some processors have different stack pointers depending on the mode of the processor. you might have one for user/application mode, then when a system call happens a system/superuser stack pointer, and an interrupt happens an interrupt stack pointer. Some architectures simply have one stack pointer...Some architectures the stack is not in the main memory space the stack and stack pointer are buried in the logic and you dont really see it (often in this case the stack size is quite limited and can roll around on itself or other bad things if you dont manage your stack usage).
Stack is a data structure of type last in first out (LIFO) which is used by procedural languages to do push/pop local variable, CPU registers, return addresses before making a function call or when an interrupt occurs or for preparation of context switches.
Variables, registers are popped out in exactly reverse order when compared to order they are pushed on stack.
Stack can grow upwards or downwards in memory. This is something that will depend upon the micro-controller.
Also, many micro-controllers have multiple stacks.
1) User stack
2) Exception stack or Interrupt stack
If RTOS is used then each process/thread/task will have its own stack. In this case user SP micro-controller register will be reassigned by context switch routine to point to stack for currently active process/thread/task.
Exception stack or Interrupt stack is shared across the system.

Objective-C ParseKit return value

In flex/lex/bison/yacc (all of which I just started reading about), you can set "$$" to be equal to some value ($1,$2,$3) and that's the value that gets returned. At least I think that's how it works.
In ParseKit, you are given a stack so I imagine that the ($1,$2,$3) would be the first three values on the stack for example. But then I think what you would want to do is pop those values off the stack and put your return value on the stack. I see that the stack comes with a push method. Do you have to pop the incoming values first before pushing something on?
Thanks
Developer of ParseKit here. I would say: it depends. A few thoughts:
Yes, it is often useful/desirable to store objects/values on the assembly's stack by calling -[PKAssembly push:] on the assembly sent to your parser delegate callbacks. Later callbacks will find these values on the assembly's stack and may want to take action when they are found.
Another option: if your callback methods are building some result object, you usually want to store it as the -[PKAssembly target] property of the assembly passed into your callback method. So you have two places where you can store values: the assembly's target or the assembly's stack. The target is the 'correct' place for this, but often the stack is also convenient. Either is fine, but i would say: store temp values on the stack, but store the ultimate object you are building as the target. But again, you can do either.
Yes, your callbacks should often want to pop values off the stack first, but that is not required. Think of if this way: Your delegate callback method receives a PKAssembly object as a parameter. And usually your callback method will inspect the assembly's stack and take action depending on what it finds there. Usually, in your callback, you'll want to pop the values you find there, if you are taking action on them. Basically: your callback should pop the values it is interested in/taking action on, because in some sense your callback was the intended recipient of those items/information.

OOP question about functions that struck me all of a sudden

May be my question is stupid. But i would like to get it cleared. We know that functions are loaded in memory only once and when you create new objects, only instance variables gets created, functions are never created. My question is, say suppose there is server and all clients access a method named createCustomer(). Say suppose all clients do something which fired createCustomer on server. So, if the method is in middle of execution and new client fires it. Will the new request be put on wait? or new request also will start executing the method? How does it all get managed when there is only one copy of function in memory? No book mentions answers to this type of questions. So i am posting here where i am bound to get answers :).
Functions are code which is then executed in a memory context. The code can be run many times in parallel (literally in parallel on a multi-processor machine), but each of those calls will execute in a different memory context (from the point of view of local variables and such). At a low level this works because the functions will reference local variables as offsets into memory on something called a "stack" which is pointed to by a processor register called the "stack pointer" (or in some interpreted languages, an analog of that register at a higher level), and the value of this register will be different for different calls to the function. So the x local variable in one call to function foo is in a different location in memory than the x local variable in another call to foo, regardless of whether those calls happen simultaneously.
Instance variables are different, they're referenced via a reference (pointer) to the memory allocated to the instance of an object. Two running copies of the same function might access the same instance variable at exactly the same time; similarly, two different functions might do so. This is why we get into "threading" or concurrency issues, synchronization, locks, race conditions, etc. But it's also one reason things can be highly efficient.
It's called "multi-threading". If each request has its own thread, and the object contains mutable data, each client will have the opportunity to modify the state of the object as they see fit. If the person who wrote the object isn't mindful of thread safety you could end up with an object that's in an inconsistent state between requests.
This is a basic threading issue, you can look it up at http://en.wikipedia.org/wiki/Thread_(computer_science).
Instead of thinking in terms of code that is executed, try to think of memory context of a thread that is changed. It does not matter where and what the actual code happens to be, and if it is the same code or a duplicate or something else.
Basically, it can happen that the function is called while it was already called earlier. The two calls are independent and may even happen to run in parallel (on a multicore machine). The way to achieve this independence is by using different stacks and virtual address spaces for each thread.
There are ways to synchronize calls, so additional callers have to wait until the first call finishes. This is also explained in the above link.

How does it know where my value is in memory?

When I write a program and tell it int c=5, it puts the value 5 into a little bit of it's memory, but how does it remember which one? The only way I could think of would be to have another bit of memory to tell it, but then it would have to remember where it kept that as well, so how does it remember where everything is?
Your code gets compiled before execution, at that step your variable will be replaced by the actual reference of the space where the value will be stored.
This at least is the general principle. In reality it will be way more complecated, but still the same basic idea.
There are lots of good answers here, but they all seem to miss one important point that I think was the main thrust of the OP's question, so here goes. I'm talking about compiled languages like C++, interpreted ones are much more complex.
When compiling your program, the compiler examines your code to find all the variables. Some variables are going to be global (or static), and some are going to be local. For the static variables, it assigns them fixed memory addresses. These addresses are likely to be sequential, and they start at some specific value. Due to the segmentation of memory on most architectures (and the virtual memory mechanisms), every application can (potentially) use the same memory addresses. Thus, if we assume the memory space programs are allowed to use starts at 0 for our example, every program you compile will put the first global variable at location 0. If that variable was 4 bytes, the next one would be at location 4, etc. These won't conflict with other programs running on your system because they're actually being mapped to an arbitrary sequential section of memory at run time. This is why it can assign a fixed address at compile time without worrying about hitting other programs.
For local variables, instead of being assigned a fixed address, they're assigned a fixed address relative to the stack pointer (which is usually a register). When a function is called that allocates variables on the stack, the stack pointer is simply moved by the required number of bytes, creating a gap in the used bytes on the stack. All the local variables are assigned fixed offsets to the stack pointer that put them into that gap. Every time a local variable is used, the real memory address is calculated by adding the stack pointer and the offset (neglecting caching values in registers). When the function returns, the stack pointer is reset to the way it was before the function was called, thus the entire stack frame including local variables is free to be overwritten by the next function call.
read Variable (programming) - Memory allocation:
http://en.wikipedia.org/wiki/Variable_(programming)#Memory_allocation
here is the text from the link (if you don't want to actually go there, but you are missing all the links within the text):
The specifics of variable allocation
and the representation of their values
vary widely, both among programming
languages and among implementations of
a given language. Many language
implementations allocate space for
local variables, whose extent lasts
for a single function call on the call
stack, and whose memory is
automatically reclaimed when the
function returns. (More generally, in
name binding, the name of a variable
is bound to the address of some
particular block (contiguous sequence)
of bytes in memory, and operations on
the variable manipulate that block.
Referencing is more common for
variables whose values have large or
unknown sizes when the code is
compiled. Such variables reference the
location of the value instead of the
storing value itself, which is
allocated from a pool of memory called
the heap.
Bound variables have values. A value,
however, is an abstraction, an idea;
in implementation, a value is
represented by some data object, which
is stored somewhere in computer
memory. The program, or the runtime
environment, must set aside memory for
each data object and, since memory is
finite, ensure that this memory is
yielded for reuse when the object is
no longer needed to represent some
variable's value.
Objects allocated from the heap must
be reclaimed—especially when the
objects are no longer needed. In a
garbage-collected language (such as
C#, Java, and Lisp), the runtime
environment automatically reclaims
objects when extant variables can no
longer refer to them. In
non-garbage-collected languages, such
as C, the program (and the programmer)
must explicitly allocate memory, and
then later free it, to reclaim its
memory. Failure to do so leads to
memory leaks, in which the heap is
depleted as the program runs, risking
eventual failure from exhausting
available memory.
When a variable refers to a data
structure created dynamically, some of
its components may be only indirectly
accessed through the variable. In such
circumstances, garbage collectors (or
analogous program features in
languages that lack garbage
collectors) must deal with a case
where only a portion of the memory
reachable from the variable needs to
be reclaimed
There's a multi-step dance that turns c = 5 into machine instructions to update a location in memory.
The compiler generates code in two parts. There's the instruction part (load a register with the address of C; load a register with the literal 5; store). And there's a data allocation part (leave 4 bytes of room at offset 0 for a variable known as "C").
A "linking loader" has to put this stuff into memory in a way that the OS will be able to run it. The loader requests memory and the OS allocates some blocks of virtual memory. The OS also maps the virtual memory to physical memory through an unrelated set of management mechanisms.
The loader puts the data page into one place and instruction part into another place. Notice that the instructions use relative addresses (an offset of 0 into the data page). The loader provides the actual location of the data page so that the instructions can resolve the real address.
When the actual "store" instruction is executed, the OS has to see if the referenced data page is actually in physical memory. It may be in the swap file and have to get loaded into physical memory. The virtual address being used is translated to a physical address of memory locations.
It's built into the program.
Basically, when a program is compiled into machine language, it becomes a series of instructions. Some instructions have memory addresses built into them, and this is the "end of the chain", so to speak. The compiler decides where each variable will be and burns this information into the executable file. (Remember the compiler is a DIFFERENT program to the program you are writing; just concentrate on how your own program works for the moment.)
For example,
ADD [1A56], 15
might add 15 to the value at location 1A56. (This instruction would be encoded using some code that the processor understands, but I won't explain that.)
Now, other instructions let you use a "variable" memory address - a memory address that was itself loaded from some location. This is the basis of pointers in C. You certainly can't have an infinite chain of these, otherwise you would run out of memory.
I hope that clears things up.
I'm going to phrase my response in very basic terminology. Please don't be insulted, I'm just not sure how proficient you already are and want to provide an answer acceptable to someone who could be a total beginner.
You aren't actually that far off in your assumption. The program you run your code through, usually called a compiler (or interpreter, depending on the language), keeps track of all the variables you use. You can think of your variables as a series of bins, and the individual pieces of data are kept inside these bins. The bins have labels on them, and when you build your source code into a program you can run, all of the labels are carried forward. The compiler takes care of this for you, so when you run the program, the proper things are fetched from their respective bin.
The variables you use are just another layer of labels. This makes things easier for you to keep track of. The way the variables are stored internally may have very complex or cryptic labels on them, but all you need to worry about is how you are referring to them in your code. Stay consistent, use good variable names, and keep track of what you're doing with your variables and the compiler/interpreter takes care of handling the low level tasks associated with that. This is a very simple, basic case of variable usage with memory.
You should study pointers.
http://home.netcom.com/~tjensen/ptr/ch1x.htm
Reduced to the bare metal, a variable lookup either reduces to an address that is some statically known offset to a base pointer held in a register (the stack pointer), or it is a constant address (global variable).
In an interpreted language, one register if often reserved to hold a pointer to a data structure (the "environment") that associates variable names with their current values.
Computers ultimately only undertand on and off - which we conveniently abstract to binary. This language is the basest level and is called machine language. I'm not sure if this is folklore - but some programmers used to (or maybe still do) program directly in machine language. Typing or reading in binary would be very cumbersome, which is why hexadecimal is often used to abbreviate the actual binary.
Because most of us are not savants, machine language is abstracted into assembly language. Assemply is a very primitive language that directly controls memory. There are a very limited number of commands (push/pop/add/goto), but these ultimately accomplish everything that is programmed. Different machine architectures have different versions of assembly, but the gist is that there are a few dozen key memory registers (physically in the CPU) - in a x86 architecture they are EAX, EBX, ECX, EDX, ... These contain data or pointers that the CPU uses to figure out what to do next. The CPU can only do 1 thing at a time and it uses these registers to figure out what to do next. Computers seem to be able to do lots of things simultaneously because the CPU can process these instructions very quickly - (millions/billions instructions per second). Of course, multi-core processors complicate things, but let's not go there...
Because most of us are not smart or accurate enough to program in assembly where you can easily crash the system, assembly is further abstracted into a 3rd generation language (3GL) - this is your C/C++/C#/Java etc... When you tell one of these languages to put the integer value 5 in a variable, your instructions are stored in text; the assembler compiles your text into an assembly file (executable); when the program is executed, the program and its instructions are queued by the CPU, when it is show time for that specific line of code, it gets read in the the CPU register and processed.
The 'not smart enough' comments about the languages are a bit tongue-in-cheek. Theoretically, the further you get away from zeros and ones to plain human language, the more quickly and efficiently you should be able to produce code.
There is an important flaw here that a few people make, which is assuming that all variables are stored in memory. Well, unless you count the CPU registers as memory, then this won't be completely right. Some compilers will optimize the generated code and if they can keep a variable stored in a register then some compilers will make use of this!
Then, of course, there's the complex matter of heap and stack memory. Local variables can be located in both! The preferred location would be in the stack, which is accessed way more often than the heap. This is the case for almost all local variables. Global variables are often part of the data segment of the final executable and tend to become part of the heap, although you can't release these global memory areas. But the heap is often used for on-the-fly allocations of new memory blocks, by allocating memory for them.
But with Global variables, the code will know exactly where they are and thus write their exact location in the code. (Well, their location from the beginning of the data segment anyways.) Register variables are located in the CPU and the compiler knows exactly which register, which is also just told to the code. Stack variables are located at an offset from the current stack pointer. This stack pointer will increase and decrease all the time, depending on the number of levels of procedures calling other procedures.
Only heap values are complex. When the application needs to store data on the heap, it needs a second variable to store it's address, otherwise it could lose track. This second variable is called a pointer and is located as global data or as part of the stack. (Or, on rare occasions, in the CPU registers.)
Oh, it's even a bit more complex than this, but already I can see some eyes rolling due to this information overkill. :-)
Think of memory as a drawer into which you decide how to devide it according to your spontaneous needs.
When you declare a variable of type integer or any other type, the compiler or interpreter (whichever) allocates a memory address in its Data Segment (DS register in assembler) and reserves a certain amount of following addresses depending on your type's length in bit.
As per your question, an integer is 32 bits long, so, from one given address, let's say D003F8AC, the 32 bits following this address will be reserved for your declared integer.
On compile time, whereever you reference your variable, the generated assembler code will replace it with its DS address. So, when you get the value of your variable C, the processor queries the address D003F8AC and retrieves it.
Hope this helps, since you already have much answers. :-)