Skip to content

Commit

Permalink
Merge pull request #4673 from WalterBright/fix14571
Browse files Browse the repository at this point in the history
fix Issue 14571 - [REG2.064] Large static arrays seem to lock up DMD
  • Loading branch information
9rnsr committed May 24, 2015
2 parents e2106cb + ae31c78 commit bb7b196
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 17 deletions.
1 change: 0 additions & 1 deletion src/backend/cc.h
Expand Up @@ -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
Expand Down
90 changes: 90 additions & 0 deletions src/backend/dt.c
Expand Up @@ -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.)
Expand Down
1 change: 1 addition & 0 deletions src/backend/dt.h
Expand Up @@ -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 *);
Expand Down
28 changes: 12 additions & 16 deletions src/todt.c
Expand Up @@ -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++)
{
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -185,6 +188,7 @@ dt_t *Initializer_toDt(Initializer *init)
default:
assert(0);
}
dt_free(dtdefault);
}

void visit(ExpInitializer *ei)
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit bb7b196

Please sign in to comment.