Ignore:
Timestamp:
Jan 3, 2010, 7:13:32 PM (12 years ago)
Author:
rbri
Message:

DJVU plugin: djvulibre updated to version 3.5.22

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libdjvu/miniexp.cpp

    r206 r280  
    1616// -------------------------------------------------------------------
    1717*/
    18 /* $Id: miniexp.cpp,v 1.14 2007/03/25 20:48:35 leonb Exp $ */
     18/* $Id: miniexp.cpp,v 1.23 2008/08/05 20:50:35 bpearlmutter Exp $ */
    1919
    2020#ifdef HAVE_CONFIG_H
     
    260260        if (! c[i])
    261261          {
    262             if (destroy && m[i+i]==m[i+i+1])
    263               delete (miniobj_t*)m[i+i];
     262            miniobj_t *obj = (miniobj_t*)m[i+i];
     263            if (destroy && obj && m[i+i]==m[i+i+1])
     264              obj->destroy();
    264265            m[i+i] = (void*)freelist;
    265266            m[i+i+1] = 0;
     
    313314
    314315#if defined(__GNUC__) && (__GNUC__ >= 3)
    315 static void gc_mark_object(void **v)
    316   __attribute__((noinline));
     316static void gc_mark_object(void **v) __attribute__((noinline));
    317317#else
    318318static void gc_mark_object(void **v);
    319319#endif
    320320
     321static bool
     322gc_mark_check(void *p)
     323{
     324  if (((size_t)p) & 2)
     325    return false;
     326  void **v = (void**)(((size_t)p) & ~(size_t)3);
     327  if (! v)
     328    return false;
     329  char *m = markbyte(v);
     330  if (*m)
     331    return false;
     332  *m = 1;
     333  if (! (((size_t)p) & 1))
     334    return true;
     335  gc_mark_object((void**)v);
     336  return false;
     337}
     338
     339static void
     340gc_mark_pair(void **v)
     341{
     342#ifndef MINIEXP_POINTER_REVERSAL
     343  // This is a simple recursive code.
     344  // Despite the tail recursion for the cdrs,
     345  // it consume a stack space that grows like
     346  // the longest chain of cars.
     347  for(;;)
     348    {
     349      if (gc_mark_check(v[0]))
     350        gc_mark_pair((void**)v[0]);
     351      if (! gc_mark_check(v[1]))
     352        break;
     353      v = (void**)v[1];
     354    }
     355#else
     356  // This is the classic pointer reversion code
     357  // It saves stack memory by temporarily reversing the pointers.
     358  // This is a bit slower because of all these nonlocal writes.
     359  // But it could be useful for memory-starved applications.
     360  // That makes no sense for most uses of miniexp.
     361  // I leave the code here because of its academic interest.
     362  void **w = 0;
     363 docar:
     364  if (gc_mark_check(v[0]))
     365    { // reverse car pointer
     366      void **p = (void**)v[0];
     367      v[0] = (void*)w;
     368      w = (void**)(((size_t)v)|(size_t)1);
     369      v = p;
     370      goto docar;
     371    }
     372 docdr:
     373  if (gc_mark_check(v[1]))
     374    { // reverse cdr pointer
     375      void **p = (void**)v[1];
     376      v[1] = (void*)w;
     377      w = v;
     378      v = p;
     379      goto docar;
     380    }
     381 doup:
     382  if (w)
     383    {
     384      if (((size_t)w)&1)
     385        { // undo car reversion
     386          void **p = (void**)(((size_t)w)&~(size_t)1);
     387          w = (void**)p[0];
     388          p[0] = (void*)v;
     389          v = p;
     390          goto docdr;
     391        }
     392      else
     393        { // undo cdr reversion
     394          void **p = w;
     395          w = (void**)p[1];
     396          p[1] = (void*)v;
     397          v = p;
     398          goto doup;
     399        }
     400    }
     401#endif
     402}
     403
    321404static void
    322405gc_mark(miniexp_t *pp)
    323406{
    324   for(;;)
    325     {
    326       miniexp_t p = *pp;
    327       if (((size_t)p) & 2) return;
    328       void **v = (void**)(((size_t)p) & ~(size_t)3);
    329       if (! v) return;
    330       char *m = markbyte(v);
    331       if (*m) return;
    332       (*m) = 1;
    333       if (((size_t)p) & 1)
    334         { // object
    335           gc_mark_object(v);
    336           return;
    337         }
    338       else
    339         { // pair
    340           gc_mark((miniexp_t*)&v[0]);
    341           pp = (miniexp_t*)&v[1];
    342         }
    343     }
     407  void **v = (void**)*pp;
     408  if (gc_mark_check((void**)*pp))
     409    gc_mark_pair(v);
    344410}
    345411
     
    347413gc_mark_object(void **v)
    348414{
     415  ASSERT(v[0] == v[1]);
    349416  miniobj_t *obj = (miniobj_t*)v[0];
    350   if (obj) obj->mark(gc_mark);
     417  if (obj)
     418    obj->mark(gc_mark);
    351419}
    352420
     
    367435      minivar_t::mark(gc_mark);
    368436      for (int i=0; i<recentsize; i++)
    369         {
    370           miniexp_t p = (miniexp_t)gc.recent[i];
    371           gc_mark(&p);
     437        { // extra cast for strict aliasing rules?
     438          char *s = (char*)&gc.recent[i];
     439          gc_mark((miniexp_t*)s);
    372440        }
    373441      // sweep
     
    396464    }
    397465  else if (gc.debug)
    398     minilisp_gc();
     466    gc_run();
    399467  void **p = gc.pairs_freelist;
    400468  gc.pairs_freelist = (void**)p[0];
     
    402470  p[0] = a;
    403471  p[1] = d;
    404   gc.recent[(++gc.recentindex) & (recentsize-1)] = p;
    405472  return p;
    406473}
     
    416483    }
    417484  else if (gc.debug)
    418     minilisp_gc();
     485    gc_run();
    419486  void **p = gc.objs_freelist;
    420487  gc.objs_freelist = (void**)p[0];
    421488  gc.objs_free -= 1;
    422489  p[0] = p[1] = obj;
    423   gc.recent[(++gc.recentindex) & (recentsize-1)] = p;
    424490  return p;
    425491}
     
    622688miniexp_cons(miniexp_t a, miniexp_t d)
    623689{
    624   gc.recent[(gc.recentindex+1) & (recentsize-1)] = (void**)a;
    625   gc.recent[(gc.recentindex+2) & (recentsize-1)] = (void**)d;
    626690  miniexp_t r = (miniexp_t)gc_alloc_pair((void*)a, (void*)d);
     691  gc.recent[(++gc.recentindex) & (recentsize-1)] = (void**)r;
    627692  return r;
    628693}
     
    673738}
    674739
    675 miniexp_t miniobj_t::classname = 0;
     740const miniexp_t miniobj_t::classname = 0;
    676741
    677742bool
     
    684749miniobj_t::mark(minilisp_mark_t*)
    685750{
     751}
     752
     753void
     754miniobj_t::destroy()
     755{
     756  delete this;
    686757}
    687758
     
    699770{
    700771  void **v = gc_alloc_object((void*)obj);
    701   return (miniexp_t)(((size_t)v)|(size_t)1);
     772  v = (void**)(((size_t)v)|((size_t)1));
     773  gc.recent[(++gc.recentindex) & (recentsize-1)] = v;
     774  return (miniexp_t)(v);
    702775}
    703776
     
    794867        {
    795868          char letter = 0;
    796           static char *tr1 = "\"\\tnrbf";
    797           static char *tr2 = "\"\\\t\n\r\b\f";
     869          static const char *tr1 = "\"\\tnrbf";
     870          static const char *tr2 = "\"\\\t\n\r\b\f";
    798871          { // extra nesting for windows
    799872            for (int i=0; tr2[i]; i++)
     
    10221095        {
    10231096          skip -= 1;
    1024           if (multiline || newline() && skip<0 && tab>indent)
     1097          if (multiline || (newline() && skip<0 && tab>indent))
    10251098            {
    10261099              mlput("\n");
     
    10421115        {
    10431116          skip -= 1;
    1044           if (multiline || newline() && skip<0 && tab>indent)
     1117          if (multiline || (newline() && skip<0 && tab>indent))
    10451118            {
    10461119              mlput("\n");
     
    12891362  for(;;)
    12901363    {
    1291       if (c==EOF || isascii(c) && !isprint(c))
     1364      if (c==EOF || (isascii(c) && !isprint(c)))
    12921365        return read_error(c);
    12931366      else if (c=='\"')
     
    13411414                }
    13421415            }
    1343           static char *tr1 = "tnrbfva";
    1344           static char *tr2 = "\t\n\r\b\f\013\007";
     1416          static const char *tr1 = "tnrbfva";
     1417          static const char *tr2 = "\t\n\r\b\f\013\007";
    13451418          { // extra nesting for windows
    13461419            for (int i=0; tr1[i]; i++)
     
    13691442    {
    13701443      c = minilisp_getc();
    1371       if (c==EOF || isascii(c) && !isprint(c))
     1444      if (c==EOF || (isascii(c) && !isprint(c)))
    13721445        return read_error(c);
    13731446      if (c=='|')
Note: See TracChangeset for help on using the changeset viewer.