Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(919)

Delta Between Two Patch Sets: src/cmd/gc/subr.c

Issue 7142052: code review 7142052: cmd/gc: don't hash nor compare struct padding or blank ... (Closed)
Left Patch Set: Created 12 years, 2 months ago
Right Patch Set: diff -r 7bc28d72d49c https://go.googlecode.com/hg/ Created 12 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/cmd/gc/walk.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 #include <u.h> 5 #include <u.h>
6 #include <libc.h> 6 #include <libc.h>
7 #include "go.h" 7 #include "go.h"
8 #include "md5.h" 8 #include "md5.h"
9 #include "y.tab.h" 9 #include "y.tab.h"
10 #include "yerr.h" 10 #include "yerr.h"
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 n->op = op; 497 n->op = op;
498 n->left = nleft; 498 n->left = nleft;
499 n->right = nright; 499 n->right = nright;
500 n->lineno = parserline(); 500 n->lineno = parserline();
501 n->xoffset = BADWIDTH; 501 n->xoffset = BADWIDTH;
502 n->orig = n; 502 n->orig = n;
503 n->curfn = curfn; 503 n->curfn = curfn;
504 return n; 504 return n;
505 } 505 }
506 506
507 static int
508 ispaddedfield(Type *t)
509 {
510 if(t->etype != TFIELD)
511 fatal("ispaddedfield called non-field %T", t);
512 return t->down != T && t->width + t->type->width != t->down->width;
513 }
514
507 int 515 int
508 algtype1(Type *t, Type **bad) 516 algtype1(Type *t, Type **bad)
509 { 517 {
510 int a, ret; 518 int a, ret;
511 Type *t1; 519 Type *t1;
512 ········ 520 ········
513 if(bad) 521 if(bad)
514 *bad = T; 522 *bad = T;
515 523
516 switch(t->etype) { 524 switch(t->etype) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 582 }
575 return -1; // needs special compare 583 return -1; // needs special compare
576 584
577 case TSTRUCT: 585 case TSTRUCT:
578 if(t->type != T && t->type->down == T) { 586 if(t->type != T && t->type->down == T) {
579 // One-field struct is same as that one field alone. 587 // One-field struct is same as that one field alone.
580 return algtype1(t->type->type, bad); 588 return algtype1(t->type->type, bad);
581 } 589 }
582 ret = AMEM; 590 ret = AMEM;
583 for(t1=t->type; t1!=T; t1=t1->down) { 591 for(t1=t->type; t1!=T; t1=t1->down) {
584 » » » if(isblanksym(t1->sym)) 592 » » » // Blank fields and padding must be ignored,
593 » » » // so need special compare.
594 » » » if(isblanksym(t1->sym) || ispaddedfield(t1)) {
595 » » » » ret = -1;
585 continue; 596 continue;
597 }
586 a = algtype1(t1->type, bad); 598 a = algtype1(t1->type, bad);
587 if(a == ANOEQ) 599 if(a == ANOEQ)
588 return ANOEQ; // not comparable 600 return ANOEQ; // not comparable
589 if(a != AMEM) 601 if(a != AMEM)
590 ret = -1; // needs special compare 602 ret = -1; // needs special compare
591 } 603 }
592 return ret; 604 return ret;
593 } 605 }
594 606
595 fatal("algtype1: unexpected type %T", t); 607 fatal("algtype1: unexpected type %T", t);
(...skipping 2091 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 n->nbody = list(n->nbody, call); 2699 n->nbody = list(n->nbody, call);
2688 2700
2689 fn->nbody = list(fn->nbody, n); 2701 fn->nbody = list(fn->nbody, n);
2690 break; 2702 break;
2691 2703
2692 case TSTRUCT: 2704 case TSTRUCT:
2693 // Walk the struct using memhash for runs of AMEM 2705 // Walk the struct using memhash for runs of AMEM
2694 // and calling specific hash functions for the others. 2706 // and calling specific hash functions for the others.
2695 first = T; 2707 first = T;
2696 for(t1=t->type;; t1=t1->down) { 2708 for(t1=t->type;; t1=t1->down) {
2697 » » » if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) { 2709 » » » if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblan ksym(t1->sym)) {
2698 » » » » if(first == T && !isblanksym(t1->sym)) 2710 » » » » if(first == T)
2699 first = t1; 2711 first = t1;
2700 » » » » continue; 2712 » » » » // If it's a memory field but it's padded, stop here.
2713 » » » » if(ispaddedfield(t1))
2714 » » » » » t1 = t1->down;
2715 » » » » else
2716 » » » » » continue;
2701 } 2717 }
2702 // Run memhash for fields up to this one. 2718 // Run memhash for fields up to this one.
2703 while(first != T && isblanksym(first->sym))
2704 first = first->down;
2705 if(first != T) { 2719 if(first != T) {
2706 if(first->down == t1) 2720 if(first->down == t1)
2707 size = first->type->width; 2721 size = first->type->width;
2708 else if(t1 == T) 2722 else if(t1 == T)
2709 size = t->width - first->width; // firs t->width is offset 2723 size = t->width - first->width; // firs t->width is offset
2710 else 2724 else
2711 size = t1->width - first->width; // bot h are offsets 2725 size = t1->width - first->width; // bot h are offsets
2712 hashel = hashmem(first->type); 2726 hashel = hashmem(first->type);
2713 // hashel(h, size, &p.first) 2727 // hashel(h, size, &p.first)
2714 call = nod(OCALL, hashel, N); 2728 call = nod(OCALL, hashel, N);
2715 call->list = list(call->list, nh); 2729 call->list = list(call->list, nh);
2716 call->list = list(call->list, nodintconst(size)) ; 2730 call->list = list(call->list, nodintconst(size)) ;
2717 nx = nod(OXDOT, np, newname(first->sym)); // TO DO: fields from other packages? 2731 nx = nod(OXDOT, np, newname(first->sym)); // TO DO: fields from other packages?
2718 na = nod(OADDR, nx, N); 2732 na = nod(OADDR, nx, N);
2719 na->etype = 1; // no escape to heap 2733 na->etype = 1; // no escape to heap
2720 call->list = list(call->list, na); 2734 call->list = list(call->list, na);
2721 fn->nbody = list(fn->nbody, call); 2735 fn->nbody = list(fn->nbody, call);
2722 2736
2723 first = T; 2737 first = T;
2724 } 2738 }
2725 if(t1 == T) 2739 if(t1 == T)
2726 break; 2740 break;
2741 if(isblanksym(t1->sym))
2742 continue;
2727 2743
2728 // Run hash for this field. 2744 // Run hash for this field.
2729 hashel = hashfor(t1->type); 2745 hashel = hashfor(t1->type);
2730 // hashel(h, size, &p.t1) 2746 // hashel(h, size, &p.t1)
2731 call = nod(OCALL, hashel, N); 2747 call = nod(OCALL, hashel, N);
2732 call->list = list(call->list, nh); 2748 call->list = list(call->list, nh);
2733 call->list = list(call->list, nodintconst(t1->type->widt h)); 2749 call->list = list(call->list, nodintconst(t1->type->widt h));
2734 nx = nod(OXDOT, np, newname(t1->sym)); // TODO: fields from other packages? 2750 nx = nod(OXDOT, np, newname(t1->sym)); // TODO: fields from other packages?
2735 na = nod(OADDR, nx, N); 2751 na = nod(OADDR, nx, N);
2736 na->etype = 1; // no escape to heap 2752 na->etype = 1; // no escape to heap
2737 call->list = list(call->list, na); 2753 call->list = list(call->list, na);
2738 fn->nbody = list(fn->nbody, call); 2754 fn->nbody = list(fn->nbody, call);
2739 } 2755 }
2756 // make sure body is not empty.
2757 fn->nbody = list(fn->nbody, nod(ORETURN, N, N));
2740 break; 2758 break;
2741 } 2759 }
2742 2760
2743 if(debug['r']) 2761 if(debug['r'])
2744 dumplist("genhash body", fn->nbody); 2762 dumplist("genhash body", fn->nbody);
2745 2763
2746 funcbody(fn); 2764 funcbody(fn);
2747 curfn = fn; 2765 curfn = fn;
2748 fn->dupok = 1; 2766 fn->dupok = 1;
2749 typecheck(&fn, Etop); 2767 typecheck(&fn, Etop);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 nrange->nbody = list(nrange->nbody, nif); 2920 nrange->nbody = list(nrange->nbody, nif);
2903 fn->nbody = list(fn->nbody, nrange); 2921 fn->nbody = list(fn->nbody, nrange);
2904 2922
2905 // *eq = true; 2923 // *eq = true;
2906 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool( 1))); 2924 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool( 1)));
2907 break; 2925 break;
2908 2926
2909 case TSTRUCT: 2927 case TSTRUCT:
2910 // Walk the struct using memequal for runs of AMEM 2928 // Walk the struct using memequal for runs of AMEM
2911 // and calling specific equality tests for the others. 2929 // and calling specific equality tests for the others.
2930 // Skip blank-named fields.
2912 first = T; 2931 first = T;
2913 for(t1=t->type;; t1=t1->down) { 2932 for(t1=t->type;; t1=t1->down) {
2914 » » » if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) { 2933 » » » if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblan ksym(t1->sym)) {
2915 » » » » if(first == T && !isblanksym(t1->sym)) 2934 » » » » if(first == T)
2916 first = t1; 2935 first = t1;
2917 » » » » continue; 2936 » » » » // If it's a memory field but it's padded, stop here.
2937 » » » » if(ispaddedfield(t1))
2938 » » » » » t1 = t1->down;
2939 » » » » else
2940 » » » » » continue;
2918 } 2941 }
2919 // Run memequal for fields up to this one. 2942 // Run memequal for fields up to this one.
2920 // TODO(rsc): All the calls to newname are wrong for 2943 // TODO(rsc): All the calls to newname are wrong for
2921 // cross-package unexported fields. 2944 // cross-package unexported fields.
2922 while(first != T && isblanksym(first->sym))
2923 first = first->down;
2924 if(first != T) { 2945 if(first != T) {
2925 if(first->down == t1) { 2946 if(first->down == t1) {
2926 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq)); 2947 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
2927 } else if(first->down->down == t1) { 2948 } else if(first->down->down == t1) {
2928 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq)); 2949 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
2929 first = first->down; 2950 first = first->down;
2930 if(!isblanksym(first->sym)) 2951 if(!isblanksym(first->sym))
2931 fn->nbody = list(fn->nbody, eqfi eld(np, nq, newname(first->sym), neq)); 2952 fn->nbody = list(fn->nbody, eqfi eld(np, nq, newname(first->sym), neq));
2932 } else { 2953 } else {
2933 // More than two fields: use memequal. 2954 // More than two fields: use memequal.
2934 if(t1 == T) 2955 if(t1 == T)
2935 size = t->width - first->width; // first->width is offset 2956 size = t->width - first->width; // first->width is offset
2936 else 2957 else
2937 size = t1->width - first->width; // both are offsets 2958 size = t1->width - first->width; // both are offsets
2938 fn->nbody = list(fn->nbody, eqmem(np, nq , newname(first->sym), size, neq)); 2959 fn->nbody = list(fn->nbody, eqmem(np, nq , newname(first->sym), size, neq));
2939 } 2960 }
2940 first = T; 2961 first = T;
2941 } 2962 }
2942 if(t1 == T) 2963 if(t1 == T)
2943 break; 2964 break;
2965 if(isblanksym(t1->sym))
2966 continue;
2944 2967
2945 // Check this field, which is not just memory. 2968 // Check this field, which is not just memory.
2946 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1-> sym), neq)); 2969 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1-> sym), neq));
2947 } 2970 }
2948 2971
2949 // *eq = true; 2972 // *eq = true;
2950 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool( 1))); 2973 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool( 1)));
2951 break; 2974 break;
2952 } 2975 }
2953 2976
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 yyerror("import path contains space character: \"%Z\"", path); 3693 yyerror("import path contains space character: \"%Z\"", path);
3671 return 1; 3694 return 1;
3672 } 3695 }
3673 if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) { 3696 if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
3674 yyerror("import path contains invalid character '%C': \" %Z\"", r, path); 3697 yyerror("import path contains invalid character '%C': \" %Z\"", r, path);
3675 return 1; 3698 return 1;
3676 } 3699 }
3677 } 3700 }
3678 return 0; 3701 return 0;
3679 } 3702 }
LEFTRIGHT
« no previous file | src/cmd/gc/walk.c » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b