[Ada] Spurious secondary stack depletion
This patch reimplements the secondary stack allocation logic to eliminate an issue which causes the memory index to overflow while the stack itself uses very little memory, thus causing a spurious Storage_Error. The issue in details: The total amount of memory that the secondary stack can accomodate is dictated by System.Parameters.Size_Type which is really an Integer, giving roughly 2 GB of storage. The secondary stack is comprised of multiple frames which logically form a contiguous array of memory. Each frame maintans a range over which it operates, where Low bound = Previous frame's high bound + 1 High bound = Previous frame's high bound + Frame size The allocation logic starts by first checking whether the current top frame (which may not be the "last" frame in the secondary stack) has enough memory to fit an object. If it does, then that frame is used. If it does not, the logic then examines the subsequent frames, while carrying out the following actions: * If the frame is too small to fit the object, it is deleted * If the frame is big enough to fit the object, it is used If all the frames were too small (and thus deleted), a new frame is added which is big enough to fit the object. Due to an issue with the deletion logic, the last frame would never be deleted. Since any new frame's range is based on the previous frame's range, the new range would keep growing, even though the secondary stack may have very few frames in use. Eventually this growth overflows the memory index type. The overflow of the memory index type happens only when the secondary stack is full, and thus signals a Storage_Error. Due to the spurious growth of the ranges, the overflow happens much faster and results in a bogus stack depleton. The issue manifests only when each new memory request to the secondary stack is slightly bigger than the previous memory request, thus prompring the secondary stack to delete all its frames, and create a new one. 2018-05-25 Hristian Kirtchev <kirtchev@adacore.com> gcc/ada/ * libgnat/s-secsta.adb (SS_Allocate): Reimplemented. (SS_Allocate_Dynamic): New routine. The allocation logic is now split into three distring cases rather than in one loop which attempts to handle all three cases. This rewrite eliminates an issue where the last frame of the stack cannot be freed, thus causing the memory range of a new frame to approach the overflow point of the memory index type. Since the overflow is logically treated as a too-much-memory-on-the-stack scenario, it causes a bogus Storage_Error. (SS_Allocate_Static): New routine. The routine factorizes the static secondary stack-related code from the former SS_Allocate. gcc/testsuite/ * gnat.dg/sec_stack2.adb: New testcase. From-SVN: r260736
Showing
This diff is collapsed.
Click to expand it.
gcc/testsuite/gnat.dg/sec_stack2.adb
0 → 100644
Please
register
or
sign in
to comment