What kind of 'context' are you requesting? A call stack is a general concept, employed in practically speaking all current programming languages. Do you want the context limited to one specific language? One specific hardware platform?
jschell wrote:Lot of text there with no context.
In C/C++ there were library calls that allowed one to chop the stack off. To reset it to a specific point. I never used it, so I don't know why it existed.I never knew of anything like that, and your reference is so unspecific (no function names etc.) that it is difficult to do a search. From what you write, it may sound like a mechanism intended for threads requiring a lot of stack space during initialization, and then enter a 'working' state with small stack requirements, so the stack limit is reduced after init, to make the address space above it available to other threads (started at a later time). I am guessing now, and may be completely wrong, but I can't think of many other uses that makes sense (based on the information you provide).
trønderen wrote: Stack relative addressing never goes outside the current frameI am not sure what you mean by 'overwriting', suspecting that you refer to something similar to out-of-bounds array indexing: If you put a somearray at the very top of the stack, you may index it beyond the limit of the current frame. That is as bad as any other out-of-bounds indexing! Conceptually, you are still within the same stack frame, you are just pretending that the frame is larger than initially allocated. There is no guarantee that the space you are trying to (mis)use is available; you might hit the stack limit.
False. In C and C++ one can overwrite the frame.
In languages with a static link (I haven't been working with any more recent one than Pascal; most newer languages don't have a static link), code of an inner function may address locations in frames lower on the stack. However, they do not do this by negative offsets (or positive, if the stack is growing downwards) from their own frame pointer. Rather, they use the static link to find the stack frame of the outer function, and do relative addressing from that frame base address - as if it was a pointer to a struct. The addressing never goes outside that frame.
Allocations of any sort still require a mechanism to deallocate it. [...] That is why they were (or are) on the stack frame. Because the deallocation is already there.Eh? What's the problem? When a method completes, it returns, whether the frame was allocated edge-by-edge or on the heap. In the former case, you adjust the top of stack register to the top of the previous frame. In the heap case, you move the freelist[x] value to the 'next' field (in the freelist interpretation of 'next') of the frame and store the address of the frame in freelist[x]. In both cases, you set the current stack frame pointer to the previous frame. I don't see any big difference at all!
trønderen wrote: Then, a given amount of RAM would be capable of handling a much larger number of threads.You certainly have not explained why this would be 'wrong'. There may certainly be other limitations on the number of threads, but memory is a significant one. Not in all cases, but quite often. Other limitations may be e.g. number/size of thread descriptors; this is highly OS / runtime system dependent, and need not be neither a hard nor a significant limit.
As stated that is wrong. Memory is not the only limitation for the number of threads.
Not to mention that no developer should ever consider the idea that an unlimited or large number of threads is a 'good' idea.It may be a bad idea, e.g. if the OS/RTS puts a hard limit on the number of descriptors, or the memory cost for each thread is large. Heap allocation may reduce the average memory cost significantly, reducing one limiting factor.
Just noting that I have never seen a computer that actually allows for the full addressable range of 64 bits. Certainly no desktop PC does that.You are certainly confusing 64 address bits with 64 gigabyte, which can be addressed with 36 bits. Current mainboards can handle up to 256 Gi.
And cloud servers are always limited also. Sometimes to very surprising low limits.You are repeating the point I made, except that I referred to embedded systems, not to cloud servers. I used '64 Gi' not as a specific value, just to emphasize that option to add more memory can be extremely limited, compared to a plain desktop PC - most tower cabinet PC users still have empty memory slots on the mainboard and can add more RAM. Not so in an IoT chip.
Because all resources, not just memory, is scarce. If you add complication to the processing model then it will require more resources. There is no way around that.You certainly haven't justified why unlinking a block from a freelist rather than adding to the top of stack register would 'add complication to the processing model'. It is so simple that at least one machine provided it as a single entry point instruction (and a corresponding return instruction), everything else was 100% identical. The purpose of it is to save (memory) resources.
I suspect you will find that the deallocation part is going be complicated but doable.In the ND-500 architecture, it was a single instruction covering both deallocation and return, copying the current freelist[x] into the freed frame and the frame address into freelist[x] - that is not 'complicated but doable'! (The instruction also did all the other return stuff.)
For all heap systems, you must handle splitting of large free blocks to get one of the size you want, and when space runs out, you must recombine smaller, adjacent free blocks. In buddy systems, both are fairly trivial operations. Furthermore, recombination can be done incrementally, e.g when waiting for I/O and no thread is runnable. It is also cheap, especially binary buddy, both for the splitting (as implemented in the ND-500) and recombination.
Following has a response that suggests the same thing.I find it slightly funny that you spend a lot of space and energy to tell me how non-workable my proposal for a heap allocated stack is, and then round it off with a reference to a post documenting that it certainly is a viable alternative and has been used for language as widespread as Java