Why am I getting a StackOverflow error in a long method?

匆匆过客 提交于 2020-01-23 01:05:09

问题


I have a small read-only database (based on data from services). The load time is critical so data can't be extracted from DB, XML and so on. I use the direct construction of data in the generated C# file:

void Load(){
    var aa = new A[ 100500 ];
    aa[0] = new A( ... );
    ...
    aa[100499] = new A( ... );
    AA = aa;
}

There are no recursion here, stackallocks and so on. But I have got a StackOverflow error.

Looking in Disassembler window I found that JIT converts this code into:

    var aa = new A[ 100500 ];
    var a0 = new A( ... );
    aa[0] = a0;
    ...
    var a100499 = new A( ... );
    aa[100499] = a100499;

So it create 100500 variables aXXXXX in stack:

-- aa[32] = new A( qwerty, asdf );
mov         ecx,185C10h                 -- var a32 = new A
call        001730F4                  
mov         dword ptr [ebp-4Ch],eax     -- different for different rows

push        dword ptr ds:[4403528h]     -- a32.ctor( ... )
mov         edx,dword ptr ds:[4403524h]  
mov         ecx,dword ptr [ebp-4Ch]  
call        00790068                  

push        dword ptr [ebp-4Ch]       -- aa[32] = a32
mov         ecx,dword ptr [ebp-3Ch]  
mov         edx,20h  
call        71CCCD30  

These changes doesn't help:

// 1. explicit variable 
A a;
a = new A( ... );  // a32 = new A(...); a = a32;
aa[32] = a

// 2. limited visibility
{ aa[32] = new A( ... ); } // for each created object

This change helps but too ugly:

// Works in Release version only
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void f32( A[] aa ) 
    => aa[32] = new A( qwerty, asdf );

...
f32( aa );  -- inlined without a32

Is any elegant way to remove these stack devourers?

Thanks in advance.

来源:https://stackoverflow.com/questions/59528181/why-am-i-getting-a-stackoverflow-error-in-a-long-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!