From ae31c78687ca24c692e84cc97d5b5f1e975be84b Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 22 May 2015 03:31:53 -0700 Subject: [PATCH] fix Issue 14571 - [REG2.064] Large static arrays seem to lock up DMD --- src/backend/cc.h | 1 - src/backend/dt.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ src/backend/dt.h | 1 + src/todt.c | 28 +++++++-------- 4 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/backend/cc.h b/src/backend/cc.h index 0cdf72c344d6..3aa8eba63e40 100644 --- a/src/backend/cc.h +++ b/src/backend/cc.h @@ -1594,7 +1594,6 @@ extern Declar gdeclar; * w = symbol number (pointer for CPP) * a = offset * DTcoff offset into code segment - * DTend mark end of list */ struct dt_t diff --git a/src/backend/dt.c b/src/backend/dt.c index dab6571c6418..d0f3973cc5b5 100644 --- a/src/backend/dt.c +++ b/src/backend/dt.c @@ -300,6 +300,96 @@ dt_t **dtdtoff(dt_t **pdtend, dt_t *dt, unsigned offset) return dtxoff(pdtend, s, offset); } +/************************************** + * Repeat a list of dt_t's count times. + */ +dt_t **dtrepeat(dt_t **pdtend, dt_t *dt, size_t count) +{ + unsigned size = dt_size(dt); + + if (dtallzeros(dt)) + return dtnzeros(pdtend, size * count); + + while (*pdtend) + pdtend = &((*pdtend)->DTnext); + + if (count == 0) + return pdtend; + + if (dtpointers(dt)) + { + dt_t *dtp = NULL; + dt_t **pdt = &dtp; + for (size_t i = 0; i < count; ++i) + { + for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) + { + dt_t *dtx = dt_calloc(dtn->dt); + *dtx = *dtn; + dtx->DTnext = NULL; + switch (dtx->dt) + { + case DT_abytes: + case DT_nbytes: + dtx->DTpbytes = (char *) MEM_PH_MALLOC(dtx->DTnbytes); + memcpy(dtx->DTpbytes, dtn->DTpbytes, dtx->DTnbytes); + break; + } + + *pdt = dtx; + pdt = &dtx->DTnext; + } + } + *pdtend = dtp; + return pdt; + } + + char *p = (char *)MEM_PH_MALLOC(size * count); + size_t offset = 0; + + if (count) + { + for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) + { + switch (dtn->dt) + { + case DT_nbytes: + memcpy(p + offset, dtn->DTpbytes, dtn->DTnbytes); + offset += dtn->DTnbytes; + break; + case DT_ibytes: + memcpy(p + offset, dtn->DTdata, dtn->DTn); + offset += dtn->DTn; + break; + case DT_symsize: + case DT_azeros: + memset(p + offset, 0, dtn->DTazeros); + offset += dtn->DTazeros; + break; + default: +#ifdef DEBUG + dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); +#endif + assert(0); + } + } + assert(offset == size); + } + + for (size_t i = 1; i < count; ++i) + { + memcpy(p + offset, p, size); + offset += size; + } + + dt_t *dtx = dt_calloc(DT_nbytes); + dtx->DTnbytes = size * count; + dtx->DTpbytes = p; + *pdtend = dtx; + pdtend = &dtx->DTnext; + return pdtend; +} + /************************** * 'Optimize' a list of dt_t's. * (Try to collapse it into one DT_azeros object.) diff --git a/src/backend/dt.h b/src/backend/dt.h index 7f38c42bd5ae..cf755fa0d543 100644 --- a/src/backend/dt.h +++ b/src/backend/dt.h @@ -21,6 +21,7 @@ dt_t **dtxoff(dt_t **pdtend,Symbol *s,unsigned offset); dt_t **dtdtoff(dt_t **pdtend, dt_t *dt, unsigned offset); dt_t **dtcoff(dt_t **pdtend,unsigned offset); dt_t ** dtcat(dt_t **pdtend,dt_t *dt); +dt_t ** dtrepeat(dt_t **pdtend, dt_t *dt, size_t count); void dt_optimize(dt_t *dt); void dtsymsize(Symbol *); void init_common(Symbol *); diff --git a/src/todt.c b/src/todt.c index 9dc436434e71..cd45664dc281 100644 --- a/src/todt.c +++ b/src/todt.c @@ -130,6 +130,8 @@ dt_t *Initializer_toDt(Initializer *init) n *= tsa->dim->toInteger(); } + dt_t *dtdefault = NULL; + dt_t **pdtend = &result; for (size_t i = 0; i < ai->dim; i++) { @@ -138,8 +140,10 @@ dt_t *Initializer_toDt(Initializer *init) pdtend = dtcat(pdtend, dt); else { - for (size_t j = 0; j < n; j++) - pdtend = Expression_toDt(edefault, pdtend); + if (!dtdefault) + Expression_toDt(edefault, &dtdefault); + + pdtend = dtrepeat(pdtend, dtdefault, n); } } switch (tb->ty) @@ -157,11 +161,10 @@ dt_t *Initializer_toDt(Initializer *init) } else { - for (size_t i = ai->dim; i < tadim; i++) - { - for (size_t j = 0; j < n; j++) - pdtend = Expression_toDt(edefault, pdtend); - } + if (!dtdefault) + Expression_toDt(edefault, &dtdefault); + + pdtend = dtrepeat(pdtend, dtdefault, n * (tadim - ai->dim)); } } else if (ai->dim > tadim) @@ -185,6 +188,7 @@ dt_t *Initializer_toDt(Initializer *init) default: assert(0); } + dt_free(dtdefault); } void visit(ExpInitializer *ei) @@ -791,15 +795,7 @@ dt_t **toDtElem(TypeSArray *tsa, dt_t **pdt, Expression *e) len /= ((StringExp *)e)->len; if (e->op == TOKarrayliteral) len /= ((ArrayLiteralExp *)e)->elements->dim; - if (dtallzeros(*pdt)) - pdt = dtnzeros(pdt, dt_size(*pdt) * (len - 1)); - else - { - for (size_t i = 1; i < len; i++) - { - pdt = Expression_toDt(e, pdt); - } - } + pdt = dtrepeat(pdt, *pdt, len - 1); } return pdt; }