News for hackers. Stuff that matters.
Re: by saagarjha on Tuesday April 30, 2024 @04:52AM (#40208670)
Have to admit I'm a little confused by this blog post. I think the target audience is people working in managed languages (e.g. on the web?), especially given the part about primitive types and objects in the intro. In that case, "stack" and "heap" are kind of different from what the native stack and heap are. Often your (runtime-allocated) stack will contain just data and be in the heap. However, if you read the rest of the blog post it is clearly talking about native code. (Though, I will note that not just GPRs get spilled on the stack: it also contains locals.) I guess this could be useful to introduce some terms that people use when talking about memory management, but there's no tie to "my language", because it doesn't really pick one. So it's difficult to generalize from what it talks about or put it to use because languages do things differently.
Re: by leononame on Tuesday April 30, 2024 @05:22AM (#40208874)
Isn't that stack/heap distinction between managed and native code just a technicality? I mean, for native code, your stack is also just allocated space in memory, right?

Similarly, your stack in a managed language is allocated on the heap of the runtime itself, sure. But in the end, once the managed code starts running, for the code itself it's a stack. Or am I mistaken and there is some special handling of stack memory vs heap memory? As far as I understand, the stack is just a big preallocated block of memory that we start filling up.

I agree that the rest of the article is pretty thin, though. It goes into managed code mentioning a tracing GC and reference counting, but doesn't even really explain what it is and doesn't explain memory management at all.

I would've expected different allocation strategies like arenas, but this is disappointing

Re: by gpderetta on Tuesday April 30, 2024 @06:50AM (#40209528)
The difference is in the name. Stack allocation is strictly FIFO [1], so it can be implemented very efficiently with just incrementing and decrementing a stack pointer, even on architectures that don't directly have an hardware stack. In principle that stack for local variables doesn't even need to be the same stack as the callstack. It is also strictly thread local.

On the other hand an heap (which has nothing to do with the heap data structure) is much more complex.

[1] At least across activation frames, of course a compiler can statically generate code that reuses frame slots in a non-FIFO way.

Re: by bregma on Tuesday April 30, 2024 @06:33AM (#40209386)
Yes, memory is memory in the same sense that exponentiation is just repeated addition of 1 to number. The article isn't really talking about memory so much as discussing storage, which is often colloquially called 'memory' by people who do not deal with it directly.

What the article is trying to do is to distinguish between scoped storage and non-scoped storage. Those are two of the 4 types of storage used in a modern programming language abstract machine. All of the 4 types of storage have backing memory allocated in different ways and at different times an initialized through different sequences, but also on modern processors are usually processed in registers, which are synchronized to their backing store through various levels of cache in different ways as well. The article is a very simplistic introduction to basic abstract storage concepts targeted at a complete beginner.

I would have expected an article about memory management to discuss the different types of memory, or maybe cacheing, or about how memory allocation and garbage collection works. But it's fine as a very high-level introduction to how storage works in a typical programming language abstract machine.

Re: by weinzierl on Tuesday April 30, 2024 @05:40AM (#40208996)
"I mean, for native code, your stack is also just allocated space in memory, right?"

Yes. At least on Linux the thread stacks and the memory on the heap are usually allocated with the same syscall (mmap) even. So, the difference is not a question of provenance but how the memory is managed. The native stack is the one the (hardware register) stack pointer points to and there can only be one per thread.

Since this stack's management is hardware supported it can be very fast and efficient. Of course, nothing prevents you from having as many stacks on the heap as you like and manage them yourself. From all I know this is not what managed languages do, but I think they still rely on the amenities of the hardware supported stack.