MCPcopy Create free account
hub / github.com/GaijinEntertainment/daScript / setAllocateOnStack

Function setAllocateOnStack

src/ast/ast_escape_analysis.cpp:226–257  ·  view source on GitHub ↗

set the stack-allocation flag on the fresh-alloc init expression; returns true if it changed it. only the shapes the codegen tiers can stack-allocate: a plain `new T()` (no initializer call, no dim) over a plain struct, and `new T(f=v)` which lowers to an ascend over a make-struct. capped by size. classes / constructors / handles are excluded: their construction has semantics (ctor invocation, rtt

Source from the content-addressed store, hash-verified

224 // capped by size. classes / constructors / handles are excluded: their construction has semantics
225 // (ctor invocation, rtti) that the plain in-frame build does not reproduce (breaks under JIT).
226 static bool setAllocateOnStack ( Expression * init ) {
227 if ( init && init->rtti_isNewExpr() ) {
228 auto en = (ExprNew *) init;
229 auto st = en->typeexpr ? en->typeexpr->structType : nullptr;
230 bool persistent = st && st->persistent;
231 bool isClass = st && st->isClass;
232 // use the non-asserting 64-bit size: a malformed/oversized type (e.g. in invalid_types.das)
233 // yields a huge value that simply fails the cap, instead of tripping the size<=0x7fffffff assert
234 bool fits = en->typeexpr && en->typeexpr->getBaseSizeOf64() <= uint64_t(MAX_STACK_ALLOC_SIZE);
235 if ( !en->initializer && en->typeexpr && en->typeexpr->dim.empty() && !persistent && !isClass && fits && !en->allocate_on_stack ) {
236 en->allocate_on_stack = true; return true;
237 }
238 } else if ( init && init->rtti_isAscend() ) {
239 auto ea = (ExprAscend *) init;
240 bool plainStruct = false;
241 if ( ea->subexpr && ea->subexpr->rtti_isMakeStruct() ) {
242 auto mks = (ExprMakeStruct *) ea->subexpr;
243 auto st = mks->makeType ? mks->makeType->structType : nullptr;
244 // note: isNewClass means "make-struct produced by a `new`" (set for plain structs too),
245 // NOT "is a class" - the class signal is the constructor / forceClass / structType->isClass
246 plainStruct = !mks->constructor && !mks->isNewHandle
247 && !mks->forceClass && !( st && st->isClass );
248 }
249 bool persistent = ea->subexpr && ea->subexpr->type && ea->subexpr->type->structType
250 && ea->subexpr->type->structType->persistent;
251 bool fits = ea->subexpr && ea->subexpr->type && ea->subexpr->type->getSizeOf64() <= uint64_t(MAX_STACK_ALLOC_SIZE);
252 if ( plainStruct && !persistent && fits && !ea->allocate_on_stack ) {
253 ea->allocate_on_stack = true; return true;
254 }
255 }
256 return false;
257 }
258
259 static bool initIsAllocatedOnStack ( Expression * init ) {
260 if ( init && init->rtti_isNewExpr() ) return ((ExprNew *)init)->allocate_on_stack;

Callers 1

visitLetMethod · 0.85

Calls 3

getBaseSizeOf64Method · 0.80
emptyMethod · 0.45
getSizeOf64Method · 0.45

Tested by

no test coverage detected