source: proto/SymbolTable/symtab_hash_template.cpp @ 1457

Last change on this file since 1457 was 1457, checked in by vla24, 8 years ago

SymbolTable?: updated implementation after Ken's refactoring

File size: 16.9 KB
Line 
1#define TEMPLATED_SIMD_LIB
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <../lib_simd.h>
9#include <hash_symbol_table.h>
10#include <queue>
11#include <string>
12
13typedef long ScanBlock;
14typedef SIMD_type BytePack;
15typedef SIMD_type BitBlock;
16
17using namespace std;
18
19#define DEBUG 0
20#define BLOCK_SIZE (sizeof(SIMD_type) * 8)
21#define SEGMENT_BLOCKS 12
22#define BUFFER_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
23#define OVERLAP_BUFSIZE 2*(sizeof(SIMD_type))
24
25#include <../carryQ.h>
26#include <xmldecl.h>
27#include <namechars.h>
28#include <../perflib/perfsec.h>
29#include <../s2p.h>
30
31#include <TagMatcher.h>
32#include <LineColTracker.h>
33#include <ErrorUtil.h>
34#include <ErrorTracker.h>
35#include <XMLTestSuiteError.h>
36
37#include <xml_error.c>
38#include <ErrorUtil.cpp>
39#include <ErrorTracker.cpp>
40#include <XMLTestSuiteError.cpp>
41
42#ifdef BUFFER_PROFILING
43        BOM_Table * parser_timer;
44
45#elif CODE_CLOCKER
46        #define NUM_EVENTS 1
47        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
48        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
49        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
50        int cal_size = 20;
51        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
52#else
53        void * parser_timer;
54#endif
55
56int block_base=0;
57int buffer_base=0;
58int buffer_last;
59char * source;
60LineColTracker tracker;
61TagMatcher matcher;
62ErrorTracker error_tracker;
63BitBlock EOF_mask = simd_const_1(1);
64
65queue <size_t> elem_starts_buf;
66queue <size_t> elem_ends_buf;
67vector <int> gids;
68HashSymbolTable symbol_table;
69
70/* StreamScan & Post Process Declarations */
71//      static inline int StreamScanToFirst(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block)
72static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block);
73
74static inline int NameStrt_check(int pos);
75static inline int Name_check(int pos);
76static inline int PIName_check(int pos);
77static inline int CD_check(int pos);
78static inline int GenRef_check(int pos);
79static inline int HexRef_check(int pos);
80static inline int DecRef_check(int pos);
81static inline int AttRef_check(int pos);
82
83@global
84
85static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits);
86static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask);
87static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, Tag_Callouts & tag_Callouts, int chars_avail);
88static inline void do_symbol_table_lookup();
89
90void do_process(FILE *infile, FILE *outfile);
91
92int main(int argc, char * argv[]) {
93        char * infilename, * outfilename;
94        FILE *infile, *outfile;
95        struct stat fileinfo;
96
97        if (argc < 2) {
98                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
99                exit(-1);
100        }
101
102        infilename = argv[1];
103        stat(infilename, &fileinfo);
104        infile = fopen(infilename, "rb");
105        if (!infile) {
106                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
107                exit(-1);
108        }
109
110        if (argc < 3) outfile = stdout;
111        else {
112                outfilename = argv[2];
113                outfile = fopen(outfilename, "wb");
114                if (!outfile) {
115                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
116                        exit(-1);
117                }
118        }
119
120//      PERF_SEC_BIND(1);
121
122        PERF_SEC_INIT(parser_timer);
123
124        do_process(infile, outfile);
125
126        PERF_SEC_DUMP(parser_timer);
127
128        PERF_SEC_DESTROY(parser_timer);
129
130        fclose(infile);
131        fclose(outfile);
132
133        return(0);
134}
135
136/* s2p Definitions */
137static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits) {
138  s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
139        basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3, basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
140}
141
142static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask) {
143  s2p_do_block(U8, basis_bits);
144  basis_bits.bit_0 = simd_and(basis_bits.bit_0, EOF_mask);
145  basis_bits.bit_1 = simd_and(basis_bits.bit_1, EOF_mask);
146  basis_bits.bit_2 = simd_and(basis_bits.bit_2, EOF_mask);
147  basis_bits.bit_3 = simd_and(basis_bits.bit_3, EOF_mask);
148  basis_bits.bit_4 = simd_and(basis_bits.bit_4, EOF_mask);
149  basis_bits.bit_5 = simd_and(basis_bits.bit_5, EOF_mask);
150  basis_bits.bit_6 = simd_and(basis_bits.bit_6, EOF_mask);
151  basis_bits.bit_7 = simd_and(basis_bits.bit_7, EOF_mask);
152}
153
154/* StreamScan & Post Process Definitions */
155static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int), int * error_pos_in_block) {
156
157        int blk;
158        int block_pos = 0;
159        int pos;
160
161        for (blk = 0; blk < blk_count; blk++) {
162                ScanBlock s = stream[blk];
163                while(s) {
164                        pos = (cfzl(s) + block_pos);
165                        int code = (ProcessPos(pos));
166                        if (code) {
167                                *error_pos_in_block = pos;
168                                return code; // error code
169                        }
170                        s = s & (s-1);  // clear rightmost bit.
171                }
172                block_pos += 8 * sizeof(ScanBlock);
173        }
174        return 0;
175}
176
177static inline int ElemStrt_check(int pos) {
178        int block_pos = block_base + pos;
179        elem_starts_buf.push(buffer_base + block_pos);
180        return 0;
181}
182
183static inline int ElemEnd_check(int pos) {
184        int block_pos = block_base + pos;
185        elem_ends_buf.push(buffer_base + block_pos);
186        return 0;
187}
188
189static inline int NameStrt_check(int pos) {
190        int block_pos = block_base + pos;
191        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
192              return XMLTestSuiteError::NAME_START;
193        }
194        return 0;
195}
196
197static inline int Name_check(int pos) {
198        int block_pos = block_base + pos;
199        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
200                  return XMLTestSuiteError::NAME;
201        }
202        return 0;
203}
204
205static inline int PIName_check(int pos) {
206        int block_pos = block_base + pos;
207        int file_pos = block_pos+buffer_base;
208        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
209              // "<?xml" legal at start of file.
210              if (!((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0]))) {
211                  return XMLTestSuiteError::XMLPINAME;
212              }
213        }
214        return 0;
215}
216
217static inline int CD_check(int pos) {
218        int block_pos = block_base + pos;
219        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
220                  return XMLTestSuiteError::CDATA;
221        }
222        return 0;
223}
224
225static inline int GenRef_check(int pos) {
226        int block_pos = block_base + pos;
227        unsigned char* s = (unsigned char*)&source[block_pos];
228        if (!(at_Ref_gt<ASCII>(s)||at_Ref_lt<ASCII>(s)||at_Ref_amp<ASCII>(s)||at_Ref_quot<ASCII>(s)||at_Ref_apos<ASCII>(s))){
229              return XMLTestSuiteError::UNDEFREF;
230        }
231        return 0;
232}
233
234static inline int HexRef_check(int pos) {
235        int block_pos = block_base + pos;
236        unsigned char* s = (unsigned char*)&source[block_pos];
237        int ch_val = 0;
238        while(at_HexDigit<ASCII>(s)){
239          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
240          if (ch_val> 0x10FFFF ){
241                return XMLTestSuiteError::CHARREF;
242          }
243          s++;
244        }
245        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
246          return XMLTestSuiteError::CHARREF;
247        }
248        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
249          return XMLTestSuiteError::XML10CHARREF;
250        }
251        return 0;
252}
253
254static inline int DecRef_check(int pos) {
255        int block_pos = block_base + pos;
256        unsigned char* s = (unsigned char*)&source[block_pos];
257        int ch_val = 0;
258        while(at_HexDigit<ASCII>(s)){
259          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
260          if (ch_val> 0x10FFFF ){
261                        return XMLTestSuiteError::CHARREF;
262          }
263          s++;
264        }
265        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
266                  return XMLTestSuiteError::CHARREF;
267        }
268        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
269                  return XMLTestSuiteError::XML10CHARREF;
270        }
271        return 0;
272}
273
274static inline int AttRef_check(int pos) {
275        int block_pos = block_base + pos;
276        unsigned char* s = (unsigned char*)&source[block_pos];
277        int ch_val = 0;
278        if(s[0]=='#'){
279          s++;
280          if(s[0]=='x' || s[0]=='X'){
281            s++;
282            while(at_HexDigit<ASCII>(s)){
283              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
284              s++;
285            }
286          }
287          else{
288            while(at_HexDigit<ASCII>(s)){
289              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
290              s++;
291            }
292          }
293          if (ch_val==60){
294            return XMLTestSuiteError::ATTREF;
295          }
296        }
297        else if(at_Ref_lt<ASCII>(s)){
298          return XMLTestSuiteError::ATTREF;
299        }
300        return 0;
301}
302
303static inline void do_symbol_table_lookup()
304{
305    while( !elem_starts_buf.empty() && !elem_ends_buf.empty() )
306    {
307        int start = elem_starts_buf.front();
308        int end = elem_ends_buf.front();
309        elem_starts_buf.pop();
310        elem_ends_buf.pop();
311        int length = end - start;
312
313        //lookup or insert to symbol table
314#if DEBUG
315        char* symbol = new char[length+1];
316        strncpy ( symbol, source + start - buffer_base, length );
317        symbol[length] ='\0';
318        printf ("start: %i[%i] | end: %i[%i] | length: %i | symbol: %s\n", start, start-buffer_base, end, end-buffer_base, length, symbol );
319
320        delete symbol; symbol = 0;
321#endif
322
323        int gid = symbol_table.Lookup_or_Insert_Name(source + start - buffer_base, length);
324        gids.push_back(gid);
325    }
326}
327
328static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, Tag_Callouts & tag_Callouts, int chars_avail){
329
330    tracker.StoreNewlines(lex.LF);
331    int rv, error_pos_in_block, error_line, error_column;
332
333    if ( bitblock_has_bit(tag_Callouts.ElemName_starts))
334    {
335        StreamScan((ScanBlock *) &tag_Callouts.ElemName_starts, sizeof(BitBlock)/sizeof(ScanBlock), ElemStrt_check, &error_pos_in_block);
336    }
337
338    if ( bitblock_has_bit(tag_Callouts.ElemName_ends) )
339    {
340        StreamScan((ScanBlock *) &tag_Callouts.ElemName_ends, sizeof(BitBlock)/sizeof(ScanBlock), ElemEnd_check, &error_pos_in_block);
341    }
342
343    do_symbol_table_lookup();
344
345
346    if (bitblock_has_bit(simd_or(check_streams.non_ascii_name_starts, check_streams.non_ascii_names))) {
347      rv = StreamScan((ScanBlock *) &check_streams.non_ascii_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check, &error_pos_in_block);
348      if (rv) {
349              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
350              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
351              exit(-1);
352      }
353
354      rv = StreamScan((ScanBlock *) &check_streams.non_ascii_names, sizeof(BitBlock)/sizeof(ScanBlock), Name_check, &error_pos_in_block);
355      if (rv) {
356              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
357              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
358              exit(-1);
359      }
360    }
361
362    if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
363      rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check, &error_pos_in_block);
364      if (rv) {
365              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
366              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
367              exit(-1);
368      }
369    }
370
371    if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
372      rv = StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check, &error_pos_in_block);
373      if (rv) {
374              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
375              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
376              exit(-1);
377      }
378    }
379
380    if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
381      rv = StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check, &error_pos_in_block);
382      if (rv) {
383              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
384              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
385              exit(-1);
386      }
387    }
388
389    if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
390      rv = StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check, &error_pos_in_block);
391      if (rv) {
392              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
393              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
394              exit(-1);
395      }
396    }
397
398    if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
399      rv = StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check, &error_pos_in_block);
400      if (rv) {
401              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
402              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
403              exit(-1);
404      }
405    }
406
407    if (bitblock_has_bit(check_streams.att_refs)){
408      rv = StreamScan((ScanBlock *) &check_streams.att_refs, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check, &error_pos_in_block);
409      if (rv) {
410              tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
411              ReportError(XMLTestSuiteError::get_msg(rv), error_line, error_column);
412              exit(-1);
413      }
414    }
415
416    if(error_tracker.Has_Noted_Error()){
417            tracker.get_Line_and_Column(error_tracker.Noted_Pos_In_Block(), error_line, error_column);
418            ReportError(error_tracker.Noted_Error_Msg(), error_line, error_column);
419            exit(-1);
420    }
421
422    matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail);
423    tracker.AdvanceBlock();
424}
425
426static inline void print_GIDS()
427{
428    int span_count = gids.size();
429    for(int i=0;i<span_count;i++) {
430             cout << gids[i] << " ";
431    }
432    cout << endl;
433}
434
435void do_process(FILE *infile, FILE *outfile) {
436
437@decl
438
439  int buf_pos = 0;
440  int block_pos = 0;
441  int errpos = 0;
442  int chars_avail = 0;
443  int check_pos = 0;
444  int chars_read = 0;
445  BytePack buf[(BUFFER_SIZE+BLOCK_SIZE+OVERLAP_BUFSIZE*2)/sizeof(SIMD_type)];
446
447  char * srcbuf = ((char *) buf) + OVERLAP_BUFSIZE;
448  buffer_base = buf_pos;
449  source = srcbuf;
450  chars_read = fread((void *)srcbuf, 1, BUFFER_SIZE + OVERLAP_BUFSIZE, infile);
451  chars_avail = chars_read;
452  if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
453
454  matcher.setSrc(srcbuf);
455
456  if(chars_read<4){
457    fprintf(stderr,"File is too short. Not well formed.\n");
458    exit(-1);
459  }
460
461  Entity_Info * e = new Entity_Info;
462  e->AnalyzeSignature((unsigned char *)srcbuf);
463
464  if (e->code_unit_base == ASCII) {
465
466    XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
467
468    decl_parser.ReadXMLInfo(*e);
469
470    if (e->code_unit_size != SingleByte || (e->has_encoding_decl && (!at_UTF_8(e->encoding)))){
471        fprintf(stderr,"Sorry, this xmlwf demo only works for UTF-8.\n");
472        exit(-1);
473    }
474  }
475  else {
476    fprintf(stderr,"Sorry, this xmlwf demo does not process EBCDIC.\n");
477        exit(-1);
478  }
479
480  if (e->content_start != 0) {
481        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_read - e->content_start);
482        buf_pos = e->content_start;
483        buffer_base = buf_pos;
484        if (chars_avail == BUFFER_SIZE) {
485                chars_read = chars_read - e->content_start +
486                             fread(&srcbuf[chars_read-e->content_start], 1, e->content_start, infile);
487                chars_avail = chars_read;
488                if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
489        }
490        else {
491          chars_read -=e->content_start;
492          chars_avail -=e->content_start;
493        }
494  }
495
496@stream_stmts
497
498/* Full Buffers */
499    while (chars_avail == BUFFER_SIZE) {
500      PERF_SEC_START(parser_timer);
501      for (int blk = 0; blk < SEGMENT_BLOCKS; blk++) {
502          block_base = blk*BLOCK_SIZE;
503          s2p_do_block((BytePack *) &srcbuf[block_base], basis_bits);
504          @block_stmts
505          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
506      }
507
508      matcher.StreamScan(chars_avail);
509      matcher.Advance_buffer();
510      tracker.Advance_buffer();
511      PERF_SEC_END(parser_timer, chars_avail);
512           
513      int bytes_left = chars_read - chars_avail;
514      memmove(buf, &srcbuf[BUFFER_SIZE - OVERLAP_BUFSIZE], bytes_left + OVERLAP_BUFSIZE);
515      chars_read = fread(&srcbuf[bytes_left],1, BUFFER_SIZE + OVERLAP_BUFSIZE - bytes_left, infile) + bytes_left;
516      chars_avail = chars_read;
517      if (chars_avail > BUFFER_SIZE) chars_avail = BUFFER_SIZE;
518      buf_pos += chars_avail;
519      buffer_base = buf_pos;
520    }
521/* Final Partial Buffer */
522    PERF_SEC_START(parser_timer);
523
524    block_pos = 0;
525    int remaining = chars_avail;
526/* Full Blocks */
527    while (remaining >= BLOCK_SIZE) {
528          block_base = block_pos;
529          s2p_do_block((BytePack *) &srcbuf[block_pos], basis_bits);
530          @block_stmts
531          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
532          block_pos += BLOCK_SIZE;
533          remaining -= BLOCK_SIZE;
534    }
535    block_base = block_pos;
536    if (remaining > 0 || @any_carry) {
537          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-remaining));
538          s2p_do_final_block((BytePack *) &srcbuf[block_pos], basis_bits, EOF_mask);
539          @final_block_stmts
540          postprocess_do_block(lex, ctCDPI_Callouts, ref_Callouts, check_streams, tag_Callouts, chars_avail);
541    }
542    buf_pos += chars_avail;
543    buffer_base = buf_pos;
544
545    matcher.StreamScan(chars_avail);
546    matcher.Advance_buffer();
547    tracker.Advance_buffer();
548
549    PERF_SEC_END(parser_timer, chars_avail);
550    if (matcher.depth != 0) {
551      fprintf(stderr, "tag matching error (depth %i) at position %i\n", matcher.depth, buffer_base);
552      exit(-1);
553    }
554#if DEBUG
555    print_GIDS();
556#endif
557}
Note: See TracBrowser for help on using the repository browser.