D2 is really that stable as it is claimed to be?

Timon Gehr timon.gehr at gmx.ch
Mon Sep 23 12:19:29 PDT 2013


On 09/22/2013 09:27 PM, Walter Bright wrote:
> On 9/22/2013 11:43 AM, Timon Gehr wrote:
>> Tracking line numbers is likely worth it. I don't believe that
>> providing column
>> numbers in error messages necessitates a slowdown though.
>
> Please consider that:
>
>       IT ISN'T JUST FOR ERROR MESSAGES
>
> It would go in the symbolic debug info, too, where it will be required
> everywhere and will be right there on the fast path through the
> lexer/compiler.
> ...

There is no such thing as a law that obliges compiler writers to add 
column numbers in debug info when such information is available in 
frontend error messages. The trade-offs involved in both cases may be 
different and deserve separate consideration.

> Now consider the lexer doing a fast skip over comment text (this ranks
> fairly high in the profile). This operation gets a lot slower if you're
> also keeping track of column number.

I am not keeping track of column number.

> Please note that:
>
>       COLUMN NUMBER ISN'T THE OFFSET FROM THE START OF THE LINE
> ...

Obviously. I compute the correct column number exactly in the case when 
an error message should actually be printed. It is not necessary to do 
any of this on the fast path. The additional memory word per location 
that I waste in comparison to DMD could be shaved off by using more 
computation in the error case (or by giving up support for exact 
underlining), but the project has not yet reached a stage where this is 
worth considering/measuring.

Excerpts from actual code I wrote roughly two years ago:

class Source{
     // computes a slice of the entire first line
     // where some given slice occurs in the source buffer.
     // this allows to recover column information on the fly, and we
     // will also be able to print the line where an error occurred
     // without storing it explicitly.
     // running time is linear in output length
     string getLineOf(string rep)in{/*...*/}out{/*...*/}body{
         string before=code[0..rep.ptr-code.ptr];
         string after=code[rep.ptr-code.ptr..$];
         immutable(char)* start=code.ptr, end=code.ptr+code.length;

         // It is fine to skip decoding here, because we are just
         // searching for ASCII characters.
         // TODO: support unicode line breaks?
         foreach_reverse(ref c; before)
             if(c=='\n'||c=='\r'){start = &c+1; break;}
         foreach(ref c; after)
             if(c=='\n'||c=='\r'){end = &c; break;}
         return start[0..end-start];
     }
     // ...
}

struct Location{
     string rep;    // slice of the code representing the Location
     int line;      // line number at start of location

     @property Source source()const{
         auto src = Source.get(rep); // (currently just a linear search)
         assert(src, "source for '"~rep~"' not found!");
         return src;
     }
     // ...
}

int getColumn(Location loc, int tabsize){
     int res=1;
     auto l=loc.source.getLineOf(loc.rep);
     for(;!l.empty&&l[0]&&l.ptr<loc.rep.ptr; l.popFront()){
         if(l.front=='\t') res=res-res%tabsize+tabsize;
         else res++;
     }
     return res;
}





More information about the Digitalmars-d mailing list