I'm currently attempting to learn HLA. Everything I write and compile ends up with 32megs of virtual memory (WinXP Home - checking with taskmanager - processes tab). Is there something I'm missing? I've looked through the docs (AoA and WinProg in Assembly) and can't find any mention of why this would be. It doesn't seem to matter whether it's a windows program or dos (compiled with -w or without). Which headers included don't seem to matter either.

Example Code:

Program DemoVars;

#include( "stdlib.hhf" );

static

InitDemo: int32 := 5;

NotInitialized: int32;

begin DemoVars;

// Display the value of the pre-initialized variable:

stdout.put( "InitDemo's value is ", InitDemo, nl );

// Input an integer value from the user and display that value:

stdout.put( "Enter an integer value: " );

stdin.get( NotInitialized );

stdout.put( "You entered: ", NotInitialized, nl );

end DemoVars;

// Program 2.2 Variable Declaration and Use
Posted on 2004-01-15 00:45:24 by CRH668
HLA automatically generates a link response file that allocates 16 megs of heap and 16 megs of stack = 32 megs.

If you wish, you can change these values by editing the <your_prog.link file and re-linking the program, assuming your make or batch file don't automatically delete the HLA generated temporary files.


Review the HLA Reference manual for more information.
Posted on 2004-01-15 01:39:01 by Kain
Another factor is that your application will be using a number of DLLs using a number of other DLLs. This has the effect that most apps, HLA or not, will show up as using at least some 3-4 megs of memory. Don't despair, though, most of this will be memory that is shared between procsses, and as such isn't gobbling up physical memory.

HLA preallocates 16 megs of stack? Whoa :P
Posted on 2004-01-15 03:23:35 by f0dder

Another factor is that your application will be using a number of DLLs using a number of other DLLs. This has the effect that most apps, HLA or not, will show up as using at least some 3-4 megs of memory. Don't despair, though, most of this will be memory that is shared between procsses, and as such isn't gobbling up physical memory.

HLA preallocates 16 megs of stack? Whoa :P


Not HLA, the linker response file.
Very easy to change.
Cheers,
Randy Hyde
Posted on 2004-01-15 13:24:16 by rhyde
Well, I still assume it's a HLA-specific thing?
What's the reasoning behind choosing such a large prealloc size?

I'm just curious, that's all :)
Posted on 2004-01-15 13:35:31 by f0dder
It's large enough that most programs that student's/beginners can come up with will run with no problems. The average user does not have to worry about linking, that happens in the background.

A more advanced user can easily tweak the settings to their hearts content.
Posted on 2004-01-15 16:43:04 by Kain

It's large enough that most programs that student's/beginners can come up with will run with no problems. The average user does not have to worry about linking, that happens in the background.

A more advanced user can easily tweak the settings to their hearts content.


Kain hit the nail mostly right on the head.
The default Windows allocation of 1 meg each (heap and stack) has created problems for some student projects in the past. So I defaulted it to 16 MBs each to stay out of trouble. This is just for safety reasons, much like the default is to generate code to build a display and align the stack upon entry into a procedure. Most people don't notice or care, but when someone does, the solution is right there at the beginning of the HLA reference manual where it discusses the linker options and the use of the link file.

BTW, for those who don't nest procedures or push odd bytes on the stack, you *can* tell HLA to generate slightly better code by putting the following two statements at the beginning of your source file (after the program or unit statement):



?@nodisplay := true;
?@noalignstack := true;


If you really want to live dangerously, you can also set @noframe to true and then you will be responsible for building the stack frame upon entry and cleaning it up on exit (as well as having to execute real "ret" instructions to return from the procedure -- just like assembly language :-) )
Cheers,
Randy Hyde
Posted on 2004-01-15 21:00:49 by rhyde
Thanks alot, I assumed it was a default setting but I couldn't find a reference to it anywhere. I'm sure I can find it now I know what I'm looking for.

--CRH
Posted on 2004-01-16 00:40:46 by CRH668
Seems like a wise decision, Randall - after all, HLA is very targetted at beginners :)

Windows does allocate stack dynamically, so I guess the 16meg prealloc is to avoid problems with random access to large local structures (the Guard Page stuff)?

How much do you know about locals etc at HLA preprocessing time? If you know the bytesize of local vars used, you could do a 'stack probe' on procedure entry, to avoid having to prealloc a large amount of stack - this could prove beneficial especially if using a lot of threads :). Then again, beginners won't really be affected and more advanced users should know how to handle it, I guess. Just an idea.

What's the "display" thing you're talking about? And what do you align the stack to (can it be user-specified? The could be a nice feature for people dealing with SSE, which *requires* strict alignment).
Posted on 2004-01-16 06:11:49 by f0dder
Originally posted by f0dder
Seems like a wise decision, Randall - after all, HLA is very targetted at beginners :)

