@@ -701,20 +701,42 @@ func (s *state) paramsToHeap() {
701701 do (typ .Results ())
702702}
703703
704+ // allocSizeAndAlign returns the size and alignment of t.
705+ // Normally just t.Size() and t.Alignment(), but there
706+ // is a special case to handle 64-bit atomics on 32-bit systems.
707+ func allocSizeAndAlign (t * types.Type ) (int64 , int64 ) {
708+ size , align := t .Size (), t .Alignment ()
709+ if types .PtrSize == 4 && align == 4 && size >= 8 {
710+ // For 64-bit atomics on 32-bit systems.
711+ size = types .RoundUp (size , 8 )
712+ align = 8
713+ }
714+ return size , align
715+ }
716+ func allocSize (t * types.Type ) int64 {
717+ size , _ := allocSizeAndAlign (t )
718+ return size
719+ }
720+ func allocAlign (t * types.Type ) int64 {
721+ _ , align := allocSizeAndAlign (t )
722+ return align
723+ }
724+
704725// newHeapaddr allocates heap memory for n and sets its heap address.
705726func (s * state ) newHeapaddr (n * ir.Name ) {
706- if n .Type ().HasPointers () || n .Type ().Size () >= maxAggregatedHeapAllocation || n .Type ().Size () == 0 {
727+ size := allocSize (n .Type ())
728+ if n .Type ().HasPointers () || size >= maxAggregatedHeapAllocation || size == 0 {
707729 s .setHeapaddr (n .Pos (), n , s .newObject (n .Type (), nil ))
708730 return
709731 }
710732
711733 // Do we have room together with our pending allocations?
712734 // If not, flush all the current ones.
713- var size int64
735+ var used int64
714736 for _ , v := range s .pendingHeapAllocations {
715- size += v .Type .Elem (). Size ( )
737+ used += allocSize ( v .Type .Elem ())
716738 }
717- if size + n . Type (). Size () > maxAggregatedHeapAllocation {
739+ if used + size > maxAggregatedHeapAllocation {
718740 s .flushPendingHeapAllocations ()
719741 }
720742
@@ -757,16 +779,16 @@ func (s *state) flushPendingHeapAllocations() {
757779 // This way we never have to worry about padding.
758780 // (Stable not required; just cleaner to keep program order among equal alignments.)
759781 slices .SortStableFunc (pending , func (x , y * ssa.Value ) int {
760- return cmp .Compare (y .Type .Elem (). Alignment ( ), x .Type .Elem (). Alignment ( ))
782+ return cmp .Compare (allocAlign ( y .Type .Elem ()), allocAlign ( x .Type .Elem ()))
761783 })
762784
763785 // Figure out how much data we need allocate.
764786 var size int64
765787 for _ , v := range pending {
766788 v .AuxInt = size // Adjust OffPtr to the right value while we are here.
767- size += v .Type .Elem (). Size ( )
789+ size += allocSize ( v .Type .Elem ())
768790 }
769- align := pending [0 ].Type .Elem (). Alignment ( )
791+ align := allocAlign ( pending [0 ].Type .Elem ())
770792 size = types .RoundUp (size , align )
771793
772794 // Convert newObject call to a mallocgc call.
0 commit comments