@@ -507,6 +507,94 @@ done:
507
507
return val
508
508
}
509
509
510
+ func mapassign_fast32ptr (t * maptype , h * hmap , key unsafe.Pointer ) unsafe.Pointer {
511
+ if h == nil {
512
+ panic (plainError ("assignment to entry in nil map" ))
513
+ }
514
+ if raceenabled {
515
+ callerpc := getcallerpc (unsafe .Pointer (& t ))
516
+ racewritepc (unsafe .Pointer (h ), callerpc , funcPC (mapassign_fast32 ))
517
+ }
518
+ if h .flags & hashWriting != 0 {
519
+ throw ("concurrent map writes" )
520
+ }
521
+ hash := t .key .alg .hash (noescape (unsafe .Pointer (& key )), uintptr (h .hash0 ))
522
+
523
+ // Set hashWriting after calling alg.hash for consistency with mapassign.
524
+ h .flags |= hashWriting
525
+
526
+ if h .buckets == nil {
527
+ h .buckets = newarray (t .bucket , 1 )
528
+ }
529
+
530
+ again:
531
+ bucket := hash & (uintptr (1 )<< h .B - 1 )
532
+ if h .growing () {
533
+ growWork (t , h , bucket )
534
+ }
535
+ b := (* bmap )(unsafe .Pointer (uintptr (h .buckets ) + bucket * uintptr (t .bucketsize )))
536
+ top := uint8 (hash >> (sys .PtrSize * 8 - 8 ))
537
+ if top < minTopHash {
538
+ top += minTopHash
539
+ }
540
+
541
+ var inserti * uint8
542
+ var insertk unsafe.Pointer
543
+ var val unsafe.Pointer
544
+ for {
545
+ for i := uintptr (0 ); i < bucketCnt ; i ++ {
546
+ if b .tophash [i ] != top {
547
+ if b .tophash [i ] == empty && inserti == nil {
548
+ inserti = & b .tophash [i ]
549
+ insertk = add (unsafe .Pointer (b ), dataOffset + i * 4 )
550
+ val = add (unsafe .Pointer (b ), dataOffset + bucketCnt * 4 + i * uintptr (t .valuesize ))
551
+ }
552
+ continue
553
+ }
554
+ k := * ((* unsafe .Pointer )(add (unsafe .Pointer (b ), dataOffset + i * 4 )))
555
+ if k != key {
556
+ continue
557
+ }
558
+ val = add (unsafe .Pointer (b ), dataOffset + bucketCnt * 4 + i * uintptr (t .valuesize ))
559
+ goto done
560
+ }
561
+ ovf := b .overflow (t )
562
+ if ovf == nil {
563
+ break
564
+ }
565
+ b = ovf
566
+ }
567
+
568
+ // Did not find mapping for key. Allocate new cell & add entry.
569
+
570
+ // If we hit the max load factor or we have too many overflow buckets,
571
+ // and we're not already in the middle of growing, start growing.
572
+ if ! h .growing () && (overLoadFactor (int64 (h .count ), h .B ) || tooManyOverflowBuckets (h .noverflow , h .B )) {
573
+ hashGrow (t , h )
574
+ goto again // Growing the table invalidates everything, so try again
575
+ }
576
+
577
+ if inserti == nil {
578
+ // all current buckets are full, allocate a new one.
579
+ newb := h .newoverflow (t , b )
580
+ inserti = & newb .tophash [0 ]
581
+ insertk = add (unsafe .Pointer (newb ), dataOffset )
582
+ val = add (insertk , bucketCnt * 4 )
583
+ }
584
+
585
+ // store new key/value at insert position
586
+ typedmemmove (t .key , insertk , unsafe .Pointer (& key ))
587
+ * inserti = top
588
+ h .count ++
589
+
590
+ done:
591
+ if h .flags & hashWriting == 0 {
592
+ throw ("concurrent map writes" )
593
+ }
594
+ h .flags &^= hashWriting
595
+ return val
596
+ }
597
+
510
598
func mapassign_fast64 (t * maptype , h * hmap , key uint64 ) unsafe.Pointer {
511
599
if h == nil {
512
600
panic (plainError ("assignment to entry in nil map" ))
@@ -595,6 +683,94 @@ done:
595
683
return val
596
684
}
597
685
686
+ func mapassign_fast64ptr (t * maptype , h * hmap , key unsafe.Pointer ) unsafe.Pointer {
687
+ if h == nil {
688
+ panic (plainError ("assignment to entry in nil map" ))
689
+ }
690
+ if raceenabled {
691
+ callerpc := getcallerpc (unsafe .Pointer (& t ))
692
+ racewritepc (unsafe .Pointer (h ), callerpc , funcPC (mapassign_fast64 ))
693
+ }
694
+ if h .flags & hashWriting != 0 {
695
+ throw ("concurrent map writes" )
696
+ }
697
+ hash := t .key .alg .hash (noescape (unsafe .Pointer (& key )), uintptr (h .hash0 ))
698
+
699
+ // Set hashWriting after calling alg.hash for consistency with mapassign.
700
+ h .flags |= hashWriting
701
+
702
+ if h .buckets == nil {
703
+ h .buckets = newarray (t .bucket , 1 )
704
+ }
705
+
706
+ again:
707
+ bucket := hash & (uintptr (1 )<< h .B - 1 )
708
+ if h .growing () {
709
+ growWork (t , h , bucket )
710
+ }
711
+ b := (* bmap )(unsafe .Pointer (uintptr (h .buckets ) + bucket * uintptr (t .bucketsize )))
712
+ top := uint8 (hash >> (sys .PtrSize * 8 - 8 ))
713
+ if top < minTopHash {
714
+ top += minTopHash
715
+ }
716
+
717
+ var inserti * uint8
718
+ var insertk unsafe.Pointer
719
+ var val unsafe.Pointer
720
+ for {
721
+ for i := uintptr (0 ); i < bucketCnt ; i ++ {
722
+ if b .tophash [i ] != top {
723
+ if b .tophash [i ] == empty && inserti == nil {
724
+ inserti = & b .tophash [i ]
725
+ insertk = add (unsafe .Pointer (b ), dataOffset + i * 8 )
726
+ val = add (unsafe .Pointer (b ), dataOffset + bucketCnt * 8 + i * uintptr (t .valuesize ))
727
+ }
728
+ continue
729
+ }
730
+ k := * ((* unsafe .Pointer )(add (unsafe .Pointer (b ), dataOffset + i * 8 )))
731
+ if k != key {
732
+ continue
733
+ }
734
+ val = add (unsafe .Pointer (b ), dataOffset + bucketCnt * 8 + i * uintptr (t .valuesize ))
735
+ goto done
736
+ }
737
+ ovf := b .overflow (t )
738
+ if ovf == nil {
739
+ break
740
+ }
741
+ b = ovf
742
+ }
743
+
744
+ // Did not find mapping for key. Allocate new cell & add entry.
745
+
746
+ // If we hit the max load factor or we have too many overflow buckets,
747
+ // and we're not already in the middle of growing, start growing.
748
+ if ! h .growing () && (overLoadFactor (int64 (h .count ), h .B ) || tooManyOverflowBuckets (h .noverflow , h .B )) {
749
+ hashGrow (t , h )
750
+ goto again // Growing the table invalidates everything, so try again
751
+ }
752
+
753
+ if inserti == nil {
754
+ // all current buckets are full, allocate a new one.
755
+ newb := h .newoverflow (t , b )
756
+ inserti = & newb .tophash [0 ]
757
+ insertk = add (unsafe .Pointer (newb ), dataOffset )
758
+ val = add (insertk , bucketCnt * 8 )
759
+ }
760
+
761
+ // store new key/value at insert position
762
+ typedmemmove (t .key , insertk , unsafe .Pointer (& key ))
763
+ * inserti = top
764
+ h .count ++
765
+
766
+ done:
767
+ if h .flags & hashWriting == 0 {
768
+ throw ("concurrent map writes" )
769
+ }
770
+ h .flags &^= hashWriting
771
+ return val
772
+ }
773
+
598
774
func mapassign_faststr (t * maptype , h * hmap , ky string ) unsafe.Pointer {
599
775
if h == nil {
600
776
panic (plainError ("assignment to entry in nil map" ))
0 commit comments