Yep. Stack/heap commitment is a bit of an advanced subject.
A good argument could be made for making the block smaller (8MB? 4MB?), but I definitely ran into problems with the Windows default of 1MB. When 16MB turns out to be a problem for people, they complain and I point out the discussion of the stacksize and heapsize linker options in the HLA documentation.


Windows does allocate stack dynamically, so I guess the 16meg prealloc is to avoid problems with random access to large local structures (the Guard Page stuff)?


Well, "dynamically" is a bad term here.
You must allocate the *address space* for the stack before the program begins execution. Windows cannot move the stack once program execution begins and the stack *must* consume contiguous memory locations (unlike the heap). Therefore, you must (at least) preallocate the addresses that the stack will use.

Windows has two memory allocation steps: allocation (of address space) and commitment (of virtual memory). The HLA default options specify that Windows both allocate and commit 16MBs of storage for the heap and the stack. What the complaint here is not that HLA allocates the space, but that it commits it, as well.

By adding some additional startup code to the HLA main program, which I am loathe to do for reasons I'll explain in a moment, I *could* commit far less memory to the stack and heap when HLA starts up. Then, when the program references uncommit address space, the code (part of the exception handling system) could kick in and commit additional blocks of memory as needed.

In an ideal world, this would be the proper solution. However, we are in the "assembly world" not the "ideal world" and assembly programmers don't like their "assemblers" generating lots of code that they didn't write (or request). Currently, the HLA compiler calls one routine (linked in) that initializes the HLA exception handling system and it emits two tiny procedures to deal with exceptions. It also emits a couple of small data structures in the static data segment to maintain exception handling information. I'm concerned about having HLA emit any more code than this, because doing so gives people the impression that it's not an "assembler" when it emits all this extra code (indeed, people have the *incorrect* perception that HLA does this already; being able to say "no, it doesn't" is a poweful tool when people start ranting about how HLA is not a "true assembler").

The bottom line is that I have to be *very* careful about having HLA emit any code that the programmer doesn't directly or indirectly specify in their program. Figuring out how to balance these two issues (efficient use of memory resources versus control over generated code) is going to take some careful thought. Probably by HLA v2.0 I'll have a real solution to this problem.


How much do you know about locals etc at HLA preprocessing time? If you know the bytesize of local vars used, you could do a 'stack probe' on procedure entry, to avoid having to prealloc a large amount of stack - this could prove beneficial especially if using a lot of threads :). Then again, beginners won't really be affected and more advanced users should know how to handle it, I guess. Just an idea.

Windows already has that. It will raise an exception if you go beyond the committed address space. Of course, you must have preallocated the address space for the maximum size that the stack can grow, but commiting memory to that address space can be done dynamically at run-time. Indeed, an advanced user could tap into Windows' SEH and put that code into their HLA apps today (just as with any other app written in assembly language). But because the stack has to lie in a contiguous region of memory, you *must* allocate the address space for the maximum amount of stack you figure you'll need (and, in the big picture, 16MB, while pretty big, is tiny compared to the 2GB available address space).


What's the "display" thing you're talking about? And what do you align the stack to (can it be user-specified? The could be a nice feature for people dealing with SSE, which *requires* strict alignment).

See http://webster.cs.ucr.edu/Page_AoAWin/PDFs/LexicalNesting.pdf for a discussion of lexical nesting, displays, and static links.
Cheers,
Randy Hyde
Posted on 2004-01-16 11:02:12 by rhyde

What the complaint here is not that HLA allocates the space, but that it commits it, as well.

Yes, sorry, I know the difference between reserve and commit - I should have been more explicit :). Btw, the pe-header reserve/commit fields affect all threads where you specify zero for dwstacksize on CreateThread - this adds up quickly with 16MB :P. But yeah, on problems, tell people about the settings.

I hadn't really thought about a SEH-way to fix the guard-page issue with local vars... I still like the stack probing method better.

You have a point about the people bitching at HLA. Silly them... just like those saying MASM is not an assembler but a compiler etc - why don't they just stop harassing you and go play with debug? ;)


Windows already has that. It will raise an exception if you go beyond the committed address space.

Yes, well... the first page (or perhaps "small region") of uncommitted stack will rage a guard page exception which windows will internally handle and grow the stack-commit - references "further away" will raise a general exception. I think the guard page exception has a shorter codepath and will result in faster code, so it's probably better to do the stack probing where you 'pretouch' the stack in 4k increments.

I'm not using HLA myself so I theoretically don't care about it, but I do like talking about improvements anyway :). Adding stack probing by default is probably a bad idea because of those silly purists that attack you from time to time, but I think it would be a nice feature to have - it would amount to HLA doing a "push bytesizeoflocals / call __probestack" on procs with >4k locals, it would make pre-committing all the stack superfluous, should be faster than using SEH to handle the faults, and is generally a nice feature to have :)
Posted on 2004-01-16 12:27:10 by f0dder