|
17 | 17 | #include "gen/irstate.h"
|
18 | 18 | #include "gen/llvmhelpers.h"
|
19 | 19 | #include "gen/logger.h"
|
| 20 | +#include "gen/runtime.h" |
20 | 21 | #include "gen/tollvm.h"
|
21 | 22 | #include "ir/irfunction.h"
|
22 | 23 | #include "ir/irtypeaggr.h"
|
@@ -488,17 +489,33 @@ void DtoCreateNestedContext(FuncGenState &funcGen) {
|
488 | 489 | auto &irFunc = funcGen.irFunc;
|
489 | 490 | unsigned depth = irFunc.depth;
|
490 | 491 | LLStructType *frameType = irFunc.frameType;
|
| 492 | + const unsigned frameAlignment = |
| 493 | + std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment); |
| 494 | + |
491 | 495 | // Create frame for current function and append to frames list
|
492 | 496 | LLValue *frame = nullptr;
|
493 | 497 | bool needsClosure = fd->needsClosure();
|
494 | 498 | IF_LOG Logger::println("Needs closure (GC) flag: %d", (int)needsClosure);
|
495 | 499 | if (needsClosure) {
|
496 |
| - // FIXME: alignment ? |
497 |
| - frame = DtoGcMalloc(fd->loc, frameType, ".frame"); |
| 500 | + LLFunction *fn = |
| 501 | + getRuntimeFunction(fd->loc, gIR->module, "_d_allocmemory"); |
| 502 | + auto size = getTypeAllocSize(frameType); |
| 503 | + if (frameAlignment > 16) // GC guarantees an alignment of 16 |
| 504 | + size += frameAlignment - 16; |
| 505 | + LLValue *mem = |
| 506 | + gIR->CreateCallOrInvoke(fn, DtoConstSize_t(size), ".gc_frame"); |
| 507 | + if (frameAlignment <= 16) { |
| 508 | + frame = DtoBitCast(mem, frameType->getPointerTo(), ".frame"); |
| 509 | + } else { |
| 510 | + const uint64_t mask = frameAlignment - 1; |
| 511 | + mem = gIR->ir->CreatePtrToInt(mem, DtoSize_t()); |
| 512 | + mem = gIR->ir->CreateAdd(mem, DtoConstSize_t(mask)); |
| 513 | + mem = gIR->ir->CreateAnd(mem, DtoConstSize_t(~mask)); |
| 514 | + frame = |
| 515 | + gIR->ir->CreateIntToPtr(mem, frameType->getPointerTo(), ".frame"); |
| 516 | + } |
498 | 517 | } else {
|
499 |
| - unsigned alignment = |
500 |
| - std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment); |
501 |
| - frame = DtoRawAlloca(frameType, alignment, ".frame"); |
| 518 | + frame = DtoRawAlloca(frameType, frameAlignment, ".frame"); |
502 | 519 | }
|
503 | 520 |
|
504 | 521 | // copy parent frames into beginning
|
|
0 commit comments