Skip to content

Commit

Permalink
fix(arm): grow slice not clear mem (#674)
Browse files Browse the repository at this point in the history
  • Loading branch information
liuq19 authored Jul 17, 2024
1 parent 125ff79 commit 65b7fbe
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 83 deletions.
9 changes: 7 additions & 2 deletions internal/rt/growslice.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ package rt

import "unsafe"

func GrowSlice(et *GoType, old GoSlice, cap int) GoSlice {
s := growslice(old.Ptr, cap, old.Cap, cap - old.Len, et)
// Growslice to newCap, not append length
// Note: the [old, newCap) will not be zeroed if et does not have any ptr data.
func GrowSlice(et *GoType, old GoSlice, newCap int) GoSlice {
if newCap < old.Len {
panic("growslice's newCap is smaller than old length")
}
s := growslice(old.Ptr, newCap, old.Cap, newCap - old.Len, et)
s.Len = old.Len
return s
}
Expand Down
45 changes: 0 additions & 45 deletions internal/rt/rt_stubs_go116.go

This file was deleted.

36 changes: 0 additions & 36 deletions internal/rt/rt_stubs_go120.go

This file was deleted.

36 changes: 36 additions & 0 deletions internal/rt/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,39 @@ func GetMap64Assign(vt reflect.Type) Map64Assign {

var emptyBytes = make([]byte, 0, 0)
var EmptySlice = *(*GoSlice)(unsafe.Pointer(&emptyBytes))

//go:linkname makeslice runtime.makeslice
//goland:noinspection GoUnusedParameter
func makeslice(et *GoType, len int, cap int) unsafe.Pointer

func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice {
if newLen == 0 {
return &EmptySlice
}

if *(*unsafe.Pointer)(oldPtr) == nil {
return &GoSlice{
Ptr: makeslice(et, newLen, newLen),
Len: newLen,
Cap: newLen,
}
}

old := (*GoSlice)(oldPtr)
if old.Cap >= newLen {
old.Len = newLen
return old
}

new := GrowSlice(et, *old, newLen)

// we sould clear the memory from [oldLen:newLen]
if et.PtrData == 0 {
oldlenmem := uintptr(old.Len) * et.Size
newlenmem := uintptr(newLen) * et.Size
MemclrNoHeapPointers(add(new.Ptr, oldlenmem), newlenmem-oldlenmem)
}

new.Len = newLen
return &new
}
30 changes: 30 additions & 0 deletions internal/rt/stubs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package rt

import (
"reflect"
"testing"
"unsafe"

"github.com/stretchr/testify/assert"
)


func TestStubsMake(t *testing.T) {
t.Run("NonPtr", func(t *testing.T) {
old := &[]int{}
news := MakeSlice(unsafe.Pointer(old), UnpackType(reflect.TypeOf(int(1))), 10000)
new := *(*[]int)(unsafe.Pointer(news))
for i := 0; i < 10000; i++ {
assert.Equal(t, new[i], 0)
}
})

t.Run("HasPtr", func(t *testing.T) {
old := &[]*int{}
news := MakeSlice(unsafe.Pointer(old), UnpackType(reflect.TypeOf((*int)(nil))), 10000)
new := *(*[]*int)(unsafe.Pointer(news))
for i := 0; i < 10000; i++ {
assert.Equal(t, new[i], (*int)(nil))
}
})
}

0 comments on commit 65b7fbe

Please sign in to comment.