OLD | NEW |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 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 // Rewrite tree to use separate statements to enforce | 5 // Rewrite tree to use separate statements to enforce |
6 // order of evaluation. Makes walk easier, because it | 6 // order of evaluation. Makes walk easier, because it |
7 // can (after this runs) reorder at will within an expression. | 7 // can (after this runs) reorder at will within an expression. |
8 // | 8 // |
9 // Rewrite x op= y into x = x op y. | 9 // Rewrite x op= y into x = x op y. |
10 // | 10 // |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 n->op = OAS; | 558 n->op = OAS; |
559 ordermapassign(n, order); | 559 ordermapassign(n, order); |
560 cleantemp(t, order); | 560 cleantemp(t, order); |
561 break; | 561 break; |
562 | 562 |
563 case OAS2MAPR: | 563 case OAS2MAPR: |
564 // Special: make sure key is addressable, | 564 // Special: make sure key is addressable, |
565 // and make sure OINDEXMAP is not copied out. | 565 // and make sure OINDEXMAP is not copied out. |
566 t = marktemp(order); | 566 t = marktemp(order); |
567 orderexprlist(n->list, order); | 567 orderexprlist(n->list, order); |
568 » » orderexpr(&n->rlist->n->left, order); | 568 » » r = n->rlist->n; |
569 » » orderexpr(&n->rlist->n->right, order); | 569 » » orderexpr(&r->left, order); |
570 » » orderaddrtemp(&n->rlist->n->right, order); | 570 » » orderexpr(&r->right, order); |
| 571 » » // See case OINDEXMAP below. |
| 572 » » if(r->right->op == OARRAYBYTESTR) |
| 573 » » » r->right->op = OARRAYBYTESTRTMP; |
| 574 » » orderaddrtemp(&r->right, order); |
571 ordermapassign(n, order); | 575 ordermapassign(n, order); |
572 cleantemp(t, order); | 576 cleantemp(t, order); |
573 break; | 577 break; |
574 | 578 |
575 case OAS2FUNC: | 579 case OAS2FUNC: |
576 // Special: avoid copy of func call n->rlist->n. | 580 // Special: avoid copy of func call n->rlist->n. |
577 t = marktemp(order); | 581 t = marktemp(order); |
578 orderexprlist(n->list, order); | 582 orderexprlist(n->list, order); |
579 ordercall(n->rlist->n, order, 0); | 583 ordercall(n->rlist->n, order, 0); |
580 ordermapassign(n, order); | 584 ordermapassign(n, order); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 t->bound = count(n->list); | 932 t->bound = count(n->list); |
929 t->type = types[TSTRING]; | 933 t->type = types[TSTRING]; |
930 n->alloc = ordertemp(t, order, 0); | 934 n->alloc = ordertemp(t, order, 0); |
931 } | 935 } |
932 break; | 936 break; |
933 | 937 |
934 case OINDEXMAP: | 938 case OINDEXMAP: |
935 // key must be addressable | 939 // key must be addressable |
936 orderexpr(&n->left, order); | 940 orderexpr(&n->left, order); |
937 orderexpr(&n->right, order); | 941 orderexpr(&n->right, order); |
| 942 |
| 943 // For x = m[string(k)] where k is []byte, the allocation of |
| 944 // backing bytes for the string can be avoided by reusing |
| 945 // the []byte backing array. This is a special case that it |
| 946 // would be nice to handle more generally, but because |
| 947 // there are no []byte-keyed maps, this specific case comes |
| 948 // up in important cases in practice. See issue 3512. |
| 949 // Nothing can change the []byte we are not copying before |
| 950 // the map index, because the map access is going to |
| 951 // be forced to happen immediately following this |
| 952 // conversion (by the ordercopyexpr a few lines below). |
| 953 if(n->etype == 0 && n->right->op == OARRAYBYTESTR) |
| 954 n->right->op = OARRAYBYTESTRTMP; |
| 955 |
938 orderaddrtemp(&n->right, order); | 956 orderaddrtemp(&n->right, order); |
939 if(n->etype == 0) { | 957 if(n->etype == 0) { |
940 // use of value (not being assigned); | 958 // use of value (not being assigned); |
941 // make copy in temporary. | 959 // make copy in temporary. |
942 n = ordercopyexpr(n, n->type, order, 0); | 960 n = ordercopyexpr(n, n->type, order, 0); |
943 } | 961 } |
944 break; | 962 break; |
945 ········ | 963 ········ |
946 case OCONVIFACE: | 964 case OCONVIFACE: |
947 // concrete type (not interface) argument must be addressable | 965 // concrete type (not interface) argument must be addressable |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 | 1018 |
1001 case ORECV: | 1019 case ORECV: |
1002 n = ordercopyexpr(n, n->type, order, 1); | 1020 n = ordercopyexpr(n, n->type, order, 1); |
1003 break; | 1021 break; |
1004 } | 1022 } |
1005 ········ | 1023 ········ |
1006 lineno = lno; | 1024 lineno = lno; |
1007 | 1025 |
1008 *np = n; | 1026 *np = n; |
1009 } | 1027 } |
OLD | NEW |