mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-11 06:23:39 +00:00
all: use unsafe.Add instead of unsafe.Pointer(uintptr(...) + ...)
We have an optimization for this specific pattern, but it's really just a hack. With the addition of unsafe.Add in Go 1.17 we can directly specify the intent instead and eventually remove this special case. The code is also easier to read.
This commit is contained in:
committed by
Ron Evans
parent
d98c0afbab
commit
4ec1e58aa6
+15
-20
@@ -169,8 +169,7 @@ func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint3
|
||||
numBuckets := uintptr(1) << m.bucketBits
|
||||
bucketNumber := (uintptr(hash) & (numBuckets - 1))
|
||||
bucketSize := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*8
|
||||
bucketAddr := uintptr(m.buckets) + bucketSize*bucketNumber
|
||||
bucket := (*hashmapBucket)(unsafe.Pointer(bucketAddr))
|
||||
bucket := (*hashmapBucket)(unsafe.Add(m.buckets, bucketSize*bucketNumber))
|
||||
var lastBucket *hashmapBucket
|
||||
|
||||
// See whether the key already exists somewhere.
|
||||
@@ -180,9 +179,9 @@ func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint3
|
||||
for bucket != nil {
|
||||
for i := uintptr(0); i < 8; i++ {
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*uintptr(i)
|
||||
slotKey := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotKeyOffset)
|
||||
slotKey := unsafe.Add(unsafe.Pointer(bucket), slotKeyOffset)
|
||||
slotValueOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*uintptr(i)
|
||||
slotValue := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotValueOffset)
|
||||
slotValue := unsafe.Add(unsafe.Pointer(bucket), slotValueOffset)
|
||||
if bucket.tophash[i] == 0 && emptySlotKey == nil {
|
||||
// Found an empty slot, store it for if we couldn't find an
|
||||
// existing slot.
|
||||
@@ -225,9 +224,9 @@ func hashmapInsertIntoNewBucket(m *hashmap, key, value unsafe.Pointer, tophash u
|
||||
bucketBuf := alloc(bucketBufSize, nil)
|
||||
// Insert into the first slot, which is empty as it has just been allocated.
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{})
|
||||
slotKey := unsafe.Pointer(uintptr(bucketBuf) + slotKeyOffset)
|
||||
slotKey := unsafe.Add(bucketBuf, slotKeyOffset)
|
||||
slotValueOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8
|
||||
slotValue := unsafe.Pointer(uintptr(bucketBuf) + slotValueOffset)
|
||||
slotValue := unsafe.Add(bucketBuf, slotValueOffset)
|
||||
m.count++
|
||||
memcpy(slotKey, key, m.keySize)
|
||||
memcpy(slotValue, value, m.valueSize)
|
||||
@@ -276,8 +275,7 @@ func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash u
|
||||
numBuckets := uintptr(1) << m.bucketBits
|
||||
bucketNumber := (uintptr(hash) & (numBuckets - 1))
|
||||
bucketSize := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*8
|
||||
bucketAddr := uintptr(m.buckets) + bucketSize*bucketNumber
|
||||
bucket := (*hashmapBucket)(unsafe.Pointer(bucketAddr))
|
||||
bucket := (*hashmapBucket)(unsafe.Add(m.buckets, bucketSize*bucketNumber))
|
||||
|
||||
tophash := uint8(hash >> 24)
|
||||
if tophash < 1 {
|
||||
@@ -289,9 +287,9 @@ func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash u
|
||||
for bucket != nil {
|
||||
for i := uintptr(0); i < 8; i++ {
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*uintptr(i)
|
||||
slotKey := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotKeyOffset)
|
||||
slotKey := unsafe.Add(unsafe.Pointer(bucket), slotKeyOffset)
|
||||
slotValueOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*uintptr(i)
|
||||
slotValue := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotValueOffset)
|
||||
slotValue := unsafe.Add(unsafe.Pointer(bucket), slotValueOffset)
|
||||
if bucket.tophash[i] == tophash {
|
||||
// This could be the key we're looking for.
|
||||
if m.keyEqual(key, slotKey, m.keySize) {
|
||||
@@ -327,8 +325,7 @@ func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32) {
|
||||
numBuckets := uintptr(1) << m.bucketBits
|
||||
bucketNumber := (uintptr(hash) & (numBuckets - 1))
|
||||
bucketSize := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*8
|
||||
bucketAddr := uintptr(m.buckets) + bucketSize*bucketNumber
|
||||
bucket := (*hashmapBucket)(unsafe.Pointer(bucketAddr))
|
||||
bucket := (*hashmapBucket)(unsafe.Add(m.buckets, bucketSize*bucketNumber))
|
||||
|
||||
tophash := uint8(hash >> 24)
|
||||
if tophash < 1 {
|
||||
@@ -340,7 +337,7 @@ func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32) {
|
||||
for bucket != nil {
|
||||
for i := uintptr(0); i < 8; i++ {
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*uintptr(i)
|
||||
slotKey := unsafe.Pointer(uintptr(unsafe.Pointer(bucket)) + slotKeyOffset)
|
||||
slotKey := unsafe.Add(unsafe.Pointer(bucket), slotKeyOffset)
|
||||
if bucket.tophash[i] == tophash {
|
||||
// This could be the key we're looking for.
|
||||
if m.keyEqual(key, slotKey, m.keySize) {
|
||||
@@ -382,8 +379,7 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
|
||||
return false
|
||||
}
|
||||
bucketSize := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*8
|
||||
bucketAddr := uintptr(it.buckets) + bucketSize*it.bucketNumber
|
||||
it.bucket = (*hashmapBucket)(unsafe.Pointer(bucketAddr))
|
||||
it.bucket = (*hashmapBucket)(unsafe.Add(it.buckets, bucketSize*it.bucketNumber))
|
||||
it.bucketNumber++ // next bucket
|
||||
}
|
||||
if it.bucket.tophash[it.bucketIndex] == 0 {
|
||||
@@ -392,16 +388,15 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
|
||||
continue
|
||||
}
|
||||
|
||||
bucketAddr := uintptr(unsafe.Pointer(it.bucket))
|
||||
slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*uintptr(it.bucketIndex)
|
||||
slotKey := unsafe.Pointer(bucketAddr + slotKeyOffset)
|
||||
slotKey := unsafe.Add(unsafe.Pointer(it.bucket), slotKeyOffset)
|
||||
memcpy(key, slotKey, m.keySize)
|
||||
|
||||
if it.buckets == m.buckets {
|
||||
// Our view of the buckets is the same as the parent map.
|
||||
// Just copy the value we have
|
||||
slotValueOffset := unsafe.Sizeof(hashmapBucket{}) + m.keySize*8 + m.valueSize*uintptr(it.bucketIndex)
|
||||
slotValue := unsafe.Pointer(bucketAddr + slotValueOffset)
|
||||
slotValue := unsafe.Add(unsafe.Pointer(it.bucket), slotValueOffset)
|
||||
memcpy(value, slotValue, m.valueSize)
|
||||
it.bucketIndex++
|
||||
} else {
|
||||
@@ -574,10 +569,10 @@ func hashmapInterfaceHash(itf interface{}, seed uintptr) uint32 {
|
||||
case reflect.Float64:
|
||||
return hashmapFloat64Hash(ptr, seed)
|
||||
case reflect.Complex64:
|
||||
rptr, iptr := ptr, unsafe.Pointer(uintptr(ptr)+4)
|
||||
rptr, iptr := ptr, unsafe.Add(ptr, 4)
|
||||
return hashmapFloat32Hash(rptr, seed) ^ hashmapFloat32Hash(iptr, seed)
|
||||
case reflect.Complex128:
|
||||
rptr, iptr := ptr, unsafe.Pointer(uintptr(ptr)+8)
|
||||
rptr, iptr := ptr, unsafe.Add(ptr, 8)
|
||||
return hashmapFloat64Hash(rptr, seed) ^ hashmapFloat64Hash(iptr, seed)
|
||||
case reflect.String:
|
||||
return hashmapStringHash(x.String(), seed)
|
||||
|
||||
Reference in New Issue
Block a